入学网安以来第一次写WP,如果发现错误或有更好的解决方案,望各位师傅不吝指出!
Hint:Bra1n p0w3r5
(出题人一眼丁真引诱人)
查一查这种编码,发现其实是一种极小化的编程语言。识别特征是只有><+=.,[]八种字符组成。参考资料:https://zh.wikipedia.org/zh-cn/Brainfuck
直接扔到ctf工具中解码
flag{Oiiaioooooiai#b7c0b1866fe58e12}
(引诱人实锤)
凯撒密码,即位移密码,古典中的古典(所以标点一般不参与加密)
直接扔到脚本里run一run得到
flag{ca3s4r's_c1pher_i5_v4ry_3azy}
(截图中代码不完整,可以用在线工具代替,脚本参考:python凯撒密码流程图_凯撒密码解密脚本(python)-CSDN博客)
已经明确明文开头是flag,所以也可以通过密文开头kqfl确定位移是5,扔到ctf工具里跑(凯撒密码工具满大街都是)
栅栏密码
栅栏密码只改变字符顺序不改变字符内容,所以一般看到{}内不完全包含全部密文即可判断是栅栏(或者位置反了)。扔到bugku工具里枚举,栏数是2。
flag{reordering_the_plaintext#686f8c03}
Hint:le chiffre indéchiffrable(不可破译的密码)
维吉尼亚密码,参考资料:https://zh.wikipedia.org/wiki/维吉尼亚密码
由于不知道密钥内容,但知道了明文开头是flag,可以尝试手搓一下得到前四位密钥是kfck。而维吉尼亚密码中密钥是循环使用的,所以大概率密钥是kfc。扔到ctf工具验证:
flag{la_c1fr4_del_5ign0r_giovan_batt1st4_b3ll5s0}
也可以用Vigenere Solver | guballa.de语义破解(但试了试其他题目其实不怎么好用),而且维吉尼亚密码被误认为是法国人发明所以此题要选法语语义。
Hint:奇奇怪怪的编码
Part1不出意外base64,解得flag{dazzling_encoding#4e0ad4
Part2全是大写不出意外base32,解得f0ca08d1e1d0f10c0c7afe422fea7
Part3没见过,但题目说是编码,在CTF工具箱(也可以用bugku工具箱 在线工具 - Bugku CTF)里随便乱试发现uuencode可以得到c55192c992036ef623372601ff3a}
查到有关UU编码的知识https://zh.wikipedia.org/wiki/Uuencode
据说uu编码题其实比较常见,当经验积累吧(后来找了其他题做确实很好辨认)。
Hint:容易分解的n
考察非对称密码RSA算法
资料:CTF学习笔记一——RSA加密_ctf rsa_457591978的博客-CSDN博客
rsa常见题型总结:CTF ——crypto ——RSA原理及各种题型总结_ctf rsa-CSDN博客
自动化工具:https://github.com/RsaCtfTool/RsaCtfTool
加密算法中getPrime(n)为生成n位素数的函数,pow(x,y,z)为x的y次方后对z取模(z为非必要参数)
显然在这道题中,n可以分解出15个素数,且容易分解,扔到factordb.com中分解质因数得到p和q(共15个):编写解密脚本:
n=17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
e=65537
c=14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595
def rsa_decode(c,e,n):
fn=1
primelist=[2217990919,2338725373,2370292207,2463878387,2706073949,2794985117,2804303069,2923072267,2970591037,3207148519,3654864131,3831680819,3939901243,4093178561,4278428893]
for p in primelist:
fn*=(p-1)
d=inverse(e,fn)
m=pow(c,d,n)
return m
print(long_to_bytes(rsa_decode(c,e,n)))
fn用于计算n的欧拉函数的值,inverse(x,y)是求x在模y下的乘法逆元函数,也可以用gmpy2库中的invert函数。运行得到flag{us4_s1ge_t0_cal_phI}
Hint:Michael J. Wiener 觉得很赞
去check这个人,发现一种不常用的rsa攻击方式:维纳攻击,适用于e很大或者e很小的时候。
这个e大到简直不要太离谱,非常适合维纳攻击。可以用RsaCtfTool自动化处理(没试过),也可以直接上脚本(截图代码不完整):调用部分:
c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248
e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825
n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433
d = wienerAttack(e, n)
print("d=", d)
m = pow(c, d, n)
print(long_to_bytes(m))
脚本代码:RSA之初学维纳攻击-CSDN博客
运行得到d= 2357048593 d确实很small flag{learn_some_continued_fraction_technique#dc16885c}
Hint:简单的异或
异或密码资料:https://zh.wikipedia.org/zh-cn/异或密码
需要注意的是,异或是按位运算的,如果其中一方数据的位数不够则会直接补零运算;题目中明文并非直接与密钥进行异或,而是一个字符一个字符地运算。然而题目中并没有给出密钥,只给出了密文。可以爆破出key为143;也可以用密文的前四位与明文开头flag进行异或得出flag(异或性质所然)。
c = 'e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2'
c = bytes.fromhex(c)
def xor(plaintext, key):
ret = []
for i in plaintext:
ret.append(i ^ key)
return ''.join(chr(s) for s in ret)
k = 0x66 ^ 0xe9
print(k, xor(c, k))
得到k=143 flag{x0r_15_symm3try_and_e4zy!!!!!!}
Hint:Caesar with multiplication
仿射密码资料:https://zh.wikipedia.org/zh-cn/仿射密碼
有两个密钥,要么手搓,要么爆破。为了省事选择爆破(
import gmpy2
from Crypto.Util.number import *
c = 'dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064'
m = 256
def mul(k0, k1, c):
ciphertext = bytes.fromhex(c)
# print(str(ciphertext))
clist = []
for f in ciphertext:
if gmpy2.gcd(k0, m) != 1:
continue
else:
clist.append(((f-k1) * gmpy2.invert(k0, m)) % m)
# lis_byd = bytes(clist)
# print(clist)
return ''.join(chr(i) for i in clist)
for k0 in range(1, 255, 2):
for k1 in range(1, 255):
if 'flag' in mul(k0, k1, c):
ans = mul(k0, k1, c)
print(k0, k1, ans)
else:
continue
爆出来k0=17,k1=23 flag{4ff1ne_c1pher_i5_very_3azy}
参考资料:AES加密算法原理的详细介绍与实现-CSDN博客
os.urandom(n)是用来生成随机n位密钥的函数。显然第一次输出结果是用来计算key和iv的重要数据。这个数据是key与iv与1做异或得到的,反过来,但凡能知道key或iv中一项就能得到另一个。观察发现key占32字节,iv占16字节,那么两者在进行异或运算时,key的高128位(比特)是没有参与运算的原始数据。又因为Key是16字节密钥乘二得到的,所以key的低128位和高128位一样,那么我们就可以直接截取异或结果的高16字节来得到key,而iv也能得到了。用库函数解码即可得到明文。
from Crypto.Cipher import AES
import os
from gmpy2 import *
from Crypto.Util.number import *
xor = 3657491768215750635844958060963805125333761387746954618540958489914964573229
enc_flag = b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'
out = long_to_bytes(xor)
key = out[:16]*2
iv = bytes_to_long(key[16:]) ^ bytes_to_long(out[16:])
iv = long_to_bytes(iv)
aes = AES.new(key, AES.MODE_CBC, iv)
flag = aes.decrypt(enc_flag)
print(flag)
flag{firsT_cry_Aes}