【bmzctf-crypto】--writeup

4进制


4进制转16进制,再转字符串。

2018 AFCTF Morse

摩斯电码解密得16进制。

16进制转字符串得flag。

2018 HEBTUCTF社会主义接班人

自由爱国自由平等自由文明平等自由平等平等自由和谐平等自由自由公正法治诚信民主公正平等公正友善自由法治公正公正友善敬业法治公正公正自由公正民主法治和谐公正公正公正诚信富强公正公正法治公正公正友善法治法治文明公正公正公正友善法治法治和谐公正自由公正平等公正诚信和谐法治爱国公正友善自由法治诚信和谐

这是社会主义编码,解码工具:https://atool.vip/corevalue/

Ook!

这是Ook编码。解密工具:Brainfuck/Ook! Obfuscation/Encoding [splitbrain.org]

栅栏密码

栅栏中的base

4C4A5645455232524B3533544B544C4C4A5A5545324D434749564E48553344474A564548495A53524E595944323D3D3D

给了16进制,先16进制转字符串,得base32。

base32解码得base64。

base64解码得栅栏密码。

栅栏密码解密,组数为5,得flag。

easy_base

题目说影分身之术*40,也就是说,base加密了40次。

解密:BASE64加密解密 点上40次也不是很久。

2018 HEBTUCTF Sudoku&Viginere

做数独,做出来才能得到维吉尼亚的密码。

数独就是每个单元格所在行所在列,该字符都是唯一的。

做出来了但是不知道密码在哪里,看到维吉尼亚的数字,应该是每个分组指向一个字符,合起来就是密码。如45指向1,4行5列。以此类推....得到15_1t_3a5y

这就是flag,但是要加上HEBTUCTF{},题目没说明。

CRC32 BOOM

给了一个三个文件。

因为1.txt和2.txt比较小,可以爆破。flag.jpg估计是用爆破出来的crc32再去爆破它。

爆破脚本:GitHub - theonlypwner/crc32: CRC32 tools: reverse, undo/rewind, and calculate hashes

这里爆破出来的是文件内容,并不是压缩包的密码。

把两个文件爆破的结果进行组合,制作成爆破flag.jpg的字典。

dic = []
#已t1开头,t2结尾的字典
fork inrange((len(t1)+len(t2))):
fori int1:
forj int2:
dic.append(i+j)
#已t1开头,t2结尾的字典
fork inrange((len(t1)+len(t2))):
fori int2:
forj int1:
dic.append(i+j)
print(dic)

withopen('dic.txt','w') asf:
fori indic:
f.write(i+'\n')

然后使用archpr等工具进行字典爆破,或者ziperello。

把解密出来的flag.jpg扔进16进制工具看到flag,这个图片估计是损坏的。

看键盘

ujn njkm ijnmhjk fgtrdcv tgvgy njkm hjuygbn ijnmhjk

实际上,就是在键盘上,安装这个字母比划,每组就是划一个单词,第一个ujn是比划i,njkm是比划n,第三个是比划t,一次类推,最后是Internet。

可怜的RSA

给了两个文件,flag.enc是加密后的密文,public.key是公钥文件。

相当于我们知道了c,n,e。n和e可以从公钥文件中分离出来。

分离方法:yafu工具。

即分离出来q,p,n=q*p。

接下来需要求私钥d。知道e,n就可以求d。

d = gmpy2.invert(e,(q-1)*(p-1))

到这里就知道了n , e , d , q , p , c(密文c只是base64加密了而已)

本来这里pow(c, d, n)就可以出来了,但是c 和n 长度一样,明文空间m和密文空间c都必须满足0<c<n-1,所以这里需要对密文c进行分组来求,有点麻烦,而PKCS1_OAEP这个库可以padding,就直接用。

脚本:

importbase64
fromCrypto.Cipher importPKCS1_OAEP
fromCrypto.PublicKey importRSA
importgmpy2

