ctf之crypto练习二 - 渗透测试中心
2021-01-16 20:09:00 Author: www.cnblogs.com(查看原文) 阅读量:482 收藏

一、js代码分析之编码转换

writeup:

  1. 打开index.html

<script src="script-min.js"></script>   //首先调用.js脚本

        <script type="text/javascript">

            var ic = false;   #默认ic值为false

            var fg = "";

            function getFlag() {                                     //function函数内的getfFlag按钮会触发相应事件

                var token = document.getElementById("secToken").value;  // #获取文本输入框中的值赋值给token

                ic = checkToken(token);       //调用checkToken(token)这个函数进行检查赋值,该函数包在.js脚本中包含

                fg = bm(token);               //调用checkToken(token)这个函数进行赋值

                showFlag()            //定义showFlag()  函数

            }

            function showFlag() {                   //showFlag()函数的输出功能

                var t = document.getElementById("flagTitle");

                var f = document.getElementById("flag");

                t.innerText = !!ic ? "You got the flag below!!" : "Wrong!";

                t.className = !!ic ? "rightflag" : "wrongflag";

                f.innerText = fg;

            }

        </script>

    </head>

    <body>

        <h1>Flag in your Hand</h1>

        <p>Type in some token to get the flag.</p>

        <p>Tips: Flag is in your hand.</p>

        <div>

            <p>

                <span>Token:</span>

                <span><input type="text" id="secToken"/></span>

            </p>

            <p>

                <input type="button" value="Get flag!" onclick="getFlag()" />

            </p>

2.很明显的看到了点击按钮触发getFlag函数,ic默认是false,调用checkToken(token)这个函数,那么说明checkToken函数就是关键点了。

3.打开checkToken函数看看里面的内容,难道说flag就是FAKE-TOKEN

4.然而输入之后还是提示错误,那就只剩fg = bm(token);这句代码有问题了

5.直接搜索ic,说明ic肯定是在这面变成false的

6.直接点击左侧图标下断点吧,然后点击按钮,成功的断了下来,发现函数参数s就是我输入的变量,然后比较s和a的长度,接着用s的值减3和a的值相比较,如果都没问题,那么就返回true

7.因此只要反推出返回true的s即可。求解代码如下:

a = [118, 104, 102, 120, 117, 108, 119, 124, 48, 123, 101, 120] s = "" for i in a: s += chr(i - 3) print(s)

8.在token框中输入security-xbu

9.最终得到flag:

RenIbyd8Fgg5hawvQm7TDQ

二、base64编码之键盘密码

writetup:

 1.打开文件后得到两串十六进制字符串

636A56355279427363446C4A49454A7154534230526D6843 56445A31614342354E326C4B4946467A5769426961453067

2.将十六进制字符串转换成ascii

http://www.ab126.com/goju/1711.html

得到:

cjV5RyBscDlJIEJqTSB0RmhC

VDZ1aCB5N2lKIFFzWiBiaE0g

3.将其base64:

得到:

r5yG lp9I BjM tFhB    T6uh y7iJ QsZ bhM 

4.看到每4个字母中间有一个空格,再看看键盘,发现是键盘密码,即几个字母在键盘上围出了一个字母,例如r5yG围出的是t,lp9I围出了o。找到每组字⺟包围的字⺟组成flag即可.(不⽤加前缀)

5.得到:

r5yG-T,lp9I-O, BJM-N,tFhB-G, T6uh-Y,y7iJ-U,QsZ-A,bhM-N

6.最终得到flag:

TONGYUAN

三、工业流量包分析

writeup:

1.打开流量包,发现存在关于ARP、UDP、SNA协议的流量包,其中存在大量的UDP流量,如图所示:

2.首先对UDP流量包进行分析,分析发现UDP流量包的长度存在大量相同,一共出现的长度分别为16 17 12 14 10 18 19 20 22 25 32 89 95 104 105 116 131 137 524 528,在这些长度中仅12,89,104,105,131,137出现一次,其余长度多次出现,于是猜测这仅出现一次的流量包存在异常。

