LitCTF

为之则易,不为则难

记录2023LitCTF——crypto题解

梦想是红色的

题目:

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

社会主义核心价值观解码

解码得到:

LitCTF{为之则易,不为则难}

Hex? Hex!

题目:

1
4c69744354467b746169313131636f6f6c6c616161217d

16进制转字符串

解码得到:

LitCTF{tai111coollaaa!}

原来你也玩原神

密文:

对应提瓦特文字

提瓦特文字表:

把最后一行对应解码得到:

LitCTF{YUANLAINIYEWANYUANSHENWWW}

你是我的关键词

题目:

1
IFRURC{X0S_YP3_JX_HBXV0PA}

根据题目信息,知道这是关键词密码,而且密钥是YOU

解码得到:

LITCTF{Y0U_AR3_MY_KEYW0RD}

Is this only base?

栅栏 –> base64 –> 凯撒

题目:

1
2
SWZxWl=F=DQef0hlEiSUIVh9ESCcMFS9NF2NXFzM
今年是本世纪的第23年呢

先根据提示,23这个数字肯定有用

首先栅栏密码解密,这里的栅栏密码是特殊的W型解密才能得到有效信息,栏目数为23

解密得到:

SWZxWlFDe0liUV9ScF9FNFMzX2NSMCEhISEhfQ==

base64解密得到

IfqZQC{IbQ_Rp_E4S3_cR0!!!!!}

把LitCTF和IfqZQC对应一下

凯撒移动3位得到

LitCTF{LeT_Us_H4V3_fU0!!!!!}

Virginia

维吉尼亚 –> 凯撒

题目:

1
2
Ysexj lrk rzmkses os wilj hhks joa rtsy xzmktye yt xuim ehgy joa ofsz blnz yz pohv tnjx fxtx yuzc dxjlmy fyd nzr tnjx fuw cegq! Orkfx wnfe yuz haty eo jwpas;lz wnjce etf wgse tu lz;bk bsaz dzu cfyt zt me,hjnaaxp yuz sabj znrd znk qtfk fyd usp cnfyck yz du fwl zmp tnnygy dzu cfyt zt oo.Sfj yuz sabj pnuzrh nfapospsy yz mgpp yuz dwkje,ettfgn ycigqd tu rlkk dzu yycotl,pnuzrh ytcrub eo qjpp etf harln,kszumm sovj eo sfve etf hguay? Gqhaex auz dzuxxpll ny ozmpry’xsokx.Tf etf fkjw tnfe iz mfrzx joa,ne pxtmahqj hawes zmp ozmpr vjcsus, eou.Yse nfapojdt uk aeuuwe jty’t tjneyxlroqj hgap tnj meyy zf kapreysitl;ehkd uuyy xaqj ehk rzsz tq ebjcyzmtnm ysaz hzmkx llusr tnjtr cfj.Hguaitjds rnps ltc tntde cmz cxd,ehuxp wnt suxy, ehuxp wnt sabj degwnhki,lnj ysoyj hhu mlvk yciki,qox tyle ysee hln guarkhtazj ehk nxpuweathp ol upovqp,wnt sabj eoahsej yseow wibjd.Luap bkltny bttn f dmoqp,gxths cneh g ptsy fyd ksos cneh g ypax.Yse hwtgnypsz kftawp woqw arblyy gp bgxpd us l fuwrozypn vfdt, etf cgs’e gu ty wkqw it qtfkzytoq joa qpt mt zf etfr vfdt lftlawps gso hkfctghsey.Bset dzu cjce htcn,etf wkwp cxdtnm fyd kapretye gwzuti joa bls yrtlosr.Loap yuzc lokp su ysaz bset dzu jnp,yuz'ce zmp otj hhu nd ssnwitl lnj jgexdznk fcoaso yuz ts iwjitl.
Uwegxp skso tnnd mkxdamj eo zmzsk upovqp wnt xegs dosjehosr tu dzu,zt ehuxp wnt sabj eoahsej dzux qtfk ny otj hae tc attehkw,eo zmzsk bso sfve etf ssnwe cmpn etf rkfwle spej ne,tu ysoyj ehgy xaqj joa xpe zmp bxnrhzjc soip ol ysitld wnjy yuz lrk wparqj duby,tu ysoyj hhu dzu cfyt zt wez yses pyoc ysaz dzu guarkhtazj ehknc fxnpnjxsiv.Fyd ok joa izn’z, izn’z bzrxd,yozmtnm gld cnwl nfapks eo etf,yuz hirq uuyy xiyx zuz ty tnj zpvtctastte yz bxnrhzjy surpotj’d dgd hizm ehox xeyxlgk.Rj pgxdwuwo iy szt g wpgaqlr Ifpsgw aayxhoxi,lnj yse ksn frfr=[86, 116, 128, 80, 98, 85, 139, 122, 134, 114, 125, 136, 117, 123, 129, 127, 128, 128, 142, 130, 140, 147, 127, 132, 131, 136, 151, 134, 152, 164] -Cgjdax