# 分离公钥文件,求n ,e。也可以使用openssl:openssl rsa -pubin -text -modulus -in pubkey.pem
f = open('C:\\Users\\n0r1and3r\\Desktop\\RSA\\public.key','rb').read()
pub = RSA.importKey(f)
n = pub.n
e = pub.e

# 大素数分解,yafu工具
p = 3133337
q = 25478326064937419292200172136399497719081842914528228316455906211693118321971399936004729134841162974144246271486439695786036588117424611881955950996219646807378822278285638261582099108339438949573034101215141156156408742843820048066830863814362379885720395082318462850002901605689761876319151147352730090957556940842144299887394678743607766937828094478336401159449035878306853716216548374273462386508307367713112073004011383418967894930554067582453248981022011922883374442736848045920676341361871231787163441467533076890081721882179369168787287724769642665399992556052144845878600126283968890273067575342061776244939

# 得到私钥d
d = gmpy2.invert(e,(q-1)*(p-1))

key_info = RSA.construct((n,e,int(d),p,q))
key = RSA.importKey(key_info.exportKey())
key = PKCS1_OAEP.new(key)

# 读密文
f1 = open('C:\\Users\\n0r1and3r\\Desktop\\RSA\\flag.enc','rb').read()
C = base64.b64decode(f1)
flag = key.decrypt(C)
print(flag)

small_RSA

给了一个加密脚本:

# -*- coding: utf-8 -*-

from Crypto.PublicKey import RSA

import libnum

import uuid

flag = "flag{***************}"

rsa = RSA.generate(4096,e=3)

p = rsa.p

d = rsa.d

e = rsa.e

N = rsa.n

m = libnum.s2n(flag)

c = pow(m, e, N)

print "[+]c:",c

print "[+]N:",N

'''

[+]c: 3442467842482561323703237574537907554035337622762971103210557480050349359873041624336261782731509068910003360547049942482415036862904844600484976674423604861710166033558576921438068555951948966099658902606725292551952345193132973996288566246138708754810511646811362017769063041425115712305629748341207792305694590742066971202523405301561233341991037374101265623265332070787449332991792097090044761973705909217137119649091313457206589803479797894924402017273543719924849592070328396276760381501612934039653

[+]N: 691316677109436623113422493782665795857921917893759942123087462879884062720557906429183155859597756890896192044003240821906332575292476160072039505771794531255542244123516929671277306361467074545720823735806308003091983427678300287709469582282466572230066580195227278214776280213722215953097747453437289734469454712426107967188109548966907237877840316009828476200388327329144783877033491238709954473809991152727333616022406517443130542713167206421787038596312975153165848625721911080561242646092299016802662913017071685740548699163836007474224715426587609549372289181977830092677128368806113131459831182390520942892670696447128631485606579943885812260640805756035377584155135770155915782120025116486061540105139339655722904721294629149025033066823599823964444620779259106176913478839370100891213072100063101232635183636552360952762838656307300621195248059253614745118852163569388418086291748805100175008658387803878200034840215506516715640621165661642177371863874586069524022258642915100615596032443145034847031564356671559179212705466145609698475546210994748949121359853094247990533075004393534565421776468785821261291309463205314057882016266066365636018084499158806717036972590848458891019171583268920180691221168453612029698510271

'''

有题目,可知三个参数,大素数n,密文c,加密指数e。仅凭这三个参数是不能直接求出明文m的,因为

m = cd (mod n)

不知道私钥d,d = gmpy2.invert(e,∮(n)),但是欧拉函数∮(n) = (q-1)*(p-1),尝试去分解n,但是失败了,4096位加密目前是安全的。

切入点就在于e=3很小,可以低加密指数攻击。

根据加密函c =me mod n,相当于m3+k*n = c,k取整数。所以只需爆破这个k值即可。因为指数是3,比较低,可以在可计算范围爆破,如果一般e取65537等,就是不可计算范围了。

解密脚本:

fromCrypto.Util.number import*
importgmpy2

