Misc

来都来了

Ctrl C + Ctrl V 即可

尊嘟假嘟

尊嘟假嘟O.o (zdjd.asia)
Ctrl C + Ctrl V 然后丢到这个尊嘟假嘟翻译器里面就可以了
这玩意挺好找的,抖音上随便搜搜到处都是

1
flag{zun_du_jia_du}

表情包,嘿嘿

看似毫无头绪,实则这个东西其实是base 100 加密,题目里也有提示,base 家族嘛BASE100编码解码 - Bugku CTF

image.png
顺便如果 edge 浏览器复制粘贴失败了,换个 PDF 阅读器就行,火狐都比这玩意好使。

1
flag{WelcOm3_to_CTF}

兽语

简单的兽语加密,网上随便找个兽语加密解码器就可以了兽音译者在线编码解码 - 兽音翻译咆哮体加密解密 (iiilab.com)
image.png

1
flag{y0u_Ne3d_4_good_fr1end}

目前为止都是送分题的范畴,主要是通过简单的解码激发对于 CTF 的兴趣。

文王八卦

通过八卦和次序,提示了应该是从八进制作为入手点,按照给定次序从0开始依次给八卦编号,从而转换成8进制,然后将其对应 ASCII 码打出即可,一题相当简单的编码题目罢了。

1
2
3
4
5
6
7
8
9
dic1 = {'乾': '0', '坎': '1', '艮': '2', '震': '3', '巽': '4', '离': '5', '坤': '6', '兑': '7', ' ': ' '}
ans = ""
s1 = "坎巽坤 坎离巽 坎巽坎 坎巽兑 坎兑震 坎巽震 乾坤乾 坎离坤 坎巽兑 坎坤艮 乾坤巽 坎坤巽 坎坤离 乾坤坎 坎巽坎 坎坤巽 坎离坎 坎离兑 坎离坤 坎兑离"
for key in s1:
ans += dic1[key]

print(ans)
for i in ans.split(" "):
print(chr(int(i, 8)), end='')

运行结果如下:

1
flag{c0ngr4tu1ation}

余音绕梁

闲着好玩出的这么一道音频隐写题目,其实出的不难,用个软件就解决了,还给了提示。
软件名字就是 Deep Sound

因此下载Deep Sound打开就可以找到hidden_text.txt ,打开就是flag,于是问题解决。

1
flag{wh3n_your_dr34ms_come_4live_you_re_unstoppable}

总结:以上 Misc 基本全是送分题,希望在 CTF 的道路上能吸引一点兴趣。

Crypto

5 + 13

在这里先臭不要face的附上个人博客链接:古典密码学1 | Wandering 的小站 (the-past-beyond-time.top)
然后发现 5 + 13 就是等于18 当然非常简单。但是这是一种凯撒密码的变种,就是 ROT18 名字的来源。

Factor

这就是一个正常的RSA解题,题目给了 n e c ,因此只需要把 n 分解质因数就可以得到 pq,从而求出私钥 d

两种方式,一种是线上工具分解http://www.factordb.com/(这个n分解结果应该是我提供的),一种是工具yafuyafu download | SourceForge.net

这里展示 yafu 的使用方式,n为10进制后,创建 test.txt 文件,输入 n 并换行。

后在 powershell 中打开该文件夹,输入下列命令

1
.\yafu-x64 "factor(@)" -batchfile test.txt

image.png
分解得到

1
2
p = 207576768896912282429437392641896918963
q = 333064906149371841782390942272121468453

因此问题转换为,已知 $p, q, e, c$ 求原文 $m$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import libnum

c = 0x21c42e0e5af7deec020b122013e51fd641c4a94597e17157d6aa31805963dbae
n = 69136537051439937318975527466213101619555566427079093617699759905667901974239
p = 207576768896912282429437392641896918963
q = 333064906149371841782390942272121468453
e = 65537
phi_n = (p - 1) * (q - 1)

# 求逆元
d = libnum.invmod(e, phi_n)

m = pow(c, d, n)
print(n)
# 数字转字节,转字符串
print(libnum.n2s(int(m)).decode())

image.png
得到flag{1la5141919810}, 实际情况是电脑不会因为c 是16进制就不会做乘方运算,但是人会。