维吉尼亚第一次解密得到:

1
2
There are moments in life when you miss someone so much that you just want to pick them from your dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.May you have enough happiness to make you sweet,enough trials to make you strong,enough sorrow to keep you human,enough hope to make you happy? Always put yourself in others’shoes.If you feel that it hurts you,it probably hurts the other person, too.The happiest of people don’t necessarily have the best of everything;they just make the most of everything that comes along their way.Happiness lies for those who cry,those who hurt, those who have searched,and those who have tried,for only they can appreciate the importance of people,who have touched their lives.Love begins with a smile,grows with a kiss and ends with a tear.The brightest future will always be based on a forgotten past, you can’t go on well in lifeuntil you let go of your past failures and heartaches.When you were born,you were crying and everyone around you was smiling.Live your life so that when you die,you're the one who is smiling and everyone around you is crying.
Jwybmp mfho nicd gfmduhy ei ubzmf jpiqfp qii xybh dinyebjhr np szo,ui ebpmp qii suwy eivwsye szos ftzf cy ioy huz ic uoiebfl,ei ubzmf qsi nuvy zif mncwy xbph zif lfuwfz hpye ce,np nsity ebbn xuly jiv mpy ubp vscrbuyc mjxp ig nscoad qiyy spo llf lpumfj xpqy,np nsity hbp szo xuyn ui wyu nsyn eyix nsuu szo bjalfwtuuy ebfcc zscphemscq.Uyx jz jiv xzh’u, xzh’u qzlss,yiubthh vlx xcwf iuajfh ei zif,spo hcmf uotn xctm zou iy niy zjqicnvhtnz nz vscrbuyy mpgpioy’d xbs hcub ebjm xytmlaf.Gj jbmdqplo ct hzn b lpavfll Dupmbl autmhisx,lhe nsy fhn zmur=[86, 116, 128, 80, 98, 85, 139, 122, 134, 114, 125, 136, 117, 123, 129, 127, 128, 128, 142, 130, 140, 147, 127, 132, 131, 136, 151, 134, 152, 164] -Wbydus

似乎没什么用,但是发现还有一段怪怪的信息,再解密一次:

1
Please send this message to those people who mean something to you,to those who have touched your life in one way or another,to those who make you smile when you really need it,to those that make you see the brighter side of things when you are really down,to those who you want to let them know that you appreciate their friendship.And if you don’t, don’t worry,nothing bad will happen to you,you will just miss out on the opportunity to brighten someone’s day with this message.My password is not a regular Caesar password,and the enc flag=[86, 116, 128, 80, 98, 85, 139, 122, 134, 114, 125, 136, 117, 123, 129, 127, 128, 128, 142, 130, 140, 147, 127, 132, 131, 136, 151, 134, 152, 164] -Caesar

注意到这段话来自Caesar(凯撒大帝)

把LitCTF的ascii码和86,116,128,80,98,85对应

写个脚本跑一下

1
2
3
4
5
6
7
8
9
list=[86, 116, 128, 80, 98, 85, 139, 122, 134, 114, 125, 136, 117, 123, 129, 127, 128, 128, 142, 130, 140, 147, 127, 132, 131, 136, 151, 134, 152, 164]
j = 0
flag = ""
for i in list:
flag += chr(i-(10+j))
j += 1
print(flag)

#LitCTF{it_is_different_caesar}

隐晦的消息记录

OPT(一次一密)加密OPT(一次一密加密法) - DexterJie’s Blog

题目:

1
2
3
4
5
出题人:6c73d5240a948c86981bc294814d
某不知名收件人:收到消息attack at dawn
出题人:xxxxxxxxxxxxxxxxxxxxxxxxxxxx
某不知名收件人:收到消息Monday or Thur
已知出题人和收件人手中的密钥相同,请解出出题人第二次发送的密文呢(16进制,字母小写,解得的结果记得要加上LitCTF{}哦。)

根据题目提示,知道这是OPT加密,了解一下原理之后就知道该加密方式是通过异或实现的

只要把密文和密钥进行异或就能得到明文

首先把 attack at dawn转成16进制,再和6c73d5240a948c86981bc294814d进行异或,即可得到密钥,因为两次密钥相同,所以把Monday or Thur和密钥异或,就是我们要的密文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ciphertext1 = 0x6c73d5240a948c86981bc294814d    #   attack at dawn转16进制后
plaintext1 = 0x61747461636b206174206461776e

