ctf之crypto练习二
一、js代码分析之编码转换
- 打开index.html
4.然而输入之后还是提示错误,那就只剩fg = bm(token);这句代码有问题了
二、base64编码之键盘密码
三、工业流量包分析
四、文本中有规律的大写字母
1.下载附件后,发现是一个很大的文本,仔细观察文本,发现文本中有很多故意加粗的大写字母。
2.将大写过滤出来出来
其中:
- grep -o 只显示匹配到的字符串
- tr -d 删除指定字符
4.将文章中的所有大写字母提取出来,得到一串全部由ZERO与ONE组成的字符串,ZERO替换为数字0,ONE替换为数字1,从而得到一个二进制表示的数,再将此数转换为字符串即可。
010000100100100101010100010100110100001101010100010001100111101101101000001100010110010000110011010111110011000101101110010111110111000001101100001101000011000101101110010111110011010100110001001101110011001101111101
5.在线二进制转字符串:
http://www.txttool.com/wenben_binarystr.asp
6.python脚本获取
#coding:utf-8
from string import uppercase
from Crypto.Util.number import long_to_bytes
def solve():
with open('data.txt','r') as f: #data.txt是上面过滤的大写字母
data=f.read()
cip=''
for c in data:
if c in uppercase:
cip+=c
cip=cip.replace('ZERO','0')
cip=cip.replace('ONE','1')
return long_to_bytes(long(cip,2))
if __name__=='__main__':
print solve()
7.得到flag:BITSCTF{h1d3_1n_pl41n_5173}
五、RSA解密
writeup:
1.将题目中的十六进制类型转换成十进制:
p=8695224115036335558506571119739296036271134788610181138168484331081777972517240308721981280176995392696427341397469232176120700610749965333026113898553049
q=13096749823995628078930936161926731366955083380107539950861609990671457149850288846976369982960384583841424977220385144435351119887497145134804975486079751
e=76629781387397242664311670987431757827144139255639280752983416867031015307352014386648673994217913815581782186636488159185965227449303118783362862435899486717504457233649829563176353949817149997773276435581910370559594639570436120596211148973227077565739467641309426944529006537681147498322988959979899800641
c=89801389443569569957398406954707598492763923418568536030323546088278758362331043119736437910117697032594835902900582040394367480829800897231925233807745278389358031404278064633313626149336724945854865041439061149411962509247624419448003604874406282213609341704339025169015256228029200222643343430028828063008
2.通过脚本获取RSA的M值
# coding=utf-8
import gmpy2
from Crypto.Util.number import *
from gmpy2 import iroot,invert
p=8695224115036335558506571119739296036271134788610181138168484331081777972517240308721981280176995392696427341397469232176120700610749965333026113898553049
q=13096749823995628078930936161926731366955083380107539950861609990671457149850288846976369982960384583841424977220385144435351119887497145134804975486079751
e=76629781387397242664311670987431757827144139255639280752983416867031015307352014386648673994217913815581782186636488159185965227449303118783362862435899486717504457233649829563176353949817149997773276435581910370559594639570436120596211148973227077565739467641309426944529006537681147498322988959979899800641
c=89801389443569569957398406954707598492763923418568536030323546088278758362331043119736437910117697032594835902900582040394367480829800897231925233807745278389358031404278064633313626149336724945854865041439061149411962509247624419448003604874406282213609341704339025169015256228029200222643343430028828063008
N = p * q
d = int(gmpy2.invert(e , (p-1) * (q-1)))
phi=(p-1)*(q-1)
print(phi)
d=int(invert(e,phi))
m=pow(c,d,N)
print(long_to_bytes(m))
六、诗歌decrypted message
1.下载题目附件可以看到如下信息:
The life that I have
Is all that I have
And the life that I have
Is yours.
The love that I have
Of the life that I have
Is yours and yours and yours.
A sleep I shall have
A rest I shall have
Yet death will be but a pause.
For the peace of my years
In the long green grass
Will be yours and yours and yours.
decrypted message: emzcf sebt yuwi ytrr ortl rbon aluo konf ihye cyog rowh prhj feom ihos perp twnb tpak heoc yaui usoa irtd tnlu ntke onds goym hmpq
可以看到上面是一段诗歌文字以及以及 decrypted message (解密消息)
2.这是一种比较奇特的加密方式,叫做Poem Codes,详见:http://wmbriggs.com/post/1001/
加密过程如下:
(1)就其算法而言,去诗歌头一个单词,全部罗列出来,然后所有单词的字母按字母表排序并编码,如第一个a为1,第二个a为2,如果没有a了就看b,第一个b为3,第二个b为4,一直排列下去。。。
(2)将要加密的信息的字母每18个一行(不足一行的abcdef....补足)
(3)将加密的信息第一个字母对应第一步的编码数字,到第二步生成的字母表中取某列。
(4)分组即成加密信息。
解密过程非常复杂,不过,有人已经写好了解密工具,详见:https://github.com/abpolym/crypto-tools/tree/master/poemcode
3.先将以下信息保存为poem.txt
The life that I have
Is all that I have
And the life that I have
Is yours.
The love that I have
Of the life that I have
Is yours and yours and yours.
A sleep I shall have
A rest I shall have
Yet death will be but a pause.
For the peace of my years
In the long green grass
Will be yours and yours and yours.
然后将以下信息保存为:messg
emzcf sebt yuwi ytrr ortl rbon aluo konf ihye cyog rowh prhj feom ihos perp twnb tpak heoc yaui usoa irtd tnlu ntke onds goym hmpq
4.执行python脚本进行解密
python poemcode.py poem.txt messg
5.猜解出一大堆消息,选择最像的那条即可,flag:
ifyouthinkcryptographyistheanswertoyourproblemthenyoudonotknowwhatyourproblemisabcdefghijklmnopqrstu七、RSA低加密指数广播攻击
基础知识:如果选取的加密指数较低,并且使用了相同的加密指数给一个接受者的群发送相同的信息,那么可以进行广播攻击得到明文。
即,选取了相同的加密指数e(这里取e=3),对相同的明文m进行了加密并进行了消息的传递,那么有:
$ c_1equiv m^e$ $mod$ $n_1$
$ c_2equiv m^e$ $mod$ $n_2$
$ c_3equiv m^e$ $mod$ $n_3$
对上述等式运用中国剩余定理,在e=3时,可以得到:
$ c_xequiv m^3$ $mod$ $n_1n_2n_3$
通过对$ c_x $进行三次开方可以求得明文。
writeup:
1.题目内容为:[{"c": 7366067574741171461722065133242916080495505913663250330082747465383676893970411476550748394841437418105312353971095003424322679616940371123028982189502042, "e": 10, "n": 25162507052339714421839688873734596177751124036723831003300959761137811490715205742941738406548150240861779301784133652165908227917415483137585388986274803},{"c": 21962825323300469151795920289886886562790942771546858500842179806566435767103803978885148772139305484319688249368999503784441507383476095946258011317951461, "e": 10, "n": 23976859589904419798320812097681858652325473791891232710431997202897819580634937070900625213218095330766877190212418023297341732808839488308551126409983193},{"c": 6569689420274066957835983390583585286570087619048110141187700584193792695235405077811544355169290382357149374107076406086154103351897890793598997687053983, "e": 10, "n": 18503782836858540043974558035601654610948915505645219820150251062305120148745545906567548650191832090823482852604346478335353784501076761922605361848703623},{"c": 4508246168044513518452493882713536390636741541551805821790338973797615971271867248584379813114125478195284692695928668946553625483179633266057122967547052, "e": 10, "n": 23383087478545512218713157932934746110721706819077423418060220083657713428503582801909807142802647367994289775015595100541168367083097506193809451365010723},{"c": 22966105670291282335588843018244161552764486373117942865966904076191122337435542553276743938817686729554714315494818922753880198945897222422137268427611672, "e": 10, "n": 31775649089861428671057909076144152870796722528112580479442073365053916012507273433028451755436987054722496057749731758475958301164082755003195632005308493},{"c": 17963313063405045742968136916219838352135561785389534381262979264585397896844470879023686508540355160998533122970239261072020689217153126649390825646712087, "e": 10, "n": 22246342022943432820696190444155665289928378653841172632283227888174495402248633061010615572642126584591103750338919213945646074833823905521643025879053949},{"c": 1652417534709029450380570653973705320986117679597563873022683140800507482560482948310131540948227797045505390333146191586749269249548168247316404074014639, "e": 10, "n": 25395461142670631268156106136028325744393358436617528677967249347353524924655001151849544022201772500033280822372661344352607434738696051779095736547813043},{"c": 15585771734488351039456631394040497759568679429510619219766191780807675361741859290490732451112648776648126779759368428205194684721516497026290981786239352, "e": 10, "n": 32056508892744184901289413287728039891303832311548608141088227876326753674154124775132776928481935378184756756785107540781632570295330486738268173167809047},{"c": 8965123421637694050044216844523379163347478029124815032832813225050732558524239660648746284884140746788823681886010577342254841014594570067467905682359797, "e": 10, "n": 52849766269541827474228189428820648574162539595985395992261649809907435742263020551050064268890333392877173572811691599841253150460219986817964461970736553},{"c": 13560945756543023008529388108446940847137853038437095244573035888531288577370829065666320069397898394848484847030321018915638381833935580958342719988978247, "e": 10, "n": 30415984800307578932946399987559088968355638354344823359397204419191241802721772499486615661699080998502439901585573950889047918537906687840725005496238621}]2.给了10组RSA的加密信息,共有10个公钥,且B包含了10个c,n,e,e都是一样的,因此想到了RSA低加密指数广播攻击。3.通过脚本获取到falg:import libnum
import gmpy2
dic = [{"c": 7366067574741171461722065133242916080495505913663250330082747465383676893970411476550748394841437418105312353971095003424322679616940371123028982189502042, "e": 10, "n": 25162507052339714421839688873734596177751124036723831003300959761137811490715205742941738406548150240861779301784133652165908227917415483137585388986274803},
{"c": 21962825323300469151795920289886886562790942771546858500842179806566435767103803978885148772139305484319688249368999503784441507383476095946258011317951461, "e": 10, "n": 23976859589904419798320812097681858652325473791891232710431997202897819580634937070900625213218095330766877190212418023297341732808839488308551126409983193},
{"c": 6569689420274066957835983390583585286570087619048110141187700584193792695235405077811544355169290382357149374107076406086154103351897890793598997687053983, "e": 10, "n": 18503782836858540043974558035601654610948915505645219820150251062305120148745545906567548650191832090823482852604346478335353784501076761922605361848703623},
{"c": 4508246168044513518452493882713536390636741541551805821790338973797615971271867248584379813114125478195284692695928668946553625483179633266057122967547052, "e": 10, "n": 23383087478545512218713157932934746110721706819077423418060220083657713428503582801909807142802647367994289775015595100541168367083097506193809451365010723},
{"c": 22966105670291282335588843018244161552764486373117942865966904076191122337435542553276743938817686729554714315494818922753880198945897222422137268427611672, "e": 10, "n": 31775649089861428671057909076144152870796722528112580479442073365053916012507273433028451755436987054722496057749731758475958301164082755003195632005308493},
{"c": 17963313063405045742968136916219838352135561785389534381262979264585397896844470879023686508540355160998533122970239261072020689217153126649390825646712087, "e": 10, "n": 22246342022943432820696190444155665289928378653841172632283227888174495402248633061010615572642126584591103750338919213945646074833823905521643025879053949},
{"c": 1652417534709029450380570653973705320986117679597563873022683140800507482560482948310131540948227797045505390333146191586749269249548168247316404074014639, "e": 10, "n": 25395461142670631268156106136028325744393358436617528677967249347353524924655001151849544022201772500033280822372661344352607434738696051779095736547813043},
{"c": 15585771734488351039456631394040497759568679429510619219766191780807675361741859290490732451112648776648126779759368428205194684721516497026290981786239352, "e": 10, "n": 32056508892744184901289413287728039891303832311548608141088227876326753674154124775132776928481935378184756756785107540781632570295330486738268173167809047},
{"c": 8965123421637694050044216844523379163347478029124815032832813225050732558524239660648746284884140746788823681886010577342254841014594570067467905682359797, "e": 10, "n": 52849766269541827474228189428820648574162539595985395992261649809907435742263020551050064268890333392877173572811691599841253150460219986817964461970736553},
{"c": 13560945756543023008529388108446940847137853038437095244573035888531288577370829065666320069397898394848484847030321018915638381833935580958342719988978247, "e": 10, "n": 30415984800307578932946399987559088968355638354344823359397204419191241802721772499486615661699080998502439901585573950889047918537906687840725005496238621}]
n = []
C = []
for i in dic:
n.append(i["n"])
C.append(i["c"])
# for i in n:
# for j in n:
# if i == j:
# continue
# else:
# if gmpy2.gcd(i, j) != 1:
# print i, j
N = 1
for i in n:
N *= i
Ni = []
for i in n:
Ni.append(N / i)
T = []
for i in xrange(10):
T.append(long(gmpy2.invert(Ni[i], n[i])))
X = 0
for i in xrange(10):
X += C[i] * Ni[i] * T[i]
m10 = X % N
m = gmpy2.iroot(m10, 10)
print libnum.n2s(m[0])4.最终得到flag:flag{wo0_th3_tr4in_i5_leav1ng_g3t_on_it}
八、zip文件头之爆破
题目描述:
我们刚刚拦截了,敌军的文件传输获取一份机密文件,请君速速破解
wirteup:
1.下载附件后,内容如下:
504B03040A0001080000626D0A49F4B5091F1E0000001200000008000000666C61672E7478746C9F170D35D0A45826A03E161FB96870EDDFC7C89A11862F9199B4CD78E7504B01023F000A0001080000626D0A49F4B5091F1E00000012000000080024000000000000002000000000000000666C61672E7478740A0020000000000001001800AF150210CAF2D1015CAEAA05CAF2D1015CAEAA05CAF2D101504B050600000000010001005A000000440000000000
很明显,504B0304是zip文件的文件头。
2.通过010 editor导入hex,然后保存为test.zip即可
3.同时也可以通过python脚本将十六进制转成zip文件
# coding=utf-8
import struct
# test.txt即为输入文件,test.zip即为输出文件
file = open("test.txt", "r")
ss = file.read()
f = open("test.zip", "wb")
i = 0
while i < len(ss):
s = ss[i:i+2]
temp = int(s, 16)
f.write(struct.pack('B', temp))
i += 2
file.close()
f.close()
5.通过输入破解的密码123456,解压出压缩文件,打开flag.txt,接口获得flag
6.flag为:
daczcasdqwdcsdzasd
九、LFSR算法解密一
writeup:
1.下载得到一个文件 末尾添加.zip.解压得到两个文件一个key 一个加密的py文件
lfsr这个算法经搜索可能是一个伪随机测试码产生器.
参考:https://www.anquanke.com/post/id/181811
def lfsr(R,mask):
output = (R << 1) & 0xffffff
i=(R&mask)&0xffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
mask = 0b1010011000100011100
key=open("key","rb").read()
for t in range(pow(2,19)):
R=t
get=0
for i in range(12):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
if chr(tmp) != key[i]: break
if i == 11: get = 1
if get == 1:
print "flag{%19d}" % int(bin(t)[2:])
break
十、LFSR算法解密二
writeup:
1.下载得到一个文件 末尾添加.zip.解压得到两个文件一个key 一个加密的py文件
2.根据R=int(flag[5:-1],2)以及len(flag)==27推测flag为21个二进制位,暴力解出flag即可
3.修改上面的脚本进行爆破:
def lfsr(R,mask):
output = (R << 1) & 0xffffff
i=(R&mask)&0xffffff
lastbit=0
while i!=0:
lastbit^=(i&1)
i=i>>1
output^=lastbit
return (output,lastbit)
mask=0x100002
key=open("key","rb").read()
for t in range(pow(2,21)):
R=t
get=0
for i in range(12):
tmp=0
for j in range(8):
(R,out)=lfsr(R,mask)
tmp=(tmp << 1)^out
if chr(tmp) != key[i]: break
if i == 11: get = 1
if get == 1:
print "flag{%21d}" % int(bin(t)[2:])
break
最终flag:
flag{110111100101001101001}十一、RAS解密
writup:1.下载附件,解压文件,得到一个文件名为cry200https://adworld.xctf.org.cn/media/task/attachments/82f462a5eb8543899f11b46cbfb4d827.zip2.通过命令file查看文件类型,得知是zip文件类型3.将cry200重命名为 cry200.zip,并解压得两个文件:key.pem 和 cipher.bin4.使用 RsaCtfTool 即可解密 工具使用命令: python3 RsaCtfTool.py --publickey key.pem --uncipherfile cipher.bin或者脚本:from Crypto.PublicKey import RSA
from Crypto.Util.number import *
from gmpy2 import *
import libnum
c=bytes_to_long(open('cipher.bin','rb').read())
key=RSA.importKey(open('key.pem').read())
n,e=key.n,key.e
#print(hex(n)[2:])
s=iroot(n+1,2)[0]
p=s-1
q=s+1
assert p*q==n and isPrime(p) and isPrime(q)
d=inverse(e,(p-1)*(q-1))
print(long_to_bytes(pow(c,d,n)))
5.最终得到flag:flag{how_d0_you_7urn_this_0n?}十二、RAS解密二
writup:1.下载附件,解压文件,得到一个文件名为cry300https://adworld.xctf.org.cn/media/task/attachments/c9b973a1f7114c0486b0410536370380.zip2.通过命令file查看文件类型,得知是zip文件类型3.将cry300重命名为 cry300.zip,并解压得两个文件:ecb.bmp和 task.txt4.根据task.txt背景描述:Somebody leaked a still from the upcoming Happy Feet Three movie, which will be released in 4K, but Warner Bros. was smart enough to encrypt it. But those idiots used a black and white bmp format, and that wasn't their biggest mistake. Show 'em who's boss and get the flag.5.根据背景介绍,原图片应该是bmp格式,经ecb工作模式加密得ecb.bmp;由于ecb工作模式不会掩盖明文的统计规律,因此只要能够修复ecb.bmp就可以见到明文,要修复ecb.bmp,则要求文件的前128字节为bmp文件格式特有的字节6.尝试直接打开BMP文件失败,可能是因为它以某种方式加密了:
7.通过winhex查看文件开头的十六进制,并没有发现BMP头。取而代之的是字符串“ Salted__”的十六进制。该字符串暗示数据已使用OpenSSL加密。opnnssl的“Salted__”之后的8个字节是 salt(ab 31 b5 e5 ca 3d b9 4d):文件的其余部分是加密数据。根据题目名称(ecb,_it’s_easy_as_123),它可能已使用ECB进行了加密。Linux penguin Tux位图图像,就是使用了ECB对其进行加密,以说明相同的明文块被加密为相同的密文块。对于具有大量重复数据块的明文,明文中的模式在密文中仍然可以识别:
8.如果我们可以将加密的数据转换为有效的BMP,则由于有了ECB的属性,我们应该能够从未加密的BMP中找到flag
通过BMP文件格式标准,可以用一个有效的BMP头替换OpenSSL字符串+8字节salt,那么就足以打开文件了
需要确定:
- 位图的宽度和高度
- 每个像素的位数
根据task.txt文本描述图像的分辨率为 4k,因此尺寸将为3840 x 2160或4096 x2160。我们可以尝试两者。
根据BMP规范,每个像素的位数可以是1、2、4、8、16、24或32。我们也可以尝试其中的每一种。
可以使用winhex删除前16个字节 ecb.bmp(“ OpenSSL __” + 8个字节salt)并替换BMP头:
Hex Value Description 42 4D "BM" Magic number (unsigned integer 66, 77) 76 90 7e 00 8294518 bytes (118+8294400) Size of the BMP file (8294400 = 3840x2160) 00 00 Unused Application specific 00 00 Unused Application specific 76 00 00 00 118 bytes (78+40) Offset where the pixel array (bitmap data) can be found 28 00 00 00 40 bytes Number of bytes in the DIB header (from this point) 00 0f 00 00 3840 Width of the bitmap in pixels 70 08 00 00 2160 Height of the bitmap in pixels 01 00 1 plane Number of color planes being used 04 00 4 bits Number of bits per pixel 00 00 00 00 0 BI_RGB, no pixel array compression used 00 90 7e 00 8294400 bytes Size of the raw bitmap data (including padding) 00 00 00 00 0 pixels/meter horizontal Print resolution of the image, 00 00 00 00 0 pixels/meter vertical (don't care about printing) 00 00 00 00 0 colors Number of colors in the palette 00 00 00 00 0 important colors 0 means all colors are important
9.将下面的十六进制删除53 61 6c 74 65 64 5f 5f ab 31 b5 e5 ca 3d b9 4df4 09 1a a5 df 88 b7 2c 0e bd 8a 73 98 15 ba 69a2 24 3e 09 94 cb 79 1e ea a1 ad 33 c8 17 66 6378 98 23 0b f0 af 20 38 f1 aa 0b f4 69 1c ec cffc d8 8e 3d 45 2a 99 b0 53 6b 50 0d 8a 3d c4 b762 9c 6a 54 f0 59 20 13 22 4f b6 e2 b6 aa 0a 8b5e 21 1a 9d cf 8c a2 f6 45 80 cb 9b b7 37 da 7f73 50 88 cb df 63 ee 22 d4 24 b3 b9 f4 24 ad 40然后再添加以下BMP字符:424d 7648 3f00 0000 0000 7600 0000 28000000 000f 0000 7008 0000 0100 0400 00000000 0048 3f00 0000 0000 0000 0000 00000000 0000 0000 0000 0000 0000 8000 00800000 0080 8000 8000 0000 8000 8000 80800000 8080 8000 c0c0 c000 0000 ff00 00ff0000 00ff ff00 ff00 0000 ff00 ff00 ffff0000 ffff ff00 ffff ffff ffff ffff ffff10.将ecb.bmp的前128字节替换为bmp文件格式特有的字节,则可以见到明文信息,实现的Python脚本如下:from Crypto.Util.number import long_to_bytes
with open('ecb.bmp','rb') as f:
data=f.read()
pre=0x424d76483f00000000007600000028000000000f000070080000010004000000000000483f00000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff00ffffffffffffffffffffL
out=long_to_bytes(pre)+data[128:]
with open('out.bmp','wb') as g:
g.write(out)
g11.最终得到falg:flag{no_penguin_here}
十三、仿射密码
基础知识:
仿射密码是一种专情密码,一对一替换:
1.加密函数是 e(x) = ax + b (mod m) 其中a和m 互质,m是字母的数目。
2.解码函数是 d(x) = a^-1(x - b) (mod m) (打不出来凑合一下 a^-1 乘法逆元)writeup:
1.下载附件,得到如下的字符串。 长度不长,大写字母和数字组成。 很容易让人想到 Base64/32 解密。
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI
base系列的加密解密特征(https://www.cnblogs.com/keeye/p/12250864.html):
Base64 : 由 0-9、a-z、A-Z、+、/ 及后缀 “=” 组成 将任意字节序列数据编码成ASCII字符串
Base32 : 用32个可打印字符 A-Z、2-7 对任意字节数据进行编码
2.通过Base62解码并没有发现什么
3.将BITSCTF 进行Base32加密 (https://www.qqxiuzi.cn/bianma/base.php)
得到:IJEVIU2DKRDA====
4.得到的这串密文与题目给出的字符串进行比对
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI
IJEVIU2DKRDA====
M解密两次对应的都是I,不同的字母对应的都是不同的解密字母,那么猜测可能是根据某种规则进行了字母替换。
对字母表进行编码:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 5 6 7
0 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 31
则有:
3 -> 11
4 -> 24
8 -> 12
20 -> 8
21 -> 21
25 -> 9
26 -> 22
5.那么,观察可得,这是仿射密码,这种密码相关介绍见:https://blog.csdn.net/x_yhy/article/details/83756908
仿射密码的a = 13和b = 4,对应表如下:
6.则密文进行仿射解密得:#coding:utf-8
#仿射密码解密
#改进欧几里得算法求线性方程的x与y
def get(a, b):
if b == 0:
return 1, 0
else:
k = a //b
remainder = a % b
x1, y1 = get(b, remainder)
x, y =y1, x1 - k * y1
return x, y
s = input("请输入解密字符:").upper()
a = int(input("请输入a:"))
b = int(input("请输入b:"))
#求a关于26的乘法逆元
x, y = get(a, 26)
a1 = x % 26
l= len(s)
for i in range(l):
cipher = a1 * (ord(s[i])- 65 - b) % 26
res=chr(cipher + 65)
print(res, end='')
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI -> IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU
对 IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU进行base32解密得:
7.或者脚本解密
from base64 import b32decode
def solve():
s='MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI'
dic='ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
msg=''.join([dic[(5*dic.find(x)+12)%32] for x in s])
return b32decode(msg+'='*(8-len(msg)%8))
if __name__=='__main__':
#python solve.py
print solve()
8.最终得到falg:
BITSCTF{S2VyY2tob2Zm}十四、RAS弱加密
writup:
1.下载附件,解压文件,得到一个文件名为bf930316910b451c94c41ce8a9d851a8文件
https://adworld.xctf.org.cn/media/task/attachments/bf930316910b451c94c41ce8a9d851a8.gz
2.通过命令file查看文件类型,得知是tar文件类型
3.将其重命名为ras.tar ,并解压得两个文件:flag.b64和key.pub
4.分部对key.pub和flag.64的进行查看,其内容都是经过base64加密
注意:显然在第一个文件中,flag经过base64加密,跑脚本时要记得给其解密
5.利用 openssl来查看 key.pub,分别计算得到p和q
root@kali:/opt/RsaCtfTool# openssl rsa -pubin -text -modulus -in key.pub
RSA Public-Key: (399 bit)
Modulus:
52:a9:9e:24:9e:e7:cf:3c:0c:bf:96:3a:00:96:61:
77:2b:c9:cd:f6:e1:e3:fb:fc:6e:44:a0:7a:5e:0f:
89:44:57:a9:f8:1c:3a:e1:32:ac:56:83:d3:5b:28:
ba:5c:32:42:43
Exponent: 65537 (0x10001)
Modulus=52A99E249EE7CF3C0CBF963A009661772BC9CDF6E1E3FBFC6E44A07A5E0F894457A9F81C3AE132AC5683D35B28BA5C324243
writing RSA key
-----BEGIN PUBLIC KEY-----
ME0wDQYJKoZIhvcNAQEBBQADPAAwOQIyUqmeJJ7nzzwMv5Y6AJZhdyvJzfbh4/v8
bkSgel4PiURXqfgcOuEyrFaD01soulwyQkMCAwEAAQ==
-----END PUBLIC KEY-----
得到 :
e = 65537
n (hex)= 52A99E249EE7CF3C0CBF963A009661772BC9CDF6E1E3FBFC6E44A07A5E0F894457A9F81C3AE132AC5683D35B28BA5C324243(十六进制)
https://tool.lu/hexconvert/
n(10)= 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019(十进制)
分解大数n,得到p、q
p = 863653476616376575308866344984576466644942572246900013156919
q = 965445304326998194798282228842484732438457170595999523426901
6.通过脚本对其进行解密
#coding:utf-8
import gmpy2
import rsa
from base64 import b64decode
p = 863653476616376575308866344984576466644942572246900013156919
q = 965445304326998194798282228842484732438457170595999523426901
n = 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
e = 65537
d = int(gmpy2.invert(e,(p-1)*(q-1)))
privatekey = rsa.PrivateKey(n,e,d,p,q)
with open("flag.b64","rb") as f:
str = b64decode(f.read())
print(rsa.decrypt(str,privatekey).decode())
7.最终得到flag:
ALEXCTF{SMALL_PRIMES_ARE_BAD}
十五、pdf之ROT13编码
writeup:
1.下载附件pdf,通过阅读器查看,发现文件无法查看
https://adworld.xctf.org.cn/media/task/attachments/9e45191069704531accd66f1ee1d5b2b.pdf
2.通过file命令查看文件类型
file flag.pdf
3.通过winhex查看文件,发现文件头是以:%CQS-1.5.格式开头(正常的pdf文件头部是%PDF-1.x数字开头)
4.通过ctfcrackt00ls工具对PDf关键字进行ROT13进行编码,可以看到得到CQS,正好是flag.pdf格式开头的
5.通过上述描述,进行rot13解密,得到解密后的pdf文件
cat flag.pdf | tr 'A-Za-z' 'N-ZA-Mn-za-m' > flags.pdf
6.打开pdf文件,发现部门内容被遮挡了
7.通过pdftohtml工具将其覆盖的文件转换成html
8.最终得到flag:BITSCTF{save_the_kid}
十六、维吉尼亚密码
基础知识:维吉尼亚密码是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式.加密原理:维吉尼亚密码的前身,是我们熟悉的凯撒密码。凯撒密码的加密方式是依靠一张字母表中的每一个字母做一定的偏移。密文生成过程中,其偏移量相等。而升级版的维吉尼亚密码则是在原有基础上,让相等偏移量变为不等的偏移量。以给出的密钥来确定密文的偏移量。在一定程度上,加大了解密的难度。当然原理还是一致的,都是依靠偏移量进行加密。这是一张用于加密的字母表。
比如给出的 明文是 HELLO 假定给的关键词是 JLAY ,那么对应的密钥便为:JLAYJ
那么对其进行加密,如图:H对应J行的是Q,E对应L行的是P,以此类推。最后得到的密文变为:QPLJX
writeup:
1.下载附件,根据题目提示是维吉利亚密码,查看文本内容如下
https://adworld.xctf.org.cn/media/task/attachments/429b7c1947d44bc4b7e62270d0fee6b3.zip
2.通过在线维吉尼亚解密网站对其进行解密,可以得到加密key为:icqvigenerehttps://www.guballa.de/vigenere-solver3.在result解密文本中搜索关键字flag,可得到 flag, '{' and 'vigenereisveryeasyhuh' and '}' 4.那么进行简化和去掉字符最终得到flag:flag{vigenereisveryeasyhuh}
十七、base64编码之RSA解密
writeup:方法一:
1.下载附件,可以看到RSA私钥上面的部分被屏蔽了请恢复私钥并解密文件,附件给出私钥编码的截图,但是只能看见最后5行
附件下载:https://adworld.xctf.org.cn/media/task/attachments/92d8c7449d614543a0f9da8f05e39bbe.zip
2.OpenSSL私钥结构
私钥信息按如下顺序排列:
version | pad | n | pad | e | pad | d | pad | p | pad | q | pad | x1 | pad | x2 | pad | x3
其中,pad是填充信息,各pad并不同,x1=d mod (p−1),x2=d mod (q−1),x3=p−1 mod qx1=d mod (p−1),x2=d mod (q−1),x3=p−1 mod q,填充pad用来注释接下来的大数的(字节)长度,\x02为pad开头的标记,有时后面接\x81或\x82,这用来标记长度值所占用的字节(\x81代表占用1个字节,\x82代表占用2个字节),有时后面不接\x81或\x82而直接放置长度;
例:\x02\x03代表接下来的大数的字节长度为3个字节;\x02\x81\x80,首先,\x81代表长度占用1个字节,因此\x80就是长度值,即128,表明接下来的大数的字节长度为128个字节。
将私钥信息按照上述顺序排列好之后,再进行base64编码
3.利用已知信息恢复私钥
截图可见编码为:
Os9mhOQRdqW2cwVrnNI72DLcAXpXUJ1HGwJBANWiJcDUGxZpnERxVw7s0913WXNtV4GqdxCzG0pG5EHThtoTRbyX0aqRP4U/hQ9tRoSoDmBn+3HPITsnbCy67VkCQBM4xZPTtUKM6Xi+16VTUnFVs9E4rqwIQCDAxn9UuVMBXlX2Cl0xOGUF4C5hItrX2woF7LVS5EizR63CyRcPovMCQQDVyNbcWD7N88MhZjujKuSrHJot7WcCaRmTGEIJ6TkU8NWt9BVjR4jVkZ2EqNd0KZWdQPukeynPcLlDEkIXyaQx
解码后结合OpenSSL私钥结构分析可得:x1,x2,x3为已知;但是仅有x1,x2,x3并不能恢复出p,q与d,若我们假设e为常用的指数3,65537等等,则可试出p与q:
d⋅e≡1 mod (p−1)(q−1)d⋅e≡1 mod (p−1)(q−1)
则有d⋅e≡1 mod (p−1)d⋅e≡1 mod (p−1)与d⋅e≡1 mod (q−1)d⋅e≡1 mod (q−1);
由x1x1与x2x2的定义可得x1⋅e≡1 mod (p−1)x1⋅e≡1 mod (p−1),x2⋅e≡1 mod (q−1)x2⋅e≡1 mod (q−1);
因此(p−1)|(x1⋅e−1)(p−1)|(x1⋅e−1);
记x1⋅e−1=r1⋅(p−1)x1⋅e−1=r1⋅(p−1);
由于x1=d mod (p−1)x1=d mod (p−1),则x1<(p−1)x1<(p−1);
几乎可以看做x1⋅e=r1⋅(p−1)x1⋅e=r1⋅(p−1),那么必有r1<er1<e;
同理可得r2<er2<e,其中x2⋅e−1=r2⋅(q−1)x2⋅e−1=r2⋅(q−1)
可以看到,ri<e,i=1,2ri<e,i=1,2,从而可使用试除法求出ri,i=1,2ri,i=1,2;
则p=(x1⋅e−1)/r1+1,q=(x2⋅e−1)/r2+1p=(x1⋅e−1)/r1+1,q=(x2⋅e−1)/r2+1;
4.解题
实现的Python脚本如下:
from Crypto.Util.number import bytes_to_long,isPrime,inverse
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
def genKey(X1,X2,X3):
e=65537L
N1=X1*e-1
N2=X2*e-1
for r in range(e):
if N1%(e-r)==0:
p=N1/(e-r)+1
if isPrime(p):
break
for r in range(e):
if N2%(e-r)==0:
q=N2/(e-r)+1
if isPrime(q):
break
N=p*q
phi=(p-1)*(q-1)
d=inverse(e,phi)
assert inverse(q,p)==X3
return RSA.construct((N,e,long(d),p,q))
def solve():
X1=bytes_to_long('\xd5\xa2%\xc0\xd4\x1b\x16i\x9cDqW\x0e\xec\xd3\xddwYsmW\x81\xaaw\x10\xb3\x1bJF\xe4A\xd3\x86\xda\x13E\xbc\x97\xd1\xaa\x91?\x85?\x85\x0fmF\x84\xa8\x0e`g\xfbq\xcf!;\'l,\xba\xedY')
X2=bytes_to_long('\x138\xc5\x93\xd3\xb5B\x8c\xe9x\xbe\xd7\xa5SRqU\xb3\xd18\xae\xac\x08@ \xc0\xc6\x7fT\xb9S\x01^U\xf6\n]18e\x05\xe0.a"\xda\xd7\xdb\n\x05\xec\xb5R\xe4H\xb3G\xad\xc2\xc9\x17\x0f\xa2\xf3')
X3=bytes_to_long('\xd5\xc8\xd6\xdcX>\xcd\xf3\xc3!f;\xa3*\xe4\xab\x1c\x9a-\xedg\x02i\x19\x93\x18B\t\xe99\x14\xf0\xd5\xad\xf4\x15cG\x88\xd5\x91\x9d\x84\xa8\xd7t)\x95\x9d@\xfb\xa4{)\xcfp\xb9C\x12B\x17\xc9\xa41')
rsa_key=genKey(X1,X2,X3)
key= PKCS1_v1_5.new(rsa_key)
with open('flag.enc','rb') as f:
return key.decrypt(f.read(),'')
if __name__=='__main__':
print solve()[:-1]
注:这里之所以猜测e为65537而不是3是因为ri<e,i=1,2,如果e=3可能情况太少。
程序运行结果如下:
$ python solve.py
5.最终得到flag:
0ctf{Keep_ca1m_and_s01ve_the_RSA_Eeeequati0n!!!}
方法二:
1.已给出部分解密,先把已给出部分进行base64解密
# -*- coding: utf-8 -*-
import base64
import binascii
a = """Os9mhOQRdqW2cwVrnNI72DLcAXpXUJ1HGwJBANWiJcDUGxZpnERxVw7s0913WXNt
V4GqdxCzG0pG5EHThtoTRbyX0aqRP4U/hQ9tRoSoDmBn+3HPITsnbCy67VkCQBM4
xZPTtUKM6Xi+16VTUnFVs9E4rqwIQCDAxn9UuVMBXlX2Cl0xOGUF4C5hItrX2woF
7LVS5EizR63CyRcPovMCQQDVyNbcWD7N88MhZjujKuSrHJot7WcCaRmTGEIJ6TkU
8NWt9BVjR4jVkZ2EqNd0KZWdQPukeynPcLlDEkIXyaQx"""
print binascii.hexlify(base64.b64decode(a))
得到:
3acf6684e41176a5b673056b9cd23bd832dc017a57509d471b024100d5a225c0d41b16699c4471570eecd3dd7759736d5781aa7710b31b4a46e441d386da1345bc97d1aa913f853f850f6d4684a80e6067fb71cf213b276c2cbaed5902401338c593d3b5428ce978bed7a553527155b3d138aeac084020c0c67f54b953015e55f60a5d31386505e02e6122dad7db0a05ecb552e448b347adc2c9170fa2f3024100d5c8d6dc583ecdf3c321663ba32ae4ab1c9a2ded6702691993184209e93914f0d5adf415634788d5919d84a8d77429959d40fba47b29cf70b943124217c9a431
2.rsa私钥格式解析标签头 3082025c(4 bytes) 类型为SEQUENCE 后接 604 bytes
020100 INTEGER 长度为0 内容为:VERSION
028181 INTEGER 长度为129 bytes 内容为: n(modulus)
0203 INTEGER 长度为3 bytes 内容为: e(publicExponent)
028180 INTEGER 长度为128 bytes 内容为: d(privateExponent)
0241 INTEGER 长度为65 bytes 内容为: p(prime1)
0241 INTEGER 长度为65 bytes 内容为: q(prime2)
0240 INTEGER 长度为64 bytes 内容为: d mod(p-1) exponent1
0240 INTEGER 长度为 64 bytes 内容为: d mod (q-1) exponent2
0241 INTEGER 长度为65 bytes 内容为: q -1 mod p coefficient
3.那么根据关键的标签头进行划分之后,可以得到:3acf6684e41176a5b673056b9cd23bd832dc017a57509d471b
0241//d mod(p-1) exponent1
00d5a225c0d41b16699c4471570eecd3dd7759736d5781aa7710b31b4a46e441d386da1345bc97d1aa913f853f850f6d4684a80e6067fb71cf213b276c2cbaed59
0240//d mod (q-1) exponent2
1338c593d3b5428ce978bed7a553527155b3d138aeac084020c0c67f54b953015e55f60a5d31386505e02e6122dad7db0a05ecb552e448b347adc2c9170fa2f3
0241//q -1 mod p coefficient
00d5c8d6dc583ecdf3c321663ba32ae4ab1c9a2ded6702691993184209e93914f0d5adf415634788d5919d84a8d77429959d40fba47b29cf70b943124217c9a431因为:e * dp == 1 (mod (p-1)) = d mod (p-1) e * dq == 1 (mod (q-1)) = d mod (q-1) q * qi == 1 (mod p) = q^-1 mod p 所以:(e * dp -1)/k +1 == (p)(e * dq -1)/j +1 == (q)(q * qi -1)/l == (p)4.脚本破解pq:
# -*- coding: utf-8 -*-
import gmpy2
d_p = 0xd5a225c0d41b16699c4471570eecd3dd7759736d5781aa7710b31b4a46e441d386da1345bc97d1aa913f853f850f6d4684a80e6067fb71cf213b276c2cbaed59
d_q = 0x1338c593d3b5428ce978bed7a553527155b3d138aeac084020c0c67f54b953015e55f60a5d31386505e02e6122dad7db0a05ecb552e448b347adc2c9170fa2f3
e = 65537
for k_p in range(1, e):
if (e*d_p - 1) % k_p == 0:
p = (e*d_p - 1) / k_p + 1
if gmpy2.is_prime(p):
print '[p] {}'.format(p)
break
for k_q in range(1, e):
if (e*d_q - 1) % k_q == 0:
q = (e*d_q - 1) / k_q + 1
if gmpy2.is_prime(q):
print '[q] {}'.format(q)
break
得到:[p] 12883429939639100479003058518523248493821688207697138417834631218638027564562306620214863988447681300666538212918572472128732943784711527013224777474072569[q] 125028936349231615998244651464070698822285137769477072954768059973117768558790240022895935986579497839370419296684431152244773691360895579114640461181273875.通过脚本解密:6.最终得到flag:0ctf{Keep_ca1m_and_s01ve_the_RSA_Eeeequati0n!!!}
十八、RSA256解密
writeup:1.下载附件,解压文件,得到一个文件名为8eec4a4af1e14eb08648c8fda7660a0f文件
https://adworld.xctf.org.cn/media/task/attachments/8eec4a4af1e14eb08648c8fda7660a0f.gz
2.通过命令file查看文件类型,得知是tar文件类型
3.将其重命名为ras256.tar ,并解压得两个文件:fllllllag.txt和gy.key
4.给出了公钥文件gy.key和密文文件fllllllag.txt,就是常规的RSA解密,有多种方法
方法一:利用RsaCtfTool工具(kali虚拟机中)
已知公钥(自动求私钥)—publickey,密文—uncipherfile
命令:python3 RsaCtfTool.py --publickey 公钥文件 --uncipherfile 加密的文件
方法二:利用公钥文件用openssl工具解出e、n,然后python3脚本解出明文
1、解出e、n
方式1:
打开kali虚拟机,用openssl解出e、n
命令:
openssl rsa -pubin -in gy.key -text -modulus
e为65537,n还比较短,用python先转换成10进制
方式2:
用脚本从公钥文件中解出n、e
# -*- coding: cp936 -*-
from Crypto.PublicKey import RSA
#1.从公钥文件中分解n和e
public_key = RSA.importKey(open(r"C:\Users\backlion\Desktop\8eec4a4af1e14eb08648c8fda7660a0f\ras256\RSA256\gy.key",'rb').read())
n = public_key.n
e = public_key.e
print('N:',n)
print('E:',e)
获取模数(Modulus) N=76775333340223961139427050707840417811156978085146970312315886671546666259161(0xA9BD4C7A7763370A042FE6BEC7DDC841602DB942C7A362D1B5D372A4D08912D9)
公钥指数(Exponent)e=65537 (0x10001)
5.对n进行因数分解
方式1:登录网站http://factordb.com/,解出p和q
方式2:使用yafu工具
(常用于比较大的整数分解)自动整数因式分解,在RSA中,当p、q的取值差异过大或过于相近的时候,使用yafu可以快速的把n值分解出p、q值!
用法:
yafu-x64.exe factor(76775333340223961139427050707840417811156978085146970312315886671546666259161)
6.到此,已经获取到RSA的全部参数
p = 273821108020968288372911424519201044333
q = 280385007186315115828483000867559983517
n=76775333340223961139427050707840417811156978085146970312315886671546666259161
e=65537
7.使用python代码解出明文
import gmpy2
import rsa
p = 273821108020968288372911424519201044333
q = 280385007186315115828483000867559983517
n = 76775333340223961139427050707840417811156978085146970312315886671546666259161
e = 65537
d = int(gmpy2.invert(e , (p-1)*(q-1)))
privatekey = rsa.PrivateKey(n , e , d , p , q)
with open("fllllllag.txt" , "rb") as f:
print(rsa.decrypt(f.read(), privatekey).decode())
最终得到flag:
flag{2o!9CTFECUN}
十九、rot13置换编码
1.下载附件,解压压缩文件,通过记事本打开里面包含密文:
XMVZGC RGC AMG RVMG HGFGMQYCD VT VWM BYNO, NSVWDS NSGO RAO XG UWFN AF HACDGMVWF. AIRVFN AII AMG JVRRVC-XVMC, FYRBIG TVIZ ESV SAH CGQGM XGGC RVMG NSAC A RYIG TMVR NSG SVWFG ESGMG NSGO EGMG XVMC WCNYI NSG HAO FVRG IVMH JARG MVWCH NVdeFAL NAZG NSGR VTT NV EAM. OVWM TIAD YF "CV NSYF YF CVN JMOBNV RO HGAM", YC IVEGMJAFG, EYNS WCHGMFJVMGF YCFNGAH VT FBAJGF, FWMMVWCHGH XO NSG WFWAI "TIAD" NAD ACH JWMIO XMAJGF. GCUVO.
这段字符串被替代密码加密。这个加密方法是把一些字母用另外一些字母替换。
2.由题目名称safer-than-rot13,先对密文进行rot13置换(这里通过ctfcracktools工具中的rot13解码),看不出任何逻辑。3。用在线解密解密quipqiup.com(http://quipqiup.com/) 4.得出解码:BROKEN MEN ARE MORE DESERVING OF OUR PITY, THOUGH THEY MAY BE JUST AS DANGEROUS. ALMOST ALL ARE COMMON-BORN, SIMPLE FOLK WHO HAD NEVER BEEN MORE THAN A MILE FROM THE HOUSE WHERE THEY WERE BORN UNTIL THE DAY SOME LORD CAME ROUND TO TAKE THEM OFF TO WAR. YOUR FLAG IS "NO THIS IS NOT CRYPTO MY DEAR", IN LOWERCASE, WITH UNDERSCORES INSTEAD OF SPACES, SURROUNDED BY THE USUAL "FLAG" TAG AND CURLY BRACES. ENJOY.5.或者通过命令置换得到:cat cry100 | tr A-Za-z N-ZA-Mn-za-m > dec1006.简单翻译如下
破碎的人更值得我们同情,尽管他们可能同样危险。几乎所有的人都是普通的,简单的人,
他们从来没有离开过他们出生的房子超过一英里,直到有一天上帝来带他们去打仗。你的
FLAG 是“NO THIS IS NOT CRYPTO MY DEAR”,小写,用下划线代替空格,周围是通常的
“FLAG”标签和大括号。享受吧。
7.可根据文意解最终得到flag:
no_this_is_not_crypto_my_dear
二十、工控流量分析
题目:有黑客入侵了工控设备后再内网发起大量扫描,而且扫描次数不止一次。分析日志指出第四次发起扫描时数据包的编号,flag形式为{}
题目附件连接:https://adworld.xctf.org.cn/media/task/attachments/57971150970f41609af811c73d8d8aac.zip
writeup:1.下载附件,并解压得到文件capture.log2.利用linux 的file命令查看日志文件属性,发现capture.log被出题者故意篡改过,对解题人进行迷惑。可以看到是pcap流量文件类型。
3.将文件名重命名为capture.pcap ,利用wireshark工具查看内容,分析流量包发现存在ICMP、TCP、UDP协议的流量包,其中IP地址192.168.0.9向IP地址192.168.0.99发送大量的TCP请求,
每次发送TCP请求是,会先进行一次ICMP的Ping请求.
3.发现数据报文有多个ip都对192.168.0.99目标机器进行扫描,分别为192.168.0.9、192.168.0.1、192.168.0.254、192.168.0.199,它们共同特点是每次发起端口扫描时候,
先进行ping操作,在wireshark中过滤出ICMP的数据包进行分析,尝试提交第四次发起扫描第一个报文编号155989,Flag为155989
4.最终得到flag:flag{155989}
基础知识:
1.有限域GF(2^n)
构造有限域GF(2^n)时,首先需要GF(2)上次数为n的本原多项式g(x);对于GF(2^n)上的每个元素a,都可以用一个次数不超过n的多项式fa表示:fa(x)=∑n−1i=0ai⋅xi,其中an−1⋯a0是a的二进制表示;从而GF(2^n)上的四则运算定义如下:
- 加法:对于a,b∈GF(2n),它们的多项式表示分别为fa,fb,记fc=fa+fb(其中系数的加法为GF(2)上的加法,即异或运算),则cn−1⋯c0的二进制值c为a+b的值;
- 减法:由于GF(2)上的加法与减法等价,因此对于a,b∈GF(2n),a+b=a-b;
- 乘法:同样地,a,b的多项式表示fa,fb,记fc=fa⋅fb mod g,由于多项式g的次数为n,故多项式fc的次数不超过n,则cn−1⋯c0的二进制值c为a⋅b的值;
- 除法:先介绍(乘法)逆元,本原多项式是一种具有特殊性质的不可约多项式,对GF(2)上任意次数不超过n的多项式f,都存在GF(2)上次数不超过n的多项式h,使得f⋅h≡1 mod g;与f作除法等价于与f的逆元h作乘法;
2. process(m,k)
考虑t2,t∈GF(2256),构造GF(2256)的本原多项式为g=x256+x10+x5+x2+1,记t的二进制表示为tn−1⋯t0,则t的多项式表示ft(x)=∑n−1i=0ti⋅xi=(((tn−1⋅x+tn−2)⋅x+⋯+t1)⋅x+t0),考虑t2:
f2t mod g
我们再来对比函数process(m,k):
def process(m, k):
tmp = m ^ k
res = 0
for i in bin(tmp)[2:]:
res = res << 1;
if (int(i)):
res = res ^ tmp
if (res >> 256):
res = res ^ P
return res
res=res<<1代表乘以x,多项式的系数全体左移一位;
if (int(i)):res^=tmp等价于res^=int(i)*tmp,代表;
if (res>>256):res^=P代表模本原多项式g;
综上,process(m,k)实际上实现了GF(2^256)上的元素m与k之和的平方;
3.解密过程(在GF(2^256)上的运算),其中已知则,可解出secret:(在GF(2^256)上的运算)接下来解出:(在GF(2^256)上的运算)然后解出flag(即):writeup:1.下载附件,对压缩包进行解压,含有两个文件:oneTimePad.py和 ciphertext其中oneTimePad.py是加密脚本,ciphertext为密文,密文内容为:af3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f
630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c
e913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b
2.对python 代码进行分析,了解运算流程:#!/usr/bin/env python# coding=utf-8from os import urandomdef process(m, k): tmp = m ^ k res = 0 for i in bin(tmp)[2:]: res = res << 1; if (int(i)): res = res ^ tmp if (res >> 256): res = res ^ P return res
def keygen(seed): key = str2num(urandom(32)) while True: yield key key = process(key, seed)
def str2num(s): return int(s.encode('hex'), 16)
P = 0x10000000000000000000000000000000000000000000000000000000000000425L
true_secret = open('flag.txt').read()[:32]assert len(true_secret) == 32print 'flag{%s}' % true_secretfake_secret1 = "I_am_not_a_secret_so_you_know_me"fake_secret2 = "feeddeadbeefcafefeeddeadbeefcafe"secret = str2num(urandom(32))
generator = keygen(secret)ctxt1 = hex(str2num(true_secret) ^ generator.next())[2:-1]ctxt2 = hex(str2num(fake_secret1) ^ generator.next())[2:-1]ctxt3 = hex(str2num(fake_secret2) ^ generator.next())[2:-1]f = open('ciphertext', 'w')f.write(ctxt1+'\n')f.write(ctxt2+'\n')f.write(ctxt3+'\n')f.close()因此这里的关键是 process 函数,只要能够通过 process 的输出求输入:
- process(key2, seed) 已知,通过输出求输入,得到 a1 = key2 ^ seed
- key2 已知,∴ seed = a1 ^ key2
- process(key, seed) 已知,通过输出求输入,得到 a2 = key ^ seed
- seed 已知,∴ key = a2 ^ seed
- ctxt1、key 已知,且 ctxt1 = true_secret ^ key,∴ true_secret = ctxt1 ^ key
- true_secret 就是 flag
3.通过尝试,发现将 process 的输出作为输入(m ^ k)运算 256 轮,最终结果与最初输入相同,因此我们可以写出 process 的反函数 arcprocess
4.通过解密脚本进行解密:
P = P = 0x10000000000000000000000000000000000000000000000000000000000000425
def load_file(filename):
content = []
with open(filename, 'r') as fp:
for line in fp.readlines():
content.append(int('0x' + line[:-1], 16))
return content
def str2num(s):
ans = 0
for c in s:
ans <<= 8
ans += ord(c)
return ans
def num2str(n):
s = ''
while n:
s += chr(n & 0xff)
n >>= 8
return s[::-1]
def bbencode(n):
a = 0
for i in bin(n)[2:]:
a <<= 1
if int(i):
a ^= n
if a >> 256:
a ^= P
return a
def process(m, k):
tmp = m ^ k
res = 0
for i in bin(tmp)[2:]:
res <<= 1
if int(i):
res ^= tmp
if res >> 256:
res ^= P
return res
fake_secret1 = "I_am_not_a_secret_so_you_know_me"
fake_secret2 = "feeddeadbeefcafefeeddeadbeefcafe"
if __name__ == "__main__":
cipherText = load_file('ciphertext')
key1 = str2num(fake_secret1) ^ cipherText[1]
key2 = str2num(fake_secret2) ^ cipherText[2]
temp = key2
for i in range(255):
temp = bbencode(temp)
seed = temp ^ key1
assert process(key1, seed) == key2
temp = key1
for i in range(255):
temp = bbencode(temp)
key = temp ^ seed
plainText = cipherText[0] ^ key
print(num2str(plainText))
5.最终得到flag:
二十一、异或加密
基础知识:XOR 加密详细介绍:
https://www.ruanyifeng.com/blog/2017/05/xor.html
异或加密特性:
1 两个值相同时, 返回 false, 否则返回 true .
2 如果对一个值连续做两次 XOR, 会返回这个值本身.
3 加密应用:
假设原始信息是 message, 密钥是 key, 第一次 XOR 会得到加密文本 cipherText. 对方拿到以后, 再用 key 做一次 XOR 运算, 就会还原得到 message.
4 一次性密码本 one-time pad https://en.wikipedia.org/wiki/One-time_pad (OTP):
key 的长度大于等于 message
key 必须是一次性的, 且每次都要随机产生
满足上述两个条件, 即称为 OTP
writeup:
题目附件:
0529242a631234122d2b36697f13272c207f2021283a6b0c7908
2f28202a302029142c653f3c7f2a2636273e3f2d653e25217908
322921780c3a235b3c2c3f207f372e21733a3a2b37263b313012
2f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d
283f652c2b31661426292b653a292c372a2f20212a316b283c09
29232178373c270f682c216532263b2d3632353c2c3c2a293504
613c37373531285b3c2a72273a67212a277f373a243c20203d5d
243a202a633d205b3c2d3765342236653a2c7423202f3f652a18
2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c
263e203d63232f0f20653f207f332065262c3168313722367918
2f2f372133202f142665212637222220733e383f2426386b
1.利用一些用同个密钥生成的密文, 猜对其中部分密文对应的明文, 即可求出公共密钥, 再用该可能的密钥去解其他的密文, 若符合, 则为密钥正确.
2.下载附件, 得到如下字符串
https://adworld.xctf.org.cn/media/task/attachments/f331d71a103f49bc94c2cc7838c29a9c
0529242a631234122d2b36697f13272c207f2021283a6b0c7908
2f28202a302029142c653f3c7f2a2636273e3f2d653e25217908
322921780c3a235b3c2c3f207f372e21733a3a2b37263b313012
2f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d
283f652c2b31661426292b653a292c372a2f20212a316b283c09
29232178373c270f682c216532263b2d3632353c2c3c2a293504
613c37373531285b3c2a72273a67212a277f373a243c20203d5d
243a202a633d205b3c2d3765342236653a2c7423202f3f652a18
2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c
263e203d63232f0f20653f207f332065262c3168313722367918
2f2f372133202f142665212637222220733e383f2426386b
3.通过十六进进制转asci发现转码出乱码
http://www.ab126.com/goju/1711.html
4.对于OTP密码的重用,我们可以利用Crib dragging attack来破解。这是一种已知部分明文的攻击,counter mode的block cipher如果重用了IV或者counter也可以用这种攻击。
实现这种脚本:https://github.com/SpiderLabs/cribdrag进行破解
5.将上面的文本内容都按一行展开
0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b
python cribdrag.py 0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b
6.程序会提醒我们输入一个可能存在于明文或者密钥里的字符串,根据题目提示,flag的开头是 ALEXCTF{,把这串字符输入:
7.可以看到0这个选项就是有意义的字符串。对于可能有意义的字符串,程序会在序号之前加上***。程序提示输入正确的位置,我们输入0。程序又会提示我们输入我们的crib是明文中的还是密钥中的,假设flag是密钥,就输入key:8.这样程序就恢复了一部分明文。在刚才的结果中,不止0一个位置是有意义的,*** 260: "ncryptio"也同样有意义。再次输入ALEXCTF{,输入260作为正确的位置。现在的结果如下:9.回到明文开头,我们可以猜测这是一封信的开头,Fri开头的单词很可能是Friend。输入“Dear Friend,”作为crib。得到0: "ALEXCTF{HERE"。 10根据flag的常见格式,可以猜测HERE之后是下划线。将“ALEXCTF{HERE_”作为crib输入:
11.得到有意义的字符串有: *** 260: "ncryption sch", *** 234: "gree with me ",*** 208: "cure, Let Me ",*** 182: "ever if the k",*** 156: " proven to be",*** 130: "hod that is m",*** 104: "is the only e",*** 78: "n scheme, I h",*** 52: "sed One time ",*** 26: "nderstood my
先看260,可以猜测后面的单词是scheme,输入"ncryption scheme "作为crib:260: "ALEXCTF{HERE_GOES"
将新的key后面加上下划线输入:
*** 260: "ncryption scheme a", *** 234: "gree with me to us",*** 208: "cure, Let Me know ",*** 182: "ever if the key is",*** 156: " proven to be not ",*** 130: "hod that is mathem",*** 104: "is the only encryp",*** 78: "n scheme, I heard ",*** 52: "sed One time pad e",*** 26: "nderstood my mista",*** 0: "Dear Friend, This "
52的后面几乎可以确定是encryption,而且这样填充的字母多,所以这次输入"sed One time pad encryption":
52: "ALEXCTF{HERE_GOES_THE_KEY}AL"
12.使用python脚本快速解密:#!/usr/bin/env python3
import binascii
def dec(msg, key):
'''
Simple char-by-char XOR with a key (Vigenere, Vernam, OTP)
'''
m = ""
for i in range(0, len(key)):
m += chr(msg[i] ^ ord(key[i]))
return m
######################################
lines = []
with open("msg", "r") as f:
# Read lines from file and decode Hex
ls = f.readlines()
for l in ls:
lines.append(binascii.unhexlify(l[:-1]))
# Step 1: Decode each line with the known key
k = "ALEXCTF{"
mes = []
for l in lines:
m = dec(l, k)
mes.append(m)
print(mes)
# Step 2: Guess some part of the first message 'Dear Fri'
k = "Dear Friend, "
m = dec(lines[0], k)
print(m)
# Step 3: Decode each line with the new known key
k = "ALEXCTF{HERE_"
mes = []
for l in lines:
m = dec(l, k)
mes.append(m)
print(mes)
# Step 4: Guess some part of the last message 'ncryption sc'
k = 'ncryption scheme '
m = dec(lines[-1], k)
print(m)
# Step 5: Decode each line with the new known key
k = "ALEXCTF{HERE_GOES_"
mes = []
for l in lines:
m = dec(l, k)
mes.append(m)
print(mes)
# Step 6: Guess all the second message 'sed One time pad e'
# the third message is 'n scheme, I heard '
# so we can retrive the complete key
k = 'sed One time pad encryptio'
m = dec(lines[2], k)
print(m)
'''
['Dear Fri', 'nderstoo', 'sed One ', 'n scheme', 'is the o', 'hod that', ' proven ', 'ever if ', 'cure, Le', 'gree wit', 'ncryptio']
ALEXCTF{HERE_
['Dear Friend, ', 'nderstood my ', 'sed One time ', 'n scheme, I h', 'is the only e', 'hod that is m', ' proven to be', 'ever if the k', 'cure, Let Me ', 'gree with me ', 'ncryption sch']
ALEXCTF{HERE_GOES
['Dear Friend, This ', 'nderstood my mista', 'sed One time pad e', 'n scheme, I heard ', 'is the only encryp', 'hod that is mathem', ' proven to be not ', 'ever if the key is', 'cure, Let Me know ', 'gree with me to us', 'ncryption scheme a']
ALEXCTF{HERE_GOES_THE_KEY}
'''
最终得到flag:ALEXCTF{HERE_GOES_THE_KEY}
1.下载附件,并打开流量包,发现存在PRES、TCP、COTP、MMS协议的流量,其中选择一个数据包,追踪TCP流发现存在关键字flag.txt,如图所示:过滤tcp协议,然后搜索关键词"flag",直到搜索到flag.txt可能有问题。但是没有发现可利用点2.然而通过多次分析与flag.txt相对应的流量包中,没有发现flag.txt的内容,于是换一个思路,对流量包进行关键字(jpg、png、zip、rar、flag)搜索,查看是否存在其他的文件。在linux系统中使用grep指令,可以对文件进行指定关键字搜索。linux中grep命令用法,我们使用指令进行关键字搜索grep "flag" -a flag.pacp
grep ".zip" -a flag.pacp
grep ".jpg" -a flag.pacp
grep ".png" -a flag.pacp
最终,发现存在base64加密的png图片码,如图所示:
运行脚本,将图片码进行base64解码,解码后得到写有Flag的图片:
# coding=utf-8
import os, base64
img_str = 'iVBORw0KGgoAAAANSUhEUgAAAdAAAABiCAYAAADgKILKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAABzXSURBVHhe7Z2Js11Fncfn75maqZmaqZkaS0elXAp1GHRUhGFAQHYQFQRFBWQRiBoBWQyyKaBsxo0tCAgkQHayQEL2jSxAyEoSIAHOvM/JPTPn9fv1Od19+9z3bvh+qr5FkXe77z33ntO/7l//fr/+m0IIIYQQ0ciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAnIgAohhBAJyIAKIYQQCciACiGEEAl0ZkDff78oNm/ZV8xfuK2Y8fxrxex5W4vlK3cVe/Ye6L1CCCGEGF6yGtC33n63uOPuNcW/fHJG8bcffsarf/3UjNLAVtz/h/Xm6/h3IYQQYiKSzYBufePt4thT55qG0NXxp8/ttTqIDGj/vP3Oe+VKf/L1y4qTzppffOq/ni/+6bDpxY+ve7n3irHw/VrKzdsjE6tFL24v7p26rrhs0pLy8x3+pZnFhz/zbDnZ+th/PFd86auzi3MuWFhcc+Py4qFpG4s1694cNcmKYf/+94oXFm4rbr1zdXHe9xcVn/+fWcVHPvv/7/WVk+YU371kcXHbyN9nzd1a7JVXRHxAeGdknFi2Ylfx+FNbiql/3lA8MPK8/+XJzcXLy3eWz80wcdxpc4t//sSMciw55Zz5xXW/WF4+zwcODO46shhQBqCjvzbHNIKWfnjVS72WB2HQtl7XxWB+KDJz9tbiM1+eaX6HTQbUej3KxZKXdxRXTV5aehys92kThm/u/Dd6vbXD9sDd960tPvH558z+fGKicfmPl5RGW4hBsnDx9lGT10q5YTuNyemHDn/WfAYQk8xf3LqyeGPb271W3bLl1X2l0bP01PRXe6/ygwG1ruOLx88uFr+0o/eqbsliQPlhrAvxiZVBHW4Y63Vd3EiHGtOe2Gx+d5XGw4CuWLWrOPv8BWbfsXp25uu9XptZMDIQ+SYRoXrksU293oToFp6Rc7+3yLwPUS7ee+/94r6p64t//Ph0830sYWSffGZLr4duwLt0wcWLzfdHGNE2fAYU/f1HpxezR1ajXdO3Ad24aW/xdx+xL+LIY2cV0597rdj95v7yh9y9e3/pysOFUEcGNA1mcKyerO/us0fNLF2iv/vjht6rx2K1Q6ngAvrlHau890OKdu3a3+vdz2NPbs7ynq++tq/XoxDd8MrGvaUHzrr/6srBu+++X1w5eanZf4gwvF2BXbDes1KIAWXhdta3FxSHHWl7nNiueXNP+/jRD30b0Ft+tcr88J/7ysxi+/YwV4AMaBpTbls55js75uQ5xcpVu3uvaMZtWymFnbveKc449wWzv1SxV9rG3BfeyGI8+d6E6IrXt75VDvisjKz7z1UOMEJW3zF68un8K9E9ew6U+5bW+1UKMaAVrGbJ9vj0F58f088fH3ql96pu6NuAEvzhfmjEDCMUGdA08PXXv69/+Nj0cq8jlHrbumLZsfOdoD3wE8+cV9zzwLrS3cpqjz1LghrwUODJwBiyh0lAAK8norsJ2n3yC2Mfmkpfv2BBOQDQ9959B8pgph073iknGLi+L5+05P/2Z2+/a/S2ghA52LV7f3Hrr1eXwS7u/dmkfmla4bG4mfqnDaU3kBiDm+9YVfzbp+3Px/OBpysnN94yduLvKsaAVry4ZMeYfggi7JK+DCgrTPcDo3//3LNRkVAyoPGQMuR+X0SWxuC2rxQDRunkrx80eD5d+MPFwaviig0b9xSbNu/t/Z/NXfesNd+P/Z6/PtMehAAYcaIRyVEWIjd4Uax7tE39wGTRWo0hDIqVi8/E252QVyJyPhfs/YZ4jFIMKBBhX++HbIQu6cuAWhYfff/yF3uvCEMGNB5r8tK2YnNx21eK4Wc3LDP7QAQjPPNsuCciBvbUfYMEq0shJgKkSln36FfPmFemWvk8eP1wz+/WmX1iXDCuPja8sse7Ul67vv8IdfZk8ULV+/3a2fPNgMNUA0o0fb0fvHJd0pcBfXrGq6M+bCVcFjHIgMaDa8j9vnhwYnDbVwpl/oJtZnvExv7qtXGrzhhWrdltvu9RJ85Jzh8VIjdLl+0cdX/iPmVbgQkg5DagBPL5tjVw2bbx69+uMdv+fMqK3ivSYT/S7Ze8zRMco4pSDShZB/V+cEF3SV8G9M+PbBz1YSs1RX5ayIDGw2zO/b64+WNw21cK4cDI+2OsrPa4UEnM7hLC7K33nnL7qt4rhBh/eE7JSybHkqIFbHnUyW1AMUhWf6d/64XeK5ohnoFVm9uez99PoQVyS90cVAwnk13yvev/jlINKC7qej9HHD2r95du6MuAYijrH7ZSbOSTDGgargvzhl/GzRLrbesKgT1Gqy2i4lDXsG9pvTdBSkJMJJ6f/bo3HSu3AaVwidXfE0+FR9N+77IXzT4I/kvFSt2ZOedgnqaVhpJqQL98wujv89RvhE0cUunLgPoM33gaUGY0zHZwV7BKeXBklcznmfb45jLijIiyrlx89EvEJxFwvx8Z4Pn8vO9LS3eU0aa5YVZZ/75+ct2y3l/CqLetKwRfcASBCIMoCeYzoKkP3kSHqGXuK6InmaCwz4sbO/Re5jdZ8vLO8n4kv4/VEFswg8h95d4nXuLhaZvKz86zwUqJKOpQSAOhqMYfHnyl7IPnmmozuZ8rVmDsTfL9Mm48+OjG8n2pUoXXJTc5DShuYcsYEbQTkk9dQUERtw/0q9/EebgqGHfdvtj7rO5dKwI45TmmPzcv/uIfja56l5soA9qW/Nqm8y+yQ4r7NaC4SbjpybOigIDVV124DNgvzJVki1uGh833MCDqvhIuTjGJihtuXjHmdTGRtKRh1Nte/TN/1SGLetu62li3/k2zHaKowSDwrYBx2XQx0HXBFT8Zu1pwXdBMBM88z1/VicCQ52b5qzVhELjvcMFZ7REFN2Jd7gScWH3VB2qiPUkP8r03rn6eWT6jBQMi1WRO+6Y/v5iI/7vvXVtGpaeC4SHYrS2PGRckv9mCRduCJy5t5DSg6zfYvwmBOzGsWWs/39wnsfC7UFDH7Yu8zQqrGEyKASUX3e2HMbZLht6AMpD6wq/bxN5ETK1VC2bW1g3iEwnEhHKDVSWEKLJQ3A1zSoPFUG9bVxusAKx2zCT37UsfyGJoMuKscIYBCv+7n33StQcnQUwKb7q1PV+uEgNFFZhSwRGCHz8irC4wq5SY2AVWrlY/m7YcTD1atXp3OZmxXuOKZ8KtQ0x97ZCKPZX++5S55So1ltdef2uMJydE/Y4bFTkNqC+oM9aI4K2wCj6wCIidODCBcvv5xncWjurH/TtKMaBECrv9dL2lM/QGlFJOVttQMXBwXSlwikFoZZG6uBEp6fUdoxYkM/JQfvrz0QMwq5EY6m3raoOZqNXu0qvz5Yu1wQPomzjxm3RRQSU37Fm7n52cWa4NQ+r+rU31IDK2L1IqNBEYGML2HWNn+4h8WlYw3OPW330iX68qYk6lGlx81uuahDGKcQuTZ+xLhWoSK6amdJAYchpQ0tisvnCdx+LuJVaKKTS/bmRF7AYk4XVg7KtT/3ulFAPKqtbthzG6S4begOI6tdoiaiFWx3pZf69E7pP7o7bhm+2FigHCzYlClEYMxR2Aud4Y6m3ragL3qC9X7NHHB1uMnYHB+hyVmGCQ7jNR4VAF9zMT9MD+nvvvIcJgYrzwiqRM7JA1wFlg5Kz2jBExHpm6LrnypXIVzThh/T1E1Qq+DfZOWbVafSC+P8YOa3+OIJtc5DSgbg5kJba3Yvn2D+zfYLlTx9wHv6O1uMHd7uK+BqUYUCbNbj9UN+uSKAOK24xSa5V8pwnw7/XXVfJV+O/HgFauJAYPfvRH/rKp/Jz1QBZ+TGZDFDq3QrRRzEPB/k/ToeHlHusD68o8SQKIOJqHmztkUIspKefOOOk/hnrbupogSMpqgyrX9KCg2pWVQ1YXkwoCZnKtGHJCUIb7edkvdI9/I9Gc54frwO3fNCHEq/Gfx4w2YASWXHvT8jIAiepNbV6bkMozb701thIWcmuc1t+b+7XJaCGrMAclGRl46QMPTZtbmue/jT89bE+8Mf4cD8j5uhU7RlbbRNJi4BlnHv9rvlVNTgPq2ysO+T5cJl1je0CqyNk2iIVw25L2ZgV9ua9DKQbUWkwRaNclUQbUpR/DV6fffu4cGRTayr5VEADgM2QhdWRxrzUFdWAAfVGoFBawcp7qiol0w0jX27IyjKHetq4mLDdJpXqA1KBgzy1kn49gE77b0AMOBgFG0fqslTiejdWkC9fsy8F1xfmOGDsX9vB89U95PnDRNsE9brWtC8PpTlyYzLr3rU8YMyKHXVj9XnSFf3+Ua27DLfmGcDtvfaP5/iBQJ+d9ntOA+rY0tiXc89ZBFYiDuNsgmMd6Jq17GdzXoRQDykH8bj8p++IxHBIGNJbrp4zde0KEyLcxZ97YkOxKv7m/fcOaoIWmA58ZVENxb3Iexhjqbetqgnwyqw0r8tgAg1ysXL07+BBtJhl8bzzk481vR+4X6zMiBqCmCR21gnG3Wm0rtZV2nPG8f0umbaDElW+1q9RmxHwrnEq4T5sGPwy4z/tAtZ+me9FXwzsm/iAXOQ2oL9o5JbDPV5GIlXsbbnAjYjvFh/talGJArSISXR+S/4E0oOSPWe+Hi6YN394AbjE3CtKHzwghBtUQeC93o59BKYZ627qa8O05E4wxnpDfG1O4mxUpe7bjZfTBd9+jEDehNVBVOvbUuWUkbxNcu+8ggBBjYrVDIbnATA6stpVCAvvY37Laoibjy1aD1SZm8pqLnAbUF5vQ9ltY+LwjuNGbYJXptmFy2xSL4L4epRhQApzcfrqOyP9AGlD2NKz3a4tixRVitUNLXrbdExbs3VkJzyjkmjGeVgCKz0Xiw21fqQnfb4VrerxhoCC/1zeQWOLgA+t0ikHg+y4ZcEJOMyJH0mqPQgvq+yZE7Ke1YbVDoZG8FFS32uO6DpmMsgpmImT10RQ4w8lAVhtfkGOX5DSgVj8oZZJ4/+/jx2SeP+tYw7aTkdzXoxQDCq5rn/sDD1VXfCANKAEC1vuRKN2EFeWFMLyxN+mPfmqX3PJdMwMKqxL28aybNLaMH7h9VGrCVwGIQW+iwD4Wbvq26OtKDOTj4dL13ffcGyGw6rbao9AzHH2rsZDf02qHQiPa3TSsSjEVtS681C471+SCZg/TaoOowjNIchpQX9pSzNGSFd4VaMOKzjoFhtq0bWOj2walGlA8D9y79b4IHMW7yGQxNIo4lEPWgPJFUl2ElRqrjONPn1u6GZuiZ1ETnEhgtYk9fQYIfLL68l0zszvr9axWSHtImWVa/aEmrI161Db5GA/wNOASD9kfJX2kydVFdDe/TayaKvzwd+uzWKH+Fr6JIAqtxkTlIKt9yCkWVjsUWl7P9wyEbmOAL9ilba/uWxfaucyIil5twUS5yGlAfWNbPaI4FF9Oqe97xSXven74/5DAzHqbSqkGFPjtyHqwJhT99GtxSBlQSvMxy/C5hkLUhC/8n1qZscRes2VACTShtmnTwN+E21+lJkjJsdogK9pzIkCpRarstCX3NwXd+Aa6NjXdw/3e90yarPYoFN/EDLVhtUGh9Hv94FsptfVBdK/VrhLeC/aBSVnrkpwG1HeMWUwd3ArKP1p9WUXpuQ+t3F1qLofgtkP9Gjo8MPSRu1+XQ8KA4t4kgrap3meomiC6z2rDnkossdfcNNDhQq5KqMVg9YWasIIEKpFrO5EhyOCb3/WvPBg0fZVWJqIBBas9isFqj9qw2qBQclx/P32EptNQn7qr4/lyGlBfjm2oO7+Oz73OvruLVWCHILbQib3bFvVj6LAFvnz/2AM32hh6A8p+BrUVrfYpasLnIglxU7ikXDOuMfLQCDF3UxiIfIwtqF1vX1cTvhqoiOpMEx32gzihwfr8yFc7UwZ0LFYbFEqO6++nD1ZOBMv49g5dMfhSozcnOQ2ozy2dYvwpKWn15e4hkpPrFs9A1DHmNwiR2xaxpeK+LiRQ0zpkgpgRjDzpSyHBaTEMtQHFYDTVzGRfjv0MqmIsG/nhycEkJ4pBNOXGtV6P6DeWfr87KwKT/ckY3PaVmuAGdA/GrTQeeXQp4Gr+wnH27+87P5DBiXsmVuyd+uj3HgCrPYrBao/asNqgUHJcf44+8KpYhRUsMRjnTM7nHrHeJwWrihMKSQlyYQVp9eUWZfAdbN+F2tKMSNtyT+Pi9+oyyn6oDeiNt9gBBCzf+bKbZospN64vPYKk9lhyfHfuKRKUcYuh3rauNqwi+Ijk92E5SowcUOsaWNnnnqX6yHEPWO1RDFZ71IbVBoWS4/pz9AHctxQetyLcXfGaiVhM3vddEB0bA/e/NdZRucp9Nppy2nOrzYBa6UldHyoxtAYUv75Vko9/CykgnHLj+vZAFyac1J6SZ+Vym5MLiislhnrbutrw5Q4ia49kIoLXwPr8yHc+ZW5yPD9WexSD1R61YbVBoeS4/hx91MGtSw5p27YQdbVzkNOAzvMUlsCdGoOv3jVBlC4TyYBanyX2kJBYhtaA+qLvQupgQsqNS1Frq01IeSsXX6msmO+O0oH1tqy8Y6i3rauNpn1QXKApKTWDpqkUXcyRTf2Q4/mx2qMYrPaoDasNCiXH9efowwdF5X11lknzybEKzWlAmfhZfRGdG/NM+iLtrUnDRDKgBA+5bVK212IYWgPqSymhYHsIKTcuxtlqQ55pLJxsb/UV8925oea4H2Oot60rBF9JQzQMZ3Gyf259dkRgxCDI8fxY7VEMVnvUhtUGhZLj+nP00QQnmbin41RixdcvOQ0o+PYuQ8dF8JWItA4R5zliwtmPrPe6avLSMa9rC+CytmU4ZLtLhtaA+maGoUnDHHNltW+CI42sNhiuHS2nV9Rhs9uXsxXz3bkFudmDjKHetq4Qmk5lIZ0o9HSc8cJXzo37alDkeH6s9igGqz1qw2qDQslx/Tn6aMMXa/Hgo3FBexa5Dah1RB4KPeWJnGkrHZAMhK6OBHTfC6WksWDg3X5iy5vGMrQG1Bd6HpJ71FTIuglmQL5UlpiDsCm8YPWBYr47ymTV23IOZAz1tnWFgEvonAv8+0TUxu3afdIPN3m8CT+4It9hyW3keH6s9igGqz1qw2qDQslx/Tn6aMMXadpU1i6U3AaUlabVH9W4QgqdEEhltaeyT1dY75diQDn70+0nJQI5hqE1oL5UCvIk28DYWW1RG74EY4KXQmY71Fz1BSOhmO/OTZym3xjqbesKhSotTfVmWRGnnIYfSkoBC1i6bKc30XqQ7uccz4/VHsVgtUdtWG1QKDmuP0cfbbDStN4j5GzMNnIbUPAdrM1h6k2wQPCNTV2u5Kz3SzGgnGHr9kPAY5cMrQE95Rw7/5PI1CY4ysw3eKK2FAaiunwHclMqbv4Cv8Eg+KatzGDMd+fWeOUA4hjqbeuKgTq8Vh91XT5pSbFmbdxeBJGATW2qgAlW4ZzRGlIwm1UzM1JfST9qJePCGhQ5nh+rPYrBao/asNqgUHJcf2ofbDGEBNY0eVpynPLRhQH1ndLDuOWb0LKtRLSu1Q6DHBOEFIv1nikGlLHbHdtvvyu+TnkMQ2tAfYWo+QI5WNWFL5cZoy8goFKIC5hoNKttJdyAuGnJDyXdZtGL28ui123vjWK+O3evwgozb6Letq4YeLBuuNkusu+KyQN7MUQ34m5hQkFwAMaS2qS4yqbcvqo47rSDK2uK9/twD4NmT5tTTFgtMEmiT4pK8/1TwQR324meA5grWXU+uyTH82O1RzFY7VEbVhsUSo7rT+mDe/aIo2eVk3Aq1/gS7ZlM+Vz9bJe0TbZD6MKAcn1nn28HWeIxoi50tZ/Ja5kINJW47KqMYYX1nqml/Phd6v1MujbujORYhtaAMjA2rSQvuHhxeZgqxdaZhRx1YlilkZB9Akrq+Q4iDtWZ59k3eOh3x43vroRDj8GqqLetKxYGEo5Ts/rqRxhcH9feNLZQdD+6cvLS8jsdJDmeH6s9isFqj9qw2qBQclx/Sh94NuqvZRxh8kmwEEUHSJeggpkvUBER8ZmDLgwoMIGk8IHVN+KaqcblC6asxIS2a6z3TTWgZ5w72n2Nh6pLhtaAgltIIFTcNL5jkELPhSTqtlopxYo9WF8xAmaHITA7dttyTTG47SulwlmKMYdZt4lAMUovumDo3JlmP7ps0pLgwtc5yfH8WO1RDFZ71IbVBoWS4/pT+rDOrYwRxeVzrD6hKwMKeOJ8200hYhGScpZoLNZ7pxpQt871MSfP6f2lG4bagPLj+g7U9Yl9LlwWCxbZaRjM3ELh+LRLr15i9mOJWR8PLwbAZ0BDN70x4G7bmHMUwW1fqR/4/nyl/lL00tKxwQt8702rg1DhzuIeyzUYxpLj+bHaoxis9qgNqw0KJcf1p/TRj/eInO+cx/Z1aUCB7ZKQrSNXjGsp54imYL1/qgF1gzyJd+iSoTaggBFlJdrkzq1E8QIq8gMDvfUa9itjISey6YBe8kQJpKkn9foM6LQnNvde0QzX4bYNzfWqcNtXygH7JrhFU1ekzJyZ6fvOY8SIPjByf/gGoCbh2sIFnHLMU05yPD9WexSD1R61YbVBoeS4/pQ+MCqxRpToVFI8crv5uzagQOBj6IlVLDC6uM4mrM+RakAZc+r9YBe6pC8DyiDJjeoqdtM5Rz8EpLB3wV4G0anMuqgNy+Y4Je/clSWzK+s9+znTklUhEaFEpjK449JcsHi7GaTgK0VoBUBZWJV0Lrkyrualdf0oJ7hg+U7Yh8ZbwKkXBD9VriUmF/xOJ501v5z13n3v2vL1GMgQeNBJXXp42qZy9klgCOkz1YQKA467lwGE/ZyZc7Z2lhAeS4773mqPYrDaozasNiiUHNffTx9Mzij/xn1Hgfhqz5CtA+4h9tPYFiGyvitXJqf1WJ+/C/hOeAZ41qprZZzk2tnzJUJ9UKvOOtb1N2UzNHGCEyhIwZou6cuAinSIDqv/0JVWRYTGuzlbPBScjyqEEB80WGnXx0NEClKXyICOE5brhplvzP7K5OvHFnXgINyJssISQohBgPfPOhvad0B+LmRAxwH2Qt0fGpGnGAOHhFv9HHbkc+UKF9c17lAhhDjUeOzJzWV1JaLorZQdtodyHn5uIQM6DpCv6f7YiOIQsfhOoa/EyQpCCHGo0ZZGeO/UblefIAM6YNiot35sROWiWAhuuOZGf1EBGVAhxKGIz4CyFcbKdBCRxDKgiVAyjvM4if4NgVzDh6Zt9KbbpJwpWocC6Rxv5tbHlQEVQhyKuAaUoMrrp6zoK5MiFhnQROp5n6TO3Dd1fbFw8fbS506VIIozE8zDgbwYzqYi8iT0p6w+LZh1UU2J/las2lVs2jKxz+UUQogUKMlIURxSFHe/OT7ZBzKgCZDXGVK4IVS56moKIYQYHDKgCVDJxDKEKaLgghBCiOFDBjQBcossYxgj/PXzXlCKiRBCDCsyoIlwQjvlrz50uH04s0/Hnjq3DEAa5MHNQggh8iMD2icH3n2/WLlqd1kE/tY7VxdXTV5a1nw9/6JF5X8paECR96dnvDruxcuFEELkQwZUCCGESEAGVAghhEhABlQIIYRIQAZUCCGESEAGVAghhEhABlQIIYRIQAZUCCGESEAGVAghhEhABlQIIYRIQAZUCCGESEAGVAghhEhABlQIIYRIQAZUCCGESEAGVAghhIimKP4XBcAIzFfvoBoAAAAASUVORK5CYII='
img_data = base64.b64decode(img_str)
with open('1.png', 'wb') as f:
f.write(img_data)
print 'successful'
最终得到flag:
flag{ICS-mms104}
1.下载附件得到一个文件,打开是一些ZERO ONE组成的文件https://adworld.xctf.org.cn/media/task/attachments/cca1ce4b15ba4ac7950f6d03f8fa6ad12.将ZERO替换为0,ONE替换为10100110001101001001100000110011101001100011010010011000001110101010011000110100101000001011101010100100101000011001100000111010101001100011010010011000001100111010011000101001100110100011101000100110001101001010000010111010001001001010000110011010001110101010011000101001100110100011001110100110001010011010000010111010101001100011010010011010001110101010010010100001100110100011101000100110001010011001100000111010001001001010000110011010001110101010011000110100100110100011101010100100101000011001100000111010001001100010100110100000101110101010011000101001100110000011101000100110001010011010000010111010101001100011010010011010001100111010011000101001100110000011101000100100101000011001101000111010101001100011010010011010001110101010010010100001100110100011101010100110001010011010000010111010101001100010100110011000001110101010010010100001100110100011101010100110001101001001100000111010001001001010000110011010001110100010011000110100101000001011101000100110001010011001100000110011101001100011010010011010001110101010011000110100100110100011001110100110001101001010000010111010001001100011010010011000001110101010010010100001100110100011101000100110001101001010000010111010101001100011010010011010001110100010011000101001101000001011101000100100101000011001100000111010001001100010100110100000101110100010010010100001100110000011101010100110001101001001100000110011101001100010100010011110100111101
3.将二进制转换成asci编码http://www.txttool.com/wenben_binarystr.asp
得到字符:Li0gLi0uLiAuIC0uLi0gLS4tLiAtIC4uLS4gLSAuLi4uIC4tLS0tIC4uLi4uIC0tLSAuLS0tLSAuLi4gLS0tIC4uLi4uIC4uLSAuLS0uIC4uLi0tIC4tLiAtLS0gLi4uLi4gLiAtLi0uIC4tLiAuLi4tLSAtIC0tLSAtIC0uLi0gLQ==是base64编码,解码得:
https://base64.us/得到解密后的摩尔斯:.- .-.. . -..- -.-. - ..-. - .... .---- ..... --- .---- ... --- ..... ..- .--. ...-- .-. --- ..... . -.-. .-. ...-- - --- - -..- -进行Morse Code解码得:得到:ALEXCTFTH15O1SO5UP3RO5ECR3TOTXT也可以通过脚本得到:import base64
#import morse_talk as mtalk
with open('flag', 'r') as f:
data = f.read()
data = data.replace("ZERO","0").replace("ONE","1").replace(' ','').replace('\n','')
word=''
for i in range(0, len(data), 8):
word+=(chr(int(data[i:i+8], 2)))
word=base64.b64decode(word).decode(encoding='UTF-8')
s = word.split(" ")
print(s)
dict = {'.-': 'A',
'-...': 'B',
'-.-.': 'C',
'-..':'D',
'.':'E',
'..-.':'F',
'--.': 'G',
'....': 'H',
'..': 'I',
'.---':'J',
'-.-': 'K',
'.-..': 'L',
'--': 'M',
'-.': 'N',
'---': 'O',
'.--.': 'P',
'--.-': 'Q',
'.-.': 'R',
'...': 'S',
'-': 'T',
'..-': 'U',
'...-': 'V',
'.--': 'W',
'-..-': 'X',
'-.--': 'Y',
'--..': 'Z',
'.----': '1',
'..---': '2',
'...--': '3',
'....-': '4',
'.....': '5',
'-....': '6',
'--...': '7',
'---..': '8',
'----.': '9',
'-----': '0',
'..--..': '?',
'-..-.': '/',
'-.--.-': '()',
'-....-': '-',
'.-.-.-': '.'
}
for item in s:
print (dict[item],end='')
加上花括号,将o替换为_ 即可得:通过测试,全是大写,才正确
ALEXCTF{TH15_1S_5UP3R_5ECR3T_TXT}