n = 691316677109436623113422493782665795857921917893759942123087462879884062720557906429183155859597756890896192044003240821906332575292476160072039505771794531255542244123516929671277306361467074545720823735806308003091983427678300287709469582282466572230066580195227278214776280213722215953097747453437289734469454712426107967188109548966907237877840316009828476200388327329144783877033491238709954473809991152727333616022406517443130542713167206421787038596312975153165848625721911080561242646092299016802662913017071685740548699163836007474224715426587609549372289181977830092677128368806113131459831182390520942892670696447128631485606579943885812260640805756035377584155135770155915782120025116486061540105139339655722904721294629149025033066823599823964444620779259106176913478839370100891213072100063101232635183636552360952762838656307300621195248059253614745118852163569388418086291748805100175008658387803878200034840215506516715640621165661642177371863874586069524022258642915100615596032443145034847031564356671559179212705466145609698475546210994748949121359853094247990533075004393534565421776468785821261291309463205314057882016266066365636018084499158806717036972590848458891019171583268920180691221168453612029698510271
e = 3
flag = 0
c = 3442467842482561323703237574537907554035337622762971103210557480050349359873041624336261782731509068910003360547049942482415036862904844600484976674423604861710166033558576921438068555951948966099658902606725292551952345193132973996288566246138708754810511646811362017769063041425115712305629748341207792305694590742066971202523405301561233341991037374101265623265332070787449332991792097090044761973705909217137119649091313457206589803479797894924402017273543719924849592070328396276760381501612934039653
fori inrange(200000000):
ifgmpy2.iroot(c + n * i,3)[1] == 1:
'''
这个函数是开n次方,gmpy2.iroot(x,n),x的n次方根。
返回值[0]是方根,[1]是布尔值。
如a = gmpy2.iroot(4,2),则返回值a[0]=2,a[1]=TRUE。
'''

flag = gmpy2.iroot(c + n * i,3)[0]
print(i,flag)
print(long_to_bytes(flag))
break

这里解得i=0,即k=0的情况。

山东省大学生网络技术大赛-baby

和上面一题small_RSA 是同一题,略过。

easy_rsa

给出了大素数n,密文c,加密指数e。

按照常规历流程,先把n分解,得到两个大质数qp。

工具:factordb.com

有了qp就好办了。脚本:

importgmpy2
d = gmpy2.invert(e,(q-1)*(p-1))
m = pow(c,d,n)
importlibnum
print(libnum.n2s(m))

flag{Eeeasy_RSA!}

rsass

爆破压缩包,密码为password。

里面是四个文件:

先从pubkey1.pem分离n,e试试看。

密钥强度2048bit。

e = 2333,n = 17362520124149736059291605717839814089431261833972408175766504894876091272021197374480215582589878198406028065354454242540322618614670160317701698407729515781811530180885334265851364490357884909336085410775168953942120359215038925025305363480538685487988827339463890539279008285241711326041868183805848503077373967082910932422798165242481154593794712639251157856102009630894845049984346776659339380886766804814959778048440996937820138560802077375885700500737699904011032451007341777160586467318264288370080315519305800247682611802774996999330812534723806925426052547128371180683265963525581842037399869323246530085399

看看pubkey2.pem。

两个模数n是一样的。所以,应该是考察共模攻击。

先把两个密文读取出来。这里有个小挫折。

直接读取报错了,点击这个strings.py文件,把encode('utf-8')删掉。

然后可以正常读取了。

共模攻击脚本:

fromgmpy2 importinvert