key = ciphertext1 ^ plaintext1

# key = 0xd07a14569fface7ec3ba6f5f623

plaintext2 = 0x4d6f6e646179206f722054687572 # Monday or Thur转16进制后

ciphertext2 = key ^ plaintext2

print(hex(ciphertext2))

#NSSCTF{4068cf2108868c889e1bf29d8351}

RSA签到

题目:

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

m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
e = 65537
n = p*q
c = pow(m,e,n)
print(f'p = {p}')
print(f'q = {q}')
print(f'c = {c}')
'''
p = 12567387145159119014524309071236701639759988903138784984758783651292440613056150667165602473478042486784826835732833001151645545259394365039352263846276073
q = 12716692565364681652614824033831497167911028027478195947187437474380470205859949692107216740030921664273595734808349540612759651241456765149114895216695451
c = 108691165922055382844520116328228845767222921196922506468663428855093343772017986225285637996980678749662049989519029385165514816621011058462841314243727826941569954125384522233795629521155389745713798246071907492365062512521474965012924607857440577856404307124237116387085337087671914959900909379028727767057
'''

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert

p = 12567387145159119014524309071236701639759988903138784984758783651292440613056150667165602473478042486784826835732833001151645545259394365039352263846276073
q =12716692565364681652614824033831497167911028027478195947187437474380470205859949692107216740030921664273595734808349540612759651241456765149114895216695451
e = 65537
c =108691165922055382844520116328228845767222921196922506468663428855093343772017986225285637996980678749662049989519029385165514816621011058462841314243727826941569954125384522233795629521155389745713798246071907492365062512521474965012924607857440577856404307124237116387085337087671914959900909379028727767057
n = p*q

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

m = pow(c,d,n)
print(long_to_bytes(m))

#LitCTF{it_is_easy_to_solve_question_when_you_know_p_and_q}

md5的破解

题目:

1
2
3
4
5
6
7
8
9
10
from Crypto.Util.number import *
from hashlib import md5
from secret import flag

#flag全是由小写字母及数字组成
m=md5(flag).hexdigest()
print(flag[:13]+flag[15:18]+flag[19:34]+flag[35:38])
print(m)
# b'LitCTF{md5can3derypt213thoughcrsh}'
# 496603d6953a15846cd7cc476f146771

注意切片,前面闭区间,后面开区间

这里输出flag中索引值0—12, 15—17, 19—33, 35—37

第13,14,18,34位需要爆破,根据提示可以缩小爆破范围

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
import string
import hashlib

for a in string.ascii_lowercase + string.digits:
for b in string.ascii_lowercase + string.digits:
for c in string.ascii_lowercase + string.digits:
for d in string.ascii_lowercase + string.digits:
flag = "LitCTF{md5can" + a + b + "3de" + c + "rypt213thoughcr" + d +"sh}"
s = hashlib.md5(flag.encode()).hexdigest()
if s == "496603d6953a15846cd7cc476f146771":
print(flag)

#LitCTF{md5can123dexrypt213thoughcrpsh}

yafu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
n = 1
for i in range(15):
n *=getPrime(32)
e = 65537
c = pow(m,e,n)
print(f'n = {n}')
print(f'c = {c}')
'''
n = 15241208217768849887180010139590210767831431018204645415681695749294131435566140166245881287131522331092026252879324931622292179726764214435307
c = 12608550100856399369399391849907846147170257754920996952259023159548789970041433744454761458030776176806265496305629236559551086998780836655717
'''

注意n的产生方式,是由15个素数相乘得到

分解n,得到15个因子,然后求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert
c = 12608550100856399369399391849907846147170257754920996952259023159548789970041433744454761458030776176806265496305629236559551086998780836655717
e = 65537
n =15241208217768849887180010139590210767831431018204645415681695749294131435566140166245881287131522331092026252879324931622292179726764214435307

p =[2201440207,3354884521,4171911923,2719600579,2906576131,4021078331,2151018733,2758708999,2315495107,4044505687,2923522073,3355651511,2585574697,2767137487,3989697563]
phi = 1
for i in p:
phi *= i-1

d = invert(e,phi)

m = pow(c,d,n)
print(long_to_bytes(m))

#LitCTF{Mu1tiple_3m4ll_prim5_fac7ors_@re_uns4f5}

factot b

题目:

1
2
3
e = 65537
n = 87924348264132406875276140514499937145050893665602592992418171647042491658461
c = 87677652386897749300638591365341016390128692783949277305987828177045932576708

网站分解

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert

p =275127860351348928173285174381581152299
q =319576316814478949870590164193048041239
n = p*q
e = 65537
c =87677652386897749300638591365341016390128692783949277305987828177045932576708

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