1
flag{1la5141919810}

异世界的探索

显然看到两个等号,第一反应是base64 编码,解密后得到 }MS4Ylt4s0_r_0{afr_3ug

可以发现里面flag{} 等符号都具有,可是根据题目提示还有两层加密

这时候的第一反应是栅栏密码或者其他一些移位密码,只有这些密码只更改字母的顺序而不更改字母本身

尝试栅栏密码W解密:(新奇款式的栅栏)
image.png
注意到分为三栏的时候只需要把字符串逆向就能得到flag。(对应题目里的倒映的世界)

1
flag{Y0u_4r3_S0_sM4rt}

口算大整数

其实是RSA密码中的小明文攻击

注意到题目中密文 c 长度远小于模数 n 长度,且模数 e 极小

因此公钥e很小,明文m也不大的话,于是 $m^e=k*n+m$ 中的 k值很小甚至为0,爆破k或直接开三次方即可,解题脚本如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmpy2
import libnum

n = 0xa3bce3926fc27e291e730abe80e936c24d28e55a42995e296b3914b3f5b68dbdcdfa91582193fcf90b8b82905aead974b6465c5f9f8ff759c66c7dd78fcd7086011915110dce9927acb28d985f97d24027139372ccd3fd1b012787b8cd28908350fa0dbba59e2661f6740e6d133777dc37690b60b87eb9c748e869b4382c8f719869bac442be8ec8cb9700222a13f40921a691d32c420077cfabccd2844b78f8dc5f48b8e210c1523a0efa12b2ab1b15406a022f5cc4d2a261d810748104b1f8bda2c2b5d82ef78c6c7a81a3b89e14b935eceff152371db9215641974731238cc778a023e462c0e205f71caa0d1c82d1f8ebaca91b13cab25e698407978d0157
e = 0x3
c = 0x10652cdfaa8b1ec60efcf3bf9cc73f918e0476a9265f6ed80d816b1826abcd23a13d45419a652ba6b33e9cd6766b31ed4aefb576f1048ef00bcbc6ebf05f89c6cbbf315d1dc6b0ef2b5a5bfde6ea0978f01b4865
res = 0


for i in range(200000000):
if gmpy2.iroot(c + n * i, 3)[1] == 1:
try:
res = int(gmpy2.iroot(c + n * i, 3)[0])
print(libnum.n2s(res).decode())
except:
continue

实际上这题中的 k = 0 因此直接将 c 开三次根后甚至能直接出答案,某种程度上还是留了一点后门?大整数运算需要有 Python 专门的库,自带的开根号精度不够,算出来一半的注意一下这个问题。
image.png

1
flag{tH1s_I5_wH4t_y0u_ne3D!}

Wiener RSA

背景

1989年,Michael J.Wiener发表了Cryptanalysis of Short RSA Secret Exponents文章,提出了一种针对解密指数 d 较低时对于RSA的攻击方法,该方法基于连分数(Continued Fraction)

在CTF中,若RSA算法提供的公钥的e非常大,那么由于ed在乘积时地位对等,d的值很可能较小,可以尝试考虑是否是维纳攻击。

数学论文如下,此处不详细展开,只要求对使用脚本解题有一定掌握即可,在告知是维纳攻击的前提下,网络上有许多相关脚本,搜索并学会配置和使用脚本是不可或缺的能力。后续学习过程中可能对其攻击原理有一定要求,无脚本可以现成利用。
shortsecretexponents.pdf (ruhr-uni-bochum.de)

解答

工具包准备如下:

1
2
git clone https://github.com/pablocelayes/rsa-wiener-attack
pip install pycryptodome

利用上述工具包求私钥 d 的脚本如下(未涉及包的导入)

1
2
3
4
5
6
7
8
9
10
11
12
13
def wiener_hack(e, n):
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k, d) in convergents:
if k != 0 and (e * d - 1) % k == 0:
phi = (e * d - 1) // k
s = n - phi + 1
discr = s * s - 4 * n
if (discr >= 0):
t = Arithmetic.is_perfect_square(discr)
if t != -1 and (s + t) % 2 == 0:
return d
return False

完整版的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from Crypto.PublicKey import RSA
import ContinuedFractions, Arithmetic
from Crypto.Util.number import long_to_bytes