defgongmo(n,c1,c2,e1,e2):
defegcd(a,b): #欧几里德
ifb == 0:
returna,0
else:
x,y = egcd(b,a % b)
returny,x - (a // b) * y
s = egcd(e1,e2)
s1 = s[0]
s2 = s[1]

#求模反元素
ifs1 < 0:
s1 = - s1
c1 = invert(c1,n)
elifs2 < 0:
s2 = - s2
c2 = invert(c2,n)
m = pow(c1,s1,n) * pow(c2,s2,n) % n
returnm

n= 17362520124149736059291605717839814089431261833972408175766504894876091272021197374480215582589878198406028065354454242540322618614670160317701698407729515781811530180885334265851364490357884909336085410775168953942120359215038925025305363480538685487988827339463890539279008285241711326041868183805848503077373967082910932422798165242481154593794712639251157856102009630894845049984346776659339380886766804814959778048440996937820138560802077375885700500737699904011032451007341777160586467318264288370080315519305800247682611802774996999330812534723806925426052547128371180683265963525581842037399869323246530085399
e1= 2333
e2= 23333

withopen('C:\\Users\\n0r1and3r\\Desktop\\rsa\\flag1.enc','r') asf1:
c1 = f1.read()
importbase64
importlibnum
c1 = base64.b64decode(c1)
c1 = libnum.s2n(c1)

withopen('C:\\Users\\n0r1and3r\\Desktop\\rsa\\flag2.enc','r') asf1:
c2 = f1.read()
c2 = base64.b64decode(c2)
c2 = libnum.s2n(c2)

flag = gongmo(n,c1,c2,e1,e2)
flag = hex(flag)
print(flag)

16进制转一下字符串得flag,大坑(横杠要去掉,这也太坑了,出题人脑子??)

【2021医疗行业CTF】base编码

R1kzRE1RWldHRTNET04yQ0dZWkRNTUpYR00zREtNWldHTTJES1JSVEdNWlRFTktHR01ZVEdOUlZJWTNES05SUkc0WlRPT0pWSVkzREVOUlJHNFpUTU5KWElRPT09PT09

一次base6解码,一次base32解码,一次16进制转字符串。

看的出来吗

bE0veldtTDs7NzlTe3hzbSFYSj5Sa2U6eyQ4NyVrI3FvWFU6Qls7QlVK

密钥是589164。

其实就是先base58编码,再base91编码,再base64编码。

反过来解码就行。

键盘之争

肯定是改了键盘布局,我们常用的键盘布局时qwer布局,还有dvorak布局,colema布局等。

qwer布局改dvorak布局脚本:

dic={r"'":"q",
r",":"w",
r".":"e",
"p":"4",
"y":"t",
"f":"y",
"g":"u",
"c":"i",
"r":"o",
"l":"p",
r"/":r"[",
r"=":r"]",
r'"':'Q',
r"<":"W",
r">":"E",
"P":"R",
"Y":"T",
"F":"Y",
"G":"U",
"C":"I",
"R":"O",
"L":"P",
r"?":r"{",
r"+":r"}",
"a":"a",
"A":"A",
"o":"s",
"O":"S",
"e":"d",
"E":"D",
"u":"f",
"U":"F",
"i":"g",
"I":"G",
"d":"h",
"D":"H",
"h":"j",
"H":"J",
"t":"k",
"T":"K",
"n":"l",
"N":"L",
"s":";",
"S":":",
r"-":r"'",
r'_':r'"',
r";":"z",
r":":"Z",
"q":"x",
"Q":"X",
"j":"c",
"J":"C",
"k":"v",
"K":"V",
"x":"b",
"X":"B",
"b":"n",
"B":"N",
"m":"m",
"M":"M",
"w":r",",
"W":r"<",
"v":r".",
"V":r">",
"z":r"/",
"Z":r"?",
r'!':"!",
r"@":r"@",
r"#":r"#",
r"$":r"$",
r"%":r"%",
r"^":r"^",
r"&":r"&",
r"*":r"*",
r"(":r"(",
r")":r")",
r"[":r"-",
r"]":r"=",
r"{":r"_",
r"}":r"+"}
s=r'ypau_kjg;"g;"ypau+'

fori ins:
print(" ".join([key forkey,value indic.items() ifvalue == i]),end='')

把this_is_flag改为它的MD5值再提交。

2018 HEBTUCTF Simple Caesar

UROGHPGS{f1zcyr_pnrf4e_f0_fvzc1r}

移位13的凯撒密码,即rot13。

2018 AFCTF MagicNum

2018 HEBTUCTF easy_crypto

第一层是摩斯电码,第二层是baconian培根密码。

明显后面那串是培根密码,把L和J换乘A和B去解密培根,或者反过来。

flag格式:HEBTUCTF{YOUARESOGREAT}

2018 AFCTF Single

两个文件,一个加密源码,一个加密后的密文。

看到密文,首先应该想到词频分析。quipqiup - cryptoquip and cryptogram solver

也不用管它是什么加密了。

2018 AFCTF你能看出这是什么加密么

这一看就是RSA,但是我看出来了,它并没有直接给我flag。。。。

好吧,还是要解的。

给了p,q,e,c。

解密脚本:

p=0x928fb6aa9d813b6c3270131818a7c54edb18e3806942b88670106c1821e0326364194a8c49392849432b37632f0abe3f3c52e909b939c91c50e41a7b8cd00c67d6743b4f

q=0xec301417ccdffa679a8dcc4027dd0d75baf9d441625ed8930472165717f4732884c33f25d4ee6a6c9ae6c44aedad039b0b72cf42cab7f80d32b74061

e=0x10001

c=0x70c9133e1647e95c3cb99bd998a9028b5bf492929725a9e8e6d2e277fa0f37205580b196e5f121a2e83bc80a8204c99f5036a07c8cf6f96c420369b4161d2654a7eccbdaf583204b645e137b3bd15c5ce865298416fd5831cba0d947113ed5be5426b708b89451934d11f9aed9085b48b729449e461ff0863552149b965e22b6


p = int(p)
q = int(q)
e = int(e)
c = int(c)
fn = (q-1)*(p-1)
n = q*p
importgmpy2
d = gmpy2.invert(e,fn)
m = pow(c,d,n)

fromCrypto.Util.number import*
m = long_to_bytes(m)
print(m)

easy_CRC

1:C4E68E3A

2:08FF301C

3:F6FBA587

4:B85C2F9A

5:F1B73D20

6:C6F1D9D7

flag=1+2+3+4+5+6

Each serial number consists of 4 characters

CRC32的爆破,flag就是解密后123456串起来,提示了明文是4个字符,直接爆破。

第一个解密得b323,这个脚本直接出字符串,不能额外16进制转字符串,比较好用。

按照这个方法,直接破解6个CRC,得到b3231e94f045e76e593266f4,即为flag。

实际上原理就像哈希碰撞,用可打印字符一一加密,看密文是否和这个次密文一样,一样就得出明文。

2018 AFCTF One Secret, Two encryption

两个公钥,两个密文。

直接对公钥进行提取e,n。

两个公钥得到如下结果:

e1 = 1666626632960368239001159408047765991270250042206244157447171188195657302933019501932101777999510001235736338843107709871785906749393004257614129802061081155861433722380145001537181142613515290138835765236002811689986472280762408157176437503021753061588746520433720734608953639111558556930490721517579994493088551013050835690019772600744317398218183883402192060480979979456469937863257781362521184578142129444122428832106721725409309113975986436241662107879085361014650716439042856013203440242834878648506244428367706708431121109714505981728529818874621868624754285069693368779495316600601299037277003994790396589299

n1 =4850297138162223468826481623082440249579136876798312652735204698689613969008632545220976699170308454082390834742570718247804202060929493571642074679428565168405877110681518105667301785653517697684490982375078989886040451115082120928982588380914609273008153977907950532498605486225883973643141516024058315360572988744607134110254489421516026937249163493982681336628726033489124705657217768229058487155865265080427488028921879608338898933540825564889012166181346177276639828346376362168934208822467295673761876965864573164529336885250577357767314256581019474130651412100897839606491189424373959244023695669653213498329

e2 =65537

n2 = 2367536768672000959668181171787295271898789288397672997134843418932405959946739637368044420319861797856771490573443003520137149324080217971836780570522258661419034481514883068092752166752967879497095564732505614751532330408675056285275354250157955321457579006360393218327164804951384290041956551855334492796719901818165788902547584563455747941517296875697241841177219635024461395596117584194226134777078874543699117761893699634303571421106917894215078938885999963580586824497040073241055890328794310025879014294051230590716562942538031883965317397728271589759718376073414632026801806560862906691989093298478752580277

意外解:直接对n1或者n2进行因数分解,可以直接分解出pq。

得到:

q1 = 27809722472252756488236572384949349891208643090117349509994417047989746484576130392206781875743390815588696964830219136848285391966773129269973231061599768809907518881304479207799187410626121509031210549317480187679455501340422680238395009932081263455435640341892702399022829951248686529928945588545968218943

p1 = 174410123761631337520799179808598127914184971978811796722414215239874114048347830609255805203105210941441708658356189056418366104015120153227123562166980882513945308613658062284844636341082646995916907680076101741743945938845994542592182491688095893467336553001430454260431413695816790105384153941685561590503

解密脚本:

e1 = 1666626632960368239001159408047765991270250042206244157447171188195657302933019501932101777999510001235736338843107709871785906749393004257614129802061081155861433722380145001537181142613515290138835765236002811689986472280762408157176437503021753061588746520433720734608953639111558556930490721517579994493088551013050835690019772600744317398218183883402192060480979979456469937863257781362521184578142129444122428832106721725409309113975986436241662107879085361014650716439042856013203440242834878648506244428367706708431121109714505981728529818874621868624754285069693368779495316600601299037277003994790396589299
n1 = 4850297138162223468826481623082440249579136876798312652735204698689613969008632545220976699170308454082390834742570718247804202060929493571642074679428565168405877110681518105667301785653517697684490982375078989886040451115082120928982588380914609273008153977907950532498605486225883973643141516024058315360572988744607134110254489421516026937249163493982681336628726033489124705657217768229058487155865265080427488028921879608338898933540825564889012166181346177276639828346376362168934208822467295673761876965864573164529336885250577357767314256581019474130651412100897839606491189424373959244023695669653213498329
p1 = 27809722472252756488236572384949349891208643090117349509994417047989746484576130392206781875743390815588696964830219136848285391966773129269973231061599768809907518881304479207799187410626121509031210549317480187679455501340422680238395009932081263455435640341892702399022829951248686529928945588545968218943
q1 = 174410123761631337520799179808598127914184971978811796722414215239874114048347830609255805203105210941441708658356189056418366104015120153227123562166980882513945308613658062284844636341082646995916907680076101741743945938845994542592182491688095893467336553001430454260431413695816790105384153941685561590503

importgmpy2
d1 = gmpy2.invert(e1,((q1-1)*(p1-1)))
importrsa
key1 = rsa.PrivateKey(n1,e1,int(d1),p1,q1) #生成rsa私钥,用这个私钥来解密密文文件flag.enc
withopen('C:\\Users\\n0r1and3r\\Desktop\\One_Secret_Two_encryption\\flag_encry1','rb') asf1:
c1 = f1.read()
print(rsa.decrypt(c1,key1))

还有另外一种解法,可能这才是考察的方法。

求n1和n2的公约数,因为题目偷懒了,估计使用的同一个素数。

得到公约数174410123761631337520799179808598127914184971978811796722414215239874114048347830609255805203105210941441708658356189056418366104015120153227123562166980882513945308613658062284844636341082646995916907680076101741743945938845994542592182491688095893467336553001430454260431413695816790105384153941685561590503

由于n = q*p,假设公约数是q,则p = n除以q。

得到e1,n1,q1,p1,则解密和上面的解密脚本一致。

Crypto_easy_crypto

fromCrypto.Util.number import*
fromsecret importflag

defkeygen(nbit):
while True:
p,q,r = [getPrime(nbit) for_ inrange(3)] #生成三个素数qpr
ifisPrime(p + q + r):
pubkey = (p * q * r,p + q + r)
privkey = (p,q,r)
returnpubkey,privkey

defencrypt(msg,pubkey):
enc = pow(bytes_to_long(msg.encode('utf-8')),0x10001,pubkey[0] * pubkey[1]) # enc = m^e mod n
returnenc

nbit = 512
pubkey,_ = keygen(nbit)
print('pubkey =',pubkey)

enc = encrypt(flag,pubkey)
print('enc =',enc)

这是一个RSA的加密过程。输出给了三个信息:p,q,c。

#pubkey = (763929224901239050077647342425144363318006219360210465113458622937882119766705458273788947718911994090187932947694326848868575500906975653763043489419853300731695950407389203582333794360159494405111004208058198680365172060235321945875374635278292661761319773173838900295933943437761251440819434675631450032782188481758975272071015244168751016874668742536151359822585793537758876078350987062972237271763834743266722655055439868971805843593929839097963319788083763,
27750416681837900468631425875797804482827864226099175414717825894823303299159277202974070903630276868248755642608884903122768656427165401563920443482151217)
#enc =