3.这里对12长度进行UDP流追踪,发现了可疑的字符

4.提取出字符串666c61677b37466f4d3253746b6865507a7d,并转换成对应ACII码

   5.最终得到Flag:

  flag{7FoM2StkhePz}

四、文本中有规律的大写字母

1.下载附件后,发现是一个很大的文本,仔细观察文本,发现文本中有很多故意加粗的大写字母。

2.将大写过滤出来出来

cat f590c0f99c014b01a5ab8b611b46c57c.txt | grep -o '[A-Z]' | tr -d '\n'

其中:

  • grep -o 只显示匹配到的字符串
  • tr -d 删除指定字符

3.得到过滤的字符:

ZEROONEZEROZEROZEROZEROONEZEROZEROONEZEROZEROONEZEROZEROONEZEROONEZEROONEZEROONEZEROZEROZEROONEZEROONEZEROZEROONEONEZEROONEZEROZEROZEROZEROONEONEZEROONEZEROONEZEROONEZEROZEROZEROONEZEROZEROZEROONEONEZEROZEROONEONEONEONEZEROONEONEZEROONEONEZEROONEZEROZEROZEROZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROZEROONEZEROZEROZEROZEROONEONEZEROZEROONEONEZEROONEZEROONEONEONEONEONEZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROONEONEONEZEROZEROONEZEROONEONEONEONEONEZEROONEONEONEZEROZEROZEROZEROZEROONEONEZEROONEONEZEROZEROZEROZEROONEONEZEROONEZEROZEROZEROZEROONEONEZEROZEROZEROONEZEROONEONEZEROONEONEONEZEROZEROONEZEROONEONEONEONEONEZEROZEROONEONEZEROONEZEROONEZEROZEROONEONEZEROZEROZEROONEZEROZEROONEONEZEROONEONEONEZEROZEROONEONEZEROZEROONEONEZEROONEONEONEONEONEZEROONE

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解密

题目描述:

Fady同学以为你是菜鸟,不怕你看到他发的东西。他以明文形式将下面这些东西发给了他的朋友 :p=0xa6055ec186de51800ddd6fcbf0192384ff42d707a55f57af4fcfb0d1dc7bd97055e8275cd4b78ec63c5d592f567c66393a061324aa2e6a8d8fc2a910cbee1ed9 q=0xfa0f9463ea0a93b929c099320d31c277e0b0dbc65b189ed76124f5a1218f5d91fd0102a4c8de11f28be5e4d0ae91ab319f4537e97ed74bc663e972a4a9119307 e=0x6d1fdab4ce3217b3fc32c9ed480a31d067fd57d93a9ab52b472dc393ab7852fbcb11abbebfd6aaae8032db1316dc22d3f7c3d631e24df13ef23d3b381a1c3e04abcc745d402ee3a031ac2718fae63b240837b4f657f29ca4702da9af22a3a019d68904a969ddb01bcf941df70af042f4fae5cbeb9c2151b324f387e525094c41 c=0x7fe1a4f743675d1987d25d38111fae0f78bbea6852cba5beda47db76d119a3efe24cb04b9449f53becd43b0b46e269826a983f832abb53b7a7e24a43ad15378344ed5c20f51e268186d24c76050c1e73647523bd5f91d9b6ad3e86bbf9126588b1dee21e6997372e36c3e74284734748891829665086e0dc523ed23c386bb520 他严重低估了我们的解密能力

writeup:

1.将题目中的十六进制类型转换成十进制:

https://tool.lu/hexconvert/

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))

3,最终得到flag:

ALEXCTF{RS4_I5_E55ENT1AL_T0_D0_BY_H4ND},

六、诗歌decrypted message

writeup:

Is yours and yours and yours.
Yet death will be but a pause.
For the peace of my years
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)将加密的信息第一个字母对应第一步的编码数字,到第二步生成的字母表中取某列。
解密过程非常复杂,不过,有人已经写好了解密工具,详见:https://github.com/abpolym/crypto-tools/tree/master/poemcode
Is yours and yours and yours.
Yet death will be but a pause.
For the peace of my years
Will be yours and yours and yours.
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
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}


题目描述:

我们刚刚拦截了,敌军的文件传输获取一份机密文件,请君速速破解

wirteup:

504B03040A0001080000626D0A49F4B5091F1E0000001200000008000000666C61672E7478746C9F170D35D0A45826A03E161FB96870EDDFC7C89A11862F9199B4CD78E7504B01023F000A0001080000626D0A49F4B5091F1E00000012000000080024000000000000002000000000000000666C61672E7478740A0020000000000001001800AF150210CAF2D1015CAEAA05CAF2D1015CAEAA05CAF2D101504B050600000000010001005A000000440000000000

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()

4.解压test.zip,发现需要解压密码,通过ziperello对zip进行破解


5.通过输入破解的密码123456,解压出压缩文件,打开flag.txt,接口获得flag

1.下载得到一个文件 末尾添加.zip.解压得到两个文件一个key 一个加密的py文件

2. py分析

根据R=int(flag[5:-1],2)以及len(flag)==25推测flag为19个二进制位,暴力解出flag即可

lfsr这个算法经搜索可能是一个伪随机测试码产生器.

参考:https://www.anquanke.com/post/id/181811

3.python脚本获取flag

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

4.最终flag为:

flag{1110101100001101011}

十、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.下载附件,解压文件,得到一个文件名为cry200

https://adworld.xctf.org.cn/media/task/attachments/82f462a5eb8543899f11b46cbfb4d827.zip

2.通过命令file查看文件类型,得知是zip文件类型

3.将cry200重命名为 cry200.zip,并解压得两个文件:key.pem 和 cipher.bin

4.使用 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.下载附件,解压文件,得到一个文件名为cry300

https://adworld.xctf.org.cn/media/task/attachments/c9b973a1f7114c0486b0410536370380.zip

2.通过命令file查看文件类型,得知是zip文件类型

3.将cry300重命名为 cry300.zip,并解压得两个文件:ecb.bmp和 task.txt

4.根据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头:

HexValueDescription
42 4D"BM"Magic number (unsigned integer 66, 77)
76 90 7e 008294518 bytes (118+8294400)Size of the BMP file (8294400 = 3840x2160)
00 00UnusedApplication specific
00 00UnusedApplication specific
76 00 00 00118 bytes (78+40)Offset where the pixel array (bitmap data) can be found
28 00 00 0040 bytesNumber of bytes in the DIB header (from this point)
00 0f 00 003840Width of the bitmap in pixels
70 08 00 002160Height of the bitmap in pixels
01 001 planeNumber of color planes being used
04 004 bitsNumber of bits per pixel
00 00 00 000BI_RGB, no pixel array compression used
00 90 7e 008294400 bytesSize of the raw bitmap data (including padding)
00 00 00 000 pixels/meter horizontalPrint resolution of the image,
00 00 00 000 pixels/meter vertical(don't care about printing)
00 00 00 000 colorsNumber of colors in the palette
00 00 00 000 important colors0 means all colors are important

9.将下面的十六进制删除

53 61 6c 74 65 64 5f 5f  ab 31 b5 e5 ca 3d b9 4d

f4 09 1a a5 df 88 b7 2c  0e bd 8a 73 98 15 ba 69

a2 24 3e 09 94 cb 79 1e  ea a1 ad 33 c8 17 66 63

78 98 23 0b f0 af 20 38  f1 aa 0b f4 69 1c ec cf

fc d8 8e 3d 45 2a 99 b0  53 6b 50 0d 8a 3d c4 b7

62 9c 6a 54 f0 59 20 13  22 4f b6 e2 b6 aa 0a 8b

5e 21 1a 9d cf 8c a2 f6  45 80 cb 9b b7 37 da 7f

73 50 88 cb df 63 ee 22  d4 24 b3 b9 f4 24 ad 40

然后再添加以下BMP字符:

424d 7648 3f00 0000 0000 7600 0000 2800

0000 000f 0000 7008 0000 0100 0400 0000

0000 0048 3f00 0000 0000 0000 0000 0000

0000 0000 0000 0000 0000 0000 8000 0080

0000 0080 8000 8000 0000 8000 8000 8080

0000 8080 8000 c0c0 c000 0000 ff00 00ff

0000 00ff ff00 ff00 0000 ff00 ff00 ffff

0000 ffff ff00 ffff ffff ffff ffff ffff

10.将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)