m = pow(c,d,n)
print(long_to_bytes(m))

#LitCTF{factordb!!!}

the same common divisor

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from Crypto.Util.number import *
m=bytes_to_long(b'xxxxxx')
e=65537
p=getPrime(1024)
q1=getPrime(1024)
q2=getPrime(1024)
n1=p*q1
n2=p*q2
c1=pow(m,e,n1)
c2=pow(m,e,n2)
n3=n1^n2
print('n1=',n1)
print('n3=',n3)
print('c1=',c1)
print('c2=',c2)
#n1= 9852079772293301283705208653824307027320071498525390578148444258198605733768947108049676831872672654449631852459503049139275329796717506126689710613873813880735666507857022786447784753088176997374711523987152412069255685005264853118880922539048290400078105858759506186417678959028622484823376958194324034590514104266608644398160457382895380141070373685334979803658172378382884352616985632157233900719194944197689860219335238499593658894630966428723660931647038577670614850305719449893199713589368780231046895222526070730152875112477675102652862254926169713030701937231206405968412044029177246460558028793385980934233
#n3= 4940268030889181135441311597961813780480775970170156650560367030148383674257975796516865571557828263935532335958510269356443566533284856608454193676600884849913964971291145182724888816164723930966472329604608512023988191536173112847915884014445539739070437180314205284883149421228744714989392788108329929896637182055266508625177260492776962915873036873839946591259443753924970795669864031580632650140641456386202636466624658715315856453572441182758855085077441336516178544978457053552156714181607801760605521338788424464551796638531143900048375037218585999440622490119344971822707261432953755569507740550277088437182
#c1= 7066425618980522033304943700150361912772559890076173881522840300333719222157667104461410726444725540513601550570478331917063911791020088865705346188662290524599499769112250751103647749860198318955619903728724860941709527724500004142950768744200491448875522031555564384426372047270359602780292587644737898593450148108629904854675417943165292922990980758572264063039172969633878015560735737699147707712154627358077477591293746136250207139049702201052305840453700782016480965369600667516646007546442708862429431724013679189842300429421340122052682391471347471758814138218632022564279296594279507382548264409296929401260
#c2= 854668035897095127498890630660344701894030345838998465420605524714323454298819946231147930930739944351187708040037822108105697983018529921300277486094149269105712677374751164879455815185393395371001495146490416978221501351569800028842842393448555836910486037183218754013655794027528039329299851644787006463456162952383099752894635657833907958930587328480492546831654755627949756658554724024525108575961076341962292900510328611128404001877137799465932130220386963518903892403159969133882215092783063943679288192557384595152566356483424061922742307738886179947575613661171671781544283180451958232826666741028590085269

共享素数

n1和n2共用了p

先异或n1,n3得到n2,再得到p

exp:

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

n1 = 9852079772293301283705208653824307027320071498525390578148444258198605733768947108049676831872672654449631852459503049139275329796717506126689710613873813880735666507857022786447784753088176997374711523987152412069255685005264853118880922539048290400078105858759506186417678959028622484823376958194324034590514104266608644398160457382895380141070373685334979803658172378382884352616985632157233900719194944197689860219335238499593658894630966428723660931647038577670614850305719449893199713589368780231046895222526070730152875112477675102652862254926169713030701937231206405968412044029177246460558028793385980934233
n3 = 4940268030889181135441311597961813780480775970170156650560367030148383674257975796516865571557828263935532335958510269356443566533284856608454193676600884849913964971291145182724888816164723930966472329604608512023988191536173112847915884014445539739070437180314205284883149421228744714989392788108329929896637182055266508625177260492776962915873036873839946591259443753924970795669864031580632650140641456386202636466624658715315856453572441182758855085077441336516178544978457053552156714181607801760605521338788424464551796638531143900048375037218585999440622490119344971822707261432953755569507740550277088437182
c1 = 7066425618980522033304943700150361912772559890076173881522840300333719222157667104461410726444725540513601550570478331917063911791020088865705346188662290524599499769112250751103647749860198318955619903728724860941709527724500004142950768744200491448875522031555564384426372047270359602780292587644737898593450148108629904854675417943165292922990980758572264063039172969633878015560735737699147707712154627358077477591293746136250207139049702201052305840453700782016480965369600667516646007546442708862429431724013679189842300429421340122052682391471347471758814138218632022564279296594279507382548264409296929401260
c2 = 854668035897095127498890630660344701894030345838998465420605524714323454298819946231147930930739944351187708040037822108105697983018529921300277486094149269105712677374751164879455815185393395371001495146490416978221501351569800028842842393448555836910486037183218754013655794027528039329299851644787006463456162952383099752894635657833907958930587328480492546831654755627949756658554724024525108575961076341962292900510328611128404001877137799465932130220386963518903892403159969133882215092783063943679288192557384595152566356483424061922742307738886179947575613661171671781544283180451958232826666741028590085269