7579294603035135817234501131256282324240132424272000903035801073847222917306092792610406876451698121956232047031639448767323475088170357863653435096746640609325525035329328626562143049656124241263576649974820533800161432666946327226418036826146160288273175521864687122720836795596635067761146519940441817765732160382018434465776749372209181212817247187474685246156193381822044772746654690126746715728166527274933634750443478682812664022009444348448955720226579468781927776133336045525149203384137859868153077820708167146052429014790660921586958660759949399826568136755816563468739111123761288318276379025018708883521

enc = pow(bytes_to_long(msg.encode('utf-8')),0x10001,pubkey[0] * pubkey[1]) 这条加密代码,可以得到,msg是flag,e = 0x10001=65537,

q = pubkey[0] = 763929224901239050077647342425144363318006219360210465113458622937882119766705458273788947718911994090187932947694326848868575500906975653763043489419853300731695950407389203582333794360159494405111004208058198680365172060235321945875374635278292661761319773173838900295933943437761251440819434675631450032782188481758975272071015244168751016874668742536151359822585793537758876078350987062972237271763834743266722655055439868971805843593929839097963319788083763

p = pubkey[1] =27750416681837900468631425875797804482827864226099175414717825894823303299159277202974070903630276868248755642608884903122768656427165401563920443482151217