g

11.最终得到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 对任意字节数据进行编码

3.将BITSCTF 进行Base32加密 (https://www.qqxiuzi.cn/bianma/base.php)

MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI IJEVIU2DKRDA

M解密两次对应的都是I,不同的字母对应的都是不同的解密字母,那么猜测可能是根据某种规则进行了字母替换。

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解密得:

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()

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())

ALEXCTF{SMALL_PRIMES_ARE_BAD}

1.下载附件pdf,通过阅读器查看,发现文件无法查看

https://adworld.xctf.org.cn/media/task/attachments/9e45191069704531accd66f1ee1d5b2b.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

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为:icqvigenere

https://www.guballa.de/vigenere-solver

3.在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

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编码

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;

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,2ri<e,i=1,2,如果e=3可能情况太少。

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] 12502893634923161599824465146407069882228513776947707295476805997311776855879024002289593598657949783937041929668443115224477369136089557911464046118127387

5.通过脚本解密:

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 > dec100

6.简单翻译如下 破碎的人更值得我们同情,尽管他们可能同样危险。几乎所有的人都是普通的,简单的人, 他们从来没有离开过他们出生的房子超过一英里,直到有一天上帝来带他们去打仗。你的 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.log

2.利用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}

基础知识:

构造有限域GF(2^n)时,首先需要GF(2)上次数为n的本原多项式g(x);对于GF(2^n)上的每个元素a,都可以用一个次数不超过n的多项式fafa表示:fa(x)=n1i=0aixifa(x)=i=0n1aixi,其中an1a0an1a0是a的二进制表示;从而GF(2^n)上的四则运算定义如下:

  • 加法:对于a,bGF(2n)a,bGF(2n),它们的多项式表示分别为fa,fbfa,fb,记fc=fa+fbfc=fa+fb(其中系数的加法为GF(2)上的加法,即异或运算),则cn1c0cn1c0的二进制值c为a+b的值;
  • 减法:由于GF(2)上的加法与减法等价,因此对于a,bGF(2n)a,bGF(2n),a+b=a-b;
  • 乘法:同样地,a,b的多项式表示fa,fbfa,fb,记fc=fafb mod gfc=fafb mod g,由于多项式gg的次数为n,故多项式fcfc的次数不超过n,则cn1c0cn1c0的二进制值c为abab的值;
  • 除法:先介绍(乘法)逆元,本原多项式是一种具有特殊性质的不可约多项式,对GF(2)上任意次数不超过n的多项式f,都存在GF(2)上次数不超过n的多项式h,使得fh1 mod gfh1 mod g;与f作除法等价于与f的逆元h作乘法;

2. process(m,k)

考虑t2,tGF(2256)t2,tGF(2256),构造GF(2256)GF(2256)的本原多项式为g=x256+x10+x5+x2+1g=x256+x10+x5+x2+1,记t的二进制表示为tn1t0tn1t0,则t的多项式表示ft(x)=n1i=0tixi=(((tn1x+tn2)x++t1)x+t0)ft(x)=i=0n1tixi=(((tn1x+tn2)x++t1)x+t0),考虑t2t2

f2t mod gft2 mod g

=(((tn1x+tn2)x++t1)x+t0)ft mod g