n2 = n1 ^ n3
p = gcd(n1,n2)
q = n1 // p
e = 65537

d = invert(e,(p-1)*(q-1))
m = pow(c1,d,n1)
print(long_to_bytes(m))

#LitCTF{TH3_Tw0_nUmb3rs_H@v3_The_sAme_D1v1s0r!!}

e的学问

考点是e和phi不互素,相关知识在学习过程中有

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Util.number import *
m=bytes_to_long(b'xxxxxx')
p=getPrime(256)
q=getPrime(256)
e=74
n=p*q
c=pow(m,e,n)
print("p=",p)
print("q=",q)
print("c=",c)
#p= 86053582917386343422567174764040471033234388106968488834872953625339458483149
#q= 72031998384560188060716696553519973198388628004850270102102972862328770104493
#c= 3939634105073614197573473825268995321781553470182462454724181094897309933627076266632153551522332244941496491385911139566998817961371516587764621395810123

因为e和phi不互素,先对e和phi求公因数t,再把e除去这个公因数

这样就使得新的e和phi互素

exp:

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

p = 86053582917386343422567174764040471033234388106968488834872953625339458483149
q = 72031998384560188060716696553519973198388628004850270102102972862328770104493
n = p*q
e = 74
c = 3939634105073614197573473825268995321781553470182462454724181094897309933627076266632153551522332244941496491385911139566998817961371516587764621395810123
phi = (p-1)*(q-1)

if gmpy2.gcd(phi,e) != 1:
t = gmpy2.gcd(phi,e) #因为Phi和e不互素,所以要用e除掉他们的公因数,保证新的e和phi互素
e1 = e // t
d = gmpy2.invert(e1,phi)
m = pow(c,d,n)
msg = gmpy2.iroot(m,t)
if msg[1]:
print(long_to_bytes(msg[0]))

#LitCTF{e_1s_n0t_@_Prime}

Euler

对欧拉函数的理解

题目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
c = pow(m,n-p-q+3,n)
print(f'n = {n}')
print(f'c = {c}')
"""
n = 115140122725890943990475192890188343698762004010330526468754961357872096040956340092062274481843042907652320664917728267982409212988849109825729150839069369465433531269728824368749655421846730162477193420534803525810831025762500375845466064264837531992986534097821734242082950392892529951104643690838773406549
c = 406480424882876909664869928877322864482740577681292497936198951316587691545267772748204383995815523935005725558478033908575228532559165174398668885819826720515607326399097899572022020453298441
"""

通过爆破K,即可得到m。

自己闲着没事试了一下,好像m的次方大于5就不能通过这个方法求

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import long_to_bytes
from gmpy2 import iroot
n = 115140122725890943990475192890188343698762004010330526468754961357872096040956340092062274481843042907652320664917728267982409212988849109825729150839069369465433531269728824368749655421846730162477193420534803525810831025762500375845466064264837531992986534097821734242082950392892529951104643690838773406549
c = 406480424882876909664869928877322864482740577681292497936198951316587691545267772748204383995815523935005725558478033908575228532559165174398668885819826720515607326399097899572022020453298441
k=0
while 1:
m = iroot(k*n+c,2)[0]
flag = str(long_to_bytes(m))
if "LitCTF" in flag :
print(flag)
break
else:
k += 1

#LitCTF{a1a8887793acfc199182a649e905daab}

easy_math

解方程

题目:

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

m = bytes_to_long(flag)
e = 65537
p = getPrime(512)
q = getPrime(128)
n = p*q
hint = p**3-q**5
c = pow(m,e,n)
print(f'n = {n}')
print(f'c = {c}')
print(f'hint = {hint}')
'''
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
c = 2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
'''

解方程得到p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sympy import symbols, solve

# 定义符号变量
x = symbols('x')
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
# 定义方程
eq = x**8 - x**5*hint - n**5

# 解方程
sol = solve(eq, x)

# 打印解
print(sol)

这个脚本能跑,需要很久,而且输出的结果很多

用下面这个脚本可以更快求出p

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
from sympy import symbols, solve
import gmpy2
from Crypto.Util.number import long_to_bytes

# 定义符号变量
p = symbols('p')
q = symbols('q')
hint = 392490868359411675557103683163021977774935163924606169241731307258226973701652855448542714274348304997416149742779376023311152228735117186027560227613656229190807480010615064372521942836446425717660375242197759811804760170129768647414717571386950790115746414735411766002368288743086845078803312201707960465419405926186622999423245762570917629351110970429987377475979058821154568001902541710817731089463915930932142007312230897818177067675996751110894377356758932
n = 2230791374046346835775433548641067593691369485828070649075162141394476183565187654365131822111419512477883295758461313983481545182887415447403634720326639070667688614534290859200753589300443797
# 定义方程
eq1 = p**3 - q**5 -hint
eq2 = p * q - n
# 解方程
sol = solve((eq1,eq2),(p,q))