那就可以直接求明文了。

解密脚本:

还没做111

Crypto_xor

题目提示了['\x00', '\x00', '\x00'] at start of xored is the best hint you get

xored是异或后的结果,开头三个/x00,只能是ctf与ctf的异或,相同字母异或得到0,下一个/x18,用/x18和{的异或结果是c,所以flag是与ctfctfctf.....的异或结果得到xored。

则flag可以是xored和ctfctfctf.........的结果。

脚本:

ls = ['\x00','\x00','\x00','\x18','C','_','\x05','E','V','T','F','U','R','B','_','U','G','_','V','\x17','V','S','@','\x03','[','C','\x02','\x07','C','Q','S','M','\x02','P','M','_','S','\x12','V','\x07','B','V','Q','\x15','S','T','\x11','_','\x05','A','P','\x02','\x17','R','Q','L','\x04','P','E','W','P','L','\x04','\x07','\x15','T','V','L','\x1b']
print(len(ls))
secret = "ctf"* (len(ls)//3)
print(secret)
a_list = [chr(ord(a) ^ ord(b)) fora,b inzip(ls,secret)]
print(a_list)
print("".join(a_list))

ctf{79f107231696395c004e87dd7709d3990f0d602a57e9f56ac428b31138bda258}

2018 AFCTF Vigenère

不用看加密程序,直接爆破,工具:Vigenere Solver - www.guballa.de

afctf{Whooooooo_U_Gotcha!}

2018 AFCTF你听过一次一密么?

不会做,直接抄脚本:

#!/usr/bin/python
## OTP - Recovering the private key from a set of messages that were encrypted w/ the same private key (Many time pad attack) - crypto100-many_time_secret @ alexctf 2017
# Original code by jwomers: https://github.com/Jwomers/many-time-pad-attack/blob/master/attack.py)


importstring
importcollections
importsets,sys

# 11 unknown ciphertexts (in hex format), all encrpyted with the same key

c1 = '25030206463d3d393131555f7f1d061d4052111a19544e2e5d'
c2 = '0f020606150f203f307f5c0a7f24070747130e16545000035d'
c3 = '1203075429152a7020365c167f390f1013170b1006481e1314'
c4 = '0f4610170e1e2235787f7853372c0f065752111b15454e0e09'
c5 = '081543000e1e6f3f3a3348533a270d064a02111a1b5f4e0a18'
c6 = '0909075412132e247436425332281a1c561f04071d520f0b11'
c7 = '4116111b101e2170203011113a69001b475206011552050219'
c8 = '041006064612297020375453342c17545a01451811411a470e'
c9 = '021311114a5b0335207f7c167f22001b44520c15544801125d'
c10 = '06140611460c26243c7f5c167f3d015446010053005907145d'
c11 = '0f05110d160f263f3a7f4210372c03111313090415481d49'
ciphers = [c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11]


# The target ciphertext we want to crack
# target_cipher = "0529242a631234122d2b36697f13272c207f2021283a6b0c7908"

# XORs two string

defstrxor(a,b): # xor two strings (trims the longer input)
return"".join([chr(ord(x) ^ ord(y)) for(x,y) inzip(a,b)])


deftarget_fix(target_cipher):
# To store the final key
final_key = [None] * 150
# To store the positions we know are broken
known_key_positions = set()

# For each ciphertext
forcurrent_index,ciphertext inenumerate(ciphers):
# print current_index,ciphertext
counter = collections.Counter()
# for each other ciphertext
forindex,ciphertext2 inenumerate(ciphers):
# print index,ciphertext2
ifcurrent_index != index: # don't xor a ciphertext with itself
# print ciphertext.decode('hex'),ciphertext2.decode('hex')

forindexOfChar,char inenumerate(strxor(ciphertext.decode('hex'),ciphertext2.decode('hex'))): # Xor the two ciphertexts
# print indexOfChar,char
# If a character in the xored result is a alphanumeric character, it means there was probably a space character in one of the plaintexts (we don't know which one)

ifchar instring.printable andchar.isalpha():
counter[indexOfChar] += 1# Increment the counter at this index
knownSpaceIndexes = []

# Loop through all positions where a space character was possible in the current_index cipher
forind,val incounter.items():
# If a space was found at least 7 times at this index out of the 9 possible XORS, then the space character was likely from the current_index cipher!
ifval >= 7: knownSpaceIndexes.append(ind)
# print knownSpaceIndexes # Shows all the positions where we now know the key!

# Now Xor the current_index with spaces, and at the knownSpaceIndexes positions we get the key back!

xor_with_spaces = strxor(ciphertext.decode('hex'),' '* 150)
forindex inknownSpaceIndexes:
# Store the key's value at the correct position
final_key[index] = xor_with_spaces[index].encode('hex')
# Record that we known the key at this position
known_key_positions.add(index)

# Construct a hex key from the currently known key, adding in '00' hex chars where we do not know (to make a complete hex string)
final_key_hex = ''.join([val ifval is not None else'00'forval infinal_key])
# Xor the currently known key with the target cipher
output = strxor(target_cipher.decode('hex'),final_key_hex.decode('hex'))

print"Fix this sentence:"
print''.join([char ifindex inknown_key_positions else'*'forindex,char inenumerate(output)]) + "\n"

# WAIT.. MANUAL STEP HERE
# This output are printing a * if that character is not known yet
# fix the missing characters like this: "Let*M**k*ow if *o{*a" = "cure, Let Me know if you a"
# if is too hard, change the target_cipher to another one and try again
# and we have our key to fix the entire text!

# sys.exit(0) #comment and continue if u got a good key


target_plaintext = "cure, Let Me know if you a"
print"Fixed:"
printtarget_plaintext + "\n"

key = strxor(target_cipher.decode('hex'),target_plaintext)

print"Decrypted msg:"
forcipher inciphers:
printstrxor(cipher.decode('hex'),key)

print"\nPrivate key recovered: "+ key + "\n"


fori inciphers:
target_fix(i)


版权声明:本文为qq_41152432原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。