def wiener_hack(e, n):
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k, d) in convergents:
if k != 0 and (e * d - 1) % k == 0:
phi = (e * d - 1) // k
s = n - phi + 1
discr = s * s - 4 * n
if (discr >= 0):
t = Arithmetic.is_perfect_square(discr)
if t != -1 and (s + t) % 2 == 0:
return d
return False


def main():
n = 122799981867653458656229479905780591709320336906548267308725133504023620666473594694619400061072384153052380482145474476277325274539534268692096140372698856686913649268243189214226426197241972179248244727576974065032906277783259533091580447468486634337837769772374096283015491595913791337168075781487175577011
e = 1634708036918022876029212484705339394117588871584112517454367841949655368912434655817734472520220293452874702665398224936229255345466873974072201646615281356263861423534178234100275738689728153879282329006386554426368727168149082061185380447183592559043261489606693247823120095812869743632614890148511762833
c = 8828249396920089665604321590729449082283412247637210954851574255858554979363879535153347766207783540409667667635411461588213929794181755191561235289121055575970985299405308351883604156440682299260079619595877340179217897011307148868696271453299235902611126697623645746302557312636041900678521266759516645215
d = wiener_hack(e, n)
m = pow(c,d,n)
print (long_to_bytes(m))


if __name__=="__main__":
main()

将上述代码放入rsa-wiener-attack 文件夹下运行即可得到 flag,最好准备 Linux 环境。

1
flag{W1eNer_atTAcK_Is_vErY_eASy!}

Fermat RSA

image.png
一些数学推导,推导完了实际就是解个一元二次方程求 p 和 q,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import gmpy2
from Crypto.Util.number import *
from sympy import *


e = 65537
c = 23895834623261377800351031954483648973943748863301467305810451110352777886300454729029165813465351332857815718013916942502578356053087425580006364436079752652396602575187901157819298680796270368515668161455494688724537106030940049090557292366949959348885616425446560414414860161844976376461908126987441253405
n = 64871829903104213643680764097850414283536373814646568873418061349075599660706209112510457467832178810869133929276049796748237853589936969078985797862477657422954022334398157187517648415739493949218289040505843638468023658049134338372905051146096638506369570551073678125496909258166096784242028555600270176773
leak = 16108617090416270985577150372010761876856874015361846998037080476963691088702658913666115496812645234594684431959245528754650234787455851230467008931520826
p, q = symbols("p q")
eq = [p*q-n,p+q-leak]
result = list(nonlinsolve(eq, [p, q]))
p,q =int(result[1][0]),int(result[1][1])
phi =(p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)

image.png

1
flag{4_s1mple_ch4llenge_of_Ferm4t_s_litt1e_theor3m_and_rsa}

典,很经典

看到给了这么一大串乱码的文本,要么维吉尼亚密码,要么单表加密的字频统计。
quipqiup - cryptoquip and cryptogram solver
字频统计的网站如下,把一大串文本全扔进去肯定出错,这么一大串文本都超出输入框了,毕竟是《哈利波特 · 魔法石》的第一章。少复制点东西就能得到如下
image.png

key = 3 是一个明显再不能明显的提示,显然是把下面这串文本进行凯撒移位加密,移位是3
移动回去之后会发现是这么个玩意:
ZmxhZ3t5MHVfcmVfc29zb28wb28wb3MwX3NtNHJ0IX0=
显然base64编码解一下就可以了。

1
flag{y0u_re_sosoo0oo0os0_sm4rt!}

不算太难的密码学题目,比较基础,学点简单的 RSA 以及数论应该能 AK(All Killed)
当然出的题目也是之前见到过的题目拼拼凑凑搞出来的,网上找到一些思路和参考并不奇怪,能找到自然也是本事的一部分,但是正式比赛是没有参考的。

Reverse

ELF

本意是直接大家了解一下啥是 ELF 顺便 Linux 里学会怎么运行可执行程序就可以了。
结果发现 IDA 里面按 F5 也能直接出来……算非预期了吧。
image.png

1
flag{1s_Execute4ble_and_Linkable_F0rmat}

以上就是这次纳新赛我出的题目的全部解析,希望大家在接下来的 CTF 日常中玩的开心。