# 打印解
print(sol)

e = 65537
c=2168563038335029902089976057856861885635845445863841607485310134441400500612435296818745930370268060353437465666224400129105788787423156958336380480503762222278722770240792709450637433509537280
p = 7321664971326604351487965655099805117568571010588695608389113791312918573783115429227542573780838065461696504325762281209452761930184231131129306271846427
q = 304683618109085947723284393392507415311
d = gmpy2.invert(e,(p-1)*(q-1))
print(long_to_bytes(pow(c,d,n)))

#LitCTF{f9fab7522253e44b48824e914d0801ba}

babyLCG

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

m = bytes_to_long(flag)
bit_len = m.bit_length()
a = getPrime(bit_len)
b = getPrime(bit_len)
p = getPrime(bit_len+1)

seed = m
result = []
for i in range(10):
seed = (a*seed+b)%p
result.append(seed)
print(result)
"""
result = [699175025435513913222265085178805479192132631113784770123757454808149151697608216361550466652878, 193316257467202036043918706856603526262215679149886976392930192639917920593706895122296071643390, 1624937780477561769577140419364339298985292198464188802403816662221142156714021229977403603922943, 659236391930254891621938248429619132720452597526316230221895367798170380093631947248925278766506, 111407194162820942281872438978366964960570302720229611594374532025973998885554449685055172110829, 1415787594624585063605356859393351333923892058922987749824214311091742328340293435914830175796909, 655057648553921580727111809001898496375489870757705297406250204329094679858718932270475755075698, 1683427135823894785654993254138434580152093609545092045940376086714124324274044014654085676620851, 492953986125248558013838257810313149490245209968714980288031443714890115686764222999717055064509, 70048773361068060773257074705619791938224397526269544533030294499007242937089146507674570192265]
"""

求seed初始值,在此之前需要先求a,b,m

关于lcg体制可以观看另外一篇博客

exp:

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
from Crypto.Util.number import long_to_bytes
import gmpy2

output = [...]

for i in range(9):
try:
t1 = output[i+1]-output[i]
t2 = output[i+2]-output[i+1]
t3 = output[i+3]-output[i+2]
t4 = output[i+4]-output[i+3]

T1 = t1*t3 - t2*t2
T2 = t2*t4 - t3*t3
n = gmpy2.gcd(T1,T2)

ni = gmpy2.invert(t1,n)
a = t2 * ni % n

Ani = gmpy2.invert(a,n)
b = (output[i+1] - a*output[i]) % n

m = Ani *(output[0]-b) % n
print(long_to_bytes(m))

except:
i += 1

#LitCTF{31fcd7832029a87f6c9f760fcf297b2f}

3tefaine丶zhou师傅分享的另外一个wp

another exp:

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
#Sage
from Crypto.Util.number import *

result = [...]

# 构建一个多项式环,包含两个变量a和b,系数在整数域ZZ上
P.<a,b> = PolynomialRing(ZZ)
# 定义了四个多项式方程f1,f2,f3,f4,其中result是一个包含数值的列表。
# 所以这构建了一个线性方程组
f1 = result[0]*a + b - result[1]
f2 = result[1]*a + b - result[2]
f3 = result[2]*a + b - result[3]
f4 = result[3]*a + b - result[4]
# 将四个方程存储在列表F中
F = [f1,f2,f3,f4]
# 使用F构建一个理想的Ideal。
Ideal = Ideal(F)
# # 计算Ideal的Gröbner基I
I = Ideal.groebner_basis()
print(I)

a = ZZ(-I[0].univariate_polynomial()(0))
b = ZZ(-I[1].univariate_polynomial()(0))
p = ZZ(I[2])

m = (result[0]-b)*a^-1 % p
print(long_to_bytes(int(m)))

P_leak

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from Crypto.Util.number import *
e=65537
m=bytes_to_long(b'xxxx')
p=getPrime(512)
q=getPrime(512)
n=p*q
phi=(p-1)*(q-1)
d=inverse(e,phi)
dp=d%(p-1)
c=pow(m,e,n)
print("dp=",dp)
print("n=",n)
print("c=",c)