=((((tn1ft)x+tn2ft)x++t1ft)x+t0ft) mod g

=((((((tn1ft)x+tn2ft) mod g)x++t1ft) mod g)x+t0ft) 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,代表+tift

if (res>>256):res^=P代表模本原多项式g;

综上,process(m,k)实际上实现了GF(2^256)上的元素m与k之和的平方(m+k)2

3.解密过程

k2=(k1+secret)2,k3=(k2+secret)2(在GF(2^256)上的运算)

c1=m1k1,c2=m2k2,c3=m3k3,其中ci(i=1,2,3),mi(i=1,2)已知

k2=m2c2,k3=m3c3,可解出secret:secret=k31/2+k2(在GF(2^256)上的运算)

接下来解出k1k1=k21/2+secret(在GF(2^256)上的运算)

然后解出flag(即m1):

writeup:

1.下载附件,对压缩包进行解压,含有两个文件:oneTimePad.py和 ciphertext

其中oneTimePad.py是加密脚本,ciphertext为密文,密文内容为:

af3fcc28377e7e983355096fd4f635856df82bbab61d2c50892d9ee5d913a07f
630eb4dce274d29a16f86940f2f35253477665949170ed9e8c9e828794b5543c
e913db07cbe4f433c7cdeaac549757d23651ebdccf69d7fbdfd5dc2829334d1b

2.对python 代码进行分析,了解运算流程:

#!/usr/bin/env python

# coding=utf-8

from os import urandom

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

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) == 32

print 'flag{%s}' % true_secret

fake_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 的输出求输入:

  1. process(key2, seed) 已知,通过输出求输入,得到 a1 = key2 ^ seed
  2. key2 已知,∴ seed = a1 ^ key2
  3. process(key, seed) 已知,通过输出求输入,得到 a2 = key ^ seed
  4. seed 已知,∴ key = a2 ^ seed
  5. ctxt1、key 已知,且 ctxt1 = true_secret ^ key,∴ true_secret = ctxt1 ^ key
  6. 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命令用法,我们使用指令进行关键字搜索

最终,发现存在base64加密的png图片码,如图所示:
运行脚本,将图片码进行base64解码,解码后得到写有Flag的图片:
# coding=utf-8
import os, base64
img_str = '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'
img_data = base64.b64decode(img_str)
with open('1.png', 'wb') as f:
   f.write(img_data)
print 'successful'

1.下载附件得到一个文件,打开是一些ZERO ONE组成的文件

https://adworld.xctf.org.cn/media/task/attachments/cca1ce4b15ba4ac7950f6d03f8fa6ad1

2.将ZERO替换为0,ONE替换为1

0100110001101001001100000110011101001100011010010011000001110101010011000110100101000001011101010100100101000011001100000111010101001100011010010011000001100111010011000101001100110100011101000100110001101001010000010111010001001001010000110011010001110101010011000101001100110100011001110100110001010011010000010111010101001100011010010011010001110101010010010100001100110100011101000100110001010011001100000111010001001001010000110011010001110101010011000110100100110100011101010100100101000011001100000111010001001100010100110100000101110101010011000101001100110000011101000100110001010011010000010111010101001100011010010011010001100111010011000101001100110000011101000100100101000011001101000111010101001100011010010011010001110101010010010100001100110100011101010100110001010011010000010111010101001100010100110011000001110101010010010100001100110100011101010100110001101001001100000111010001001001010000110011010001110100010011000110100101000001011101000100110001010011001100000110011101001100011010010011010001110101010011000110100100110100011001110100110001101001010000010111010001001100011010010011000001110101010010010100001100110100011101000100110001101001010000010111010101001100011010010011010001110100010011000101001101000001011101000100100101000011001100000111010001001100010100110100000101110100010010010100001100110000011101010100110001101001001100000110011101001100010100010011110100111101

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}

文章来源: http://www.cnblogs.com/backlion/p/14286965.html
如有侵权请联系:admin#unsafe.sh