#dp= 5892502924236878675675338970704766304539618343869489297045857272605067962848952532606770917225218534430490745895652561015493032055636004130931491316020329
#n= 50612159190225619689404794427464916374543237300894011803225784470008992781409447214236779975896311093686413491163221778479739252804271270231391599602217675895446538524670610623369953168412236472302812808639218392319634397138871387898452935081756580084070333246950840091192420542761507705395568904875746222477
#c= 39257649468514605476432946851710016346016992413796229928386230062780829495844059368939749930876895443279723032641876662714088329296631207594999580050131450251288839714711436117326769029649419789323982613380617840218087161435260837263996287628129307328857086987521821533565738409794866606381789730458247531619

dp泄露

exp:

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

n = 50612159190225619689404794427464916374543237300894011803225784470008992781409447214236779975896311093686413491163221778479739252804271270231391599602217675895446538524670610623369953168412236472302812808639218392319634397138871387898452935081756580084070333246950840091192420542761507705395568904875746222477
c = 39257649468514605476432946851710016346016992413796229928386230062780829495844059368939749930876895443279723032641876662714088329296631207594999580050131450251288839714711436117326769029649419789323982613380617840218087161435260837263996287628129307328857086987521821533565738409794866606381789730458247531619
dp =5892502924236878675675338970704766304539618343869489297045857272605067962848952532606770917225218534430490745895652561015493032055636004130931491316020329
e =65537

for i in range(1,e):
t = (dp * e - 1) % i
if t == 0:
p = (dp * e - 1) // i + 1
if n % p == 0:
q = n // p
d = gmpy2.invert(e,(p-1)*(q-1))
print(long_to_bytes(pow(c,d,n)))

#LitCTF{Prim3_1s_Le@k!!!!!}

Where is P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Util.number import *
m=bytes_to_long(b'XXXX')
e=65537
p=getPrime(1024)
q=getPrime(1024)
n=p*q
print(p)
c=pow(m,e,n)
P=p>>340
print(P)
a=pow(P,3,n)
print("n=",n)
print("c=",c)
print("a=",a)

#n= 24479907029118467064460793139240403258697681144532146836881997837526487637306591893357774423547391867013441147680031968367449693796015901951120514250935018725570026327610524687128709707340727799633444550317834481416507364804274266363478822257132586592232042108076935945436358397787891169163821061005102693505011197453089873909085170776511350713452580692963748763166981047023704528272230392479728897831538235554137129584665886878574314566549330671483636900134584707867654841021494106881794644469229030140144595938886437242375435914268001721437309283611088568191856208951867342004280893021653793820874747638264412653721
#c= 6566517934961780069851397787369134601399136324586682773286046135297104713708615112015588908759927424841719937322574766875308296258325687730658550956691921018605724308665345526807393669538103819281108643141723589363068859617542807984954436567078438099854340705208503317269397632214274507740533638883597409138972287275965697689862321166613821995226000320597560745749780942467497435742492468670016480112957715214640939272457886646483560443432985954141177463448896521810457886108311082101521263110578485768091003174683555938678346359150123350656418123918738868598042533211541966786594006129134087145798672161268647536724
#a= 22184346235325197613876257964606959796734210361241668065837491428527234174610482874427139453643569493268653377061231169173874401139203757698022691973395609028489121048788465356158531144787135876251872262389742175830840373281181905217510352227396545981674450409488394636498629147806808635157820030290630290808150235068140864601098322473572121965126109735529553247807211711005936042322910065304489093415276688746634951081501428768318098925390576594162098506572668709475140964400043947851427774550253257759990959997691631511262768785787474750441024242552456956598974533625095249106992723798354594261566983135394923063605

p高位泄露

因为P大小为684bit,P的3次方是2052bit,而n是2048bit,相差4位

爆一下k就可以得到P

exp:

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
from Crypto.Util.number import *
import gmpy2

n= 24479907029118467064460793139240403258697681144532146836881997837526487637306591893357774423547391867013441147680031968367449693796015901951120514250935018725570026327610524687128709707340727799633444550317834481416507364804274266363478822257132586592232042108076935945436358397787891169163821061005102693505011197453089873909085170776511350713452580692963748763166981047023704528272230392479728897831538235554137129584665886878574314566549330671483636900134584707867654841021494106881794644469229030140144595938886437242375435914268001721437309283611088568191856208951867342004280893021653793820874747638264412653721
c= 6566517934961780069851397787369134601399136324586682773286046135297104713708615112015588908759927424841719937322574766875308296258325687730658550956691921018605724308665345526807393669538103819281108643141723589363068859617542807984954436567078438099854340705208503317269397632214274507740533638883597409138972287275965697689862321166613821995226000320597560745749780942467497435742492468670016480112957715214640939272457886646483560443432985954141177463448896521810457886108311082101521263110578485768091003174683555938678346359150123350656418123918738868598042533211541966786594006129134087145798672161268647536724
a= 22184346235325197613876257964606959796734210361241668065837491428527234174610482874427139453643569493268653377061231169173874401139203757698022691973395609028489121048788465356158531144787135876251872262389742175830840373281181905217510352227396545981674450409488394636498629147806808635157820030290630290808150235068140864601098322473572121965126109735529553247807211711005936042322910065304489093415276688746634951081501428768318098925390576594162098506572668709475140964400043947851427774550253257759990959997691631511262768785787474750441024242552456956598974533625095249106992723798354594261566983135394923063605
e = 65537

R.<x> = PolynomialRing(Zmod(n))

for k in range(1000):
t = gmpy2.iroot(k*n+a,3)
if t[1]:
high_p = int(t[0])<<340
f = high_p + x
x = f.small_roots(X = 2^340,beta = 0.4)
if x:
p = int(high_p + x[0])
q = n // int(p)
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(k)
print(long_to_bytes(int(m)))
break

# k = 11
# LitCTF{Y0U_hAV3_g0T_Th3_r1ghT_AnsW3r}

我测你vva

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Encrypto{
public static void main(String[] args) {
String flag="";
int cipher;
char[] arr;
arr=flag.toCharArray();
for(int i=0; i<flag.length(); i++) {
if(i%2==0){
cipher=Integer.valueOf(arr[i]);
cipher=cipher+i;
System.out.print((char)cipher);
}
if(i%2!=0){
cipher=Integer.valueOf(arr[i]);
cipher=cipher-i;
System.out.print((char)cipher);
}
}
}
}
//cipher=HYEQJvPZ~X@+Bp

比赛的时候是非预期解,现在重新做一遍

Integer.valueOf() 方法将一个字符串表示的整数转换为对应的Integer 对象

题目的意思就是把明文偶数位的值加上他的索引值再变为字符串,eg:arr[2]="65"经过加密之后这个位置就变成了”C”

奇数位则是把明文减去他的索引值

把脚本逆回去就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Decrypto{
public static void main(String[] args) {
String Cipher="HYEQJvPZ~X@+Bp";
int flag;
char[] arr;
arr=Cipher.toCharArray();
for(int i=0; i<Cipher.length(); i++) {
if(i%2==0){
flag=Integer.valueOf(arr[i]);
flag=flag-i;
System.out.print((char)flag);
}
if(i%2!=0){
flag=Integer.valueOf(arr[i]);
flag=flag+i;
System.out.print((char)flag);
}
}
}
}

# HZCTF{Java666}
# 格式改一下 LitCTF{Java666}

Babyxor

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

m = bytes_to_long(flag)
assert len(flag)==32
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537
c1 = p^m
c2 = pow(m,e,n)
print(f'n = {n}')
print(f'c1 = {c1}')
print(f'c2 = {c2}')
"""
n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
"""

首先测试了一下32长度的字符串,转为int类型的数据大概是256bit

1024位的p需要已知576位

512位的p需要已知288位

当满足这样一个关系的时候才可恢复:

但是把f.small_roots(X,beta,epsilon)中的epsilon改为0.01,即最小的时候,可以在已知264位的情况下恢复512位的p,已知528位恢复1024位的p,而这道题中,我们已知256位p,所以需要爆破8位,再恢复p

exp:

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
import gmpy2
from tqdm import *
from Crypto.Util.number import *
n = 139167681803392690594490403105432649693546256181767408269202101512534988406137879788255103631885736461742577594980136624933914700779445704490217419248411578290305101891222576080645870988658334799437317221565839991979543660824098367011942169305111105129234902517835649895908656770416774539906212596072334423407
c1 = 11201139662236758800406931253538295757259990870588609533820056210585752522925690049252488581929717556881067021381940083808024384402885422258545946243513996
c2 = 112016152270171196606652761990170033221036025260883289104273504703557624964071464062375228351458191745141525003775876044271210498526920529385038130932141551598616579917681815276713386113932345056134302042399379895915706991873687943357627747262597883603999621939794450743982662393955266685255577026078256473601
e=65537
pbits = 512

p_high = c1 >> 256
for i in trange(2**8):
p4 = p_high<<8 #这里需要先爆破8位,使得知道264位以后再恢复p
p4 = p4 + i
kbits = pbits - p4.nbits()
p4 = p4 << kbits
R.<x> = PolynomialRing(Zmod(n))
f = x + p4
x = f.small_roots(X=2^kbits, beta=0.4, epsilon=0.01)
if x:
p = p4 + int(x[0])
q = n // p
d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c2,d,n)
print(long_to_bytes(int(m)))
break

#LitCTF{oh!!!!coppersmith_is_fun}

放虚拟机跑会更快一些

-------------已经到底啦!-------------