文章目录

  • Exposure
  • more_calc
  • RSAssss
  • simpleRSA
  • blowfishgame

Exposure

题目考点:

dp高位泄露

题目

Do you know how to rsa?
from Crypto.Util.number import *
import gmpy2p = getStrongPrime(512)
q = getStrongPrime(512)
n = p * q
phi = (p - 1) * (q - 1)
e = 7621
d = gmpy2.invert(e, phi)flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
c = pow(bytes_to_long(flag), e, n)dp = d % (p - 1)
print(dp >> 200)
print(c, e, n)'''
dp>>200 = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863
'''

解题
参考文章:https://github.com/pcw109550/write-up/tree/master/2019/KAPO/Lenstra-Lenstra-Lovasz

∵e×d≡1(mod(p−1)(q−1))∴e×d=k1(p−1)(q−1)+1,k1∈Z∵dp=d(modp−1)∴e×[k2(p−1)+dp]=k1(p−1)(q−1)+1,k1、k2∈Z∴e×dp=(p−1)[k1(q−1)−ek2]+1令k3=k1(q−1)−ek2,即e×dp=k3(p−1)+1∴e×dp≡1(modp−1)∵dp<p−1∴k3<e∵e×dp=k3(p−1)+1=k3×p−k3+1∴e×dp+k3−1≡0(modp)\begin{aligned} &\because e \times d \equiv 1 \pmod {(p-1)(q-1)} \\ &\therefore e \times d=k_1 (p-1)(q-1)+1,k_1 \in \mathbb{Z}\\ &\because dp =d \pmod {p-1} \\ &\therefore e \times [k_2(p-1)+dp]=k_1 (p-1)(q-1)+1,k_1、k_2 \in \mathbb{Z} \\ &\therefore e \times dp = (p-1)[k_1(q-1)-ek_2]+1 \\ &令k_3=k_1(q-1)-ek_2,即e \times dp = k_3(p-1)+1 \\ &\therefore e \times dp \equiv 1 \pmod {p-1} \\ &\because dp<p-1 \\ &\therefore k_3<e \\ &\because e \times dp = k_3(p-1)+1=k_3 \times p-k_3+1 \\ &\therefore e \times dp+k_3-1 \equiv 0 \pmod p \end{aligned} ​∵e×d≡1(mod(p−1)(q−1))∴e×d=k1​(p−1)(q−1)+1,k1​∈Z∵dp=d(modp−1)∴e×[k2​(p−1)+dp]=k1​(p−1)(q−1)+1,k1​、k2​∈Z∴e×dp=(p−1)[k1​(q−1)−ek2​]+1令k3​=k1​(q−1)−ek2​,即e×dp=k3​(p−1)+1∴e×dp≡1(modp−1)∵dp<p−1∴k3​<e∵e×dp=k3​(p−1)+1=k3​×p−k3​+1∴e×dp+k3​−1≡0(modp)​

这道题知道secret = dp>>200,即已知dp的高位恢复出dp。
e×(secret<<200+x)+k3−1≡0(modp)e \times (secret<<200+x)+k_3-1 \equiv 0 \pmod pe×(secret<<200+x)+k3​−1≡0(modp)

#sage
#dp高位泄露攻击,这里泄露了(secret=dp>>200)
secret = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863F.<x> = PolynomialRing(Zmod(n))
d = inverse_mod(e, n)
for k in range(1, e):# 这里爆破得到 k=1237print('k =',k)f = (secret << 200) + x + (k - 1) * dx0 = f.small_roots(X=2 ** (200 + 1), beta=0.44, epsilon=1/32)if len(x0) != 0:dp = x0[0] + (secret << 200)for i in range(2, e):p = (e * Integer(dp) - 1 + i) // iif n % p == 0:breakif p < 0:continueelse:print('p =',p)print('dp =',dp)break

整合脚本,获取flag。

#sage
secret = 1153696846823715458342658568392537778171840014923745253759529432977932183322553944430236879985
c = 46735962204857190520476434898881001530665718155698898882603422023484998388668858692912250418134186095459060506275961050676051693220280588047233628259880712415593039977585805890920089318643002597837000049626154900908543384761210358835843974072960080857150727010985827690190496793207012355214605393036388807616
e = 7621
n = 140376049134934822153964243403031201922239588054133319056483413311963385321279682186354948441840374124640187894619689719746347334298621083485494086361152915457458004998419817456902929318697902819798254427945343361548635794308362823239150919240307072688623000747781103375481834571274423004856276841225675241863[n, secret, c] = list(map(Integer, [n, secret, c]))def facorize(e, dp):for i in range(2, e):p = (e * dp - 1 + i) // iif n % p == 0:return preturn -1def recover(secret):F.<x> = PolynomialRing(Zmod(n))d = inverse_mod(e, n)for k in range(1235, e):print('k =',k)f = (secret << 200) + x + (k - 1) * dx0 = f.small_roots(X=2 ** (200 + 1), beta=0.44, epsilon=1/32)if len(x0) != 0:dp = x0[0] + (secret << 200)p = facorize(e, Integer(dp))if p < 0:continueelse:return p, dpif __name__ == "__main__":p, dp = recover(secret)q = n // passert p * q == nphi = (p - 1) * (q - 1)d = inverse_mod(e, phi)print('p =',p)print('q =',q)m = pow(c, d, n)flag = bytes.fromhex(hex(m)[2:])print(flag)

more_calc

题目

maybe u need more cpu
import gmpy2
from Crypto.Util.number import *flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"p = getStrongPrime(2048)
for i in range(1, (p+1)//2):s += pow(i, p-2, p)
s = s % p
q = gmpy2.next_prime(s)
n = p*q
e = 0x10001
c = pow(bytes_to_long(flag), e, n)
print(p)
print(c)
'''
p = 27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069
c = 350559186837488832821747843236518135605207376031858002274245004287622649330215113818719954185397072838014144973032329600905419861908678328971318153205085007743269253957395282420325663132161022100365481003745940818974280988045034204540385744572806102552420428326265541925346702843693366991753468220300070888651732502520797002707248604275755144713421649971492440442052470723153111156457558558362147002004646136522011344261017461901953583462467622428810167107079281190209731251995976003352201766861887320739990258601550606005388872967825179626176714503475557883810543445555390014562686801894528311600623156984829864743222963877167099892926717479789226681810584894066635076755996423203380493776130488170859798745677727810528672150350333480506424506676127108526488370011099147698875070043925524217837379654168009179798131378352623177947753192948012574831777413729910050668759007704596447625484384743880766558428224371417726480372362810572395522725083798926133468409600491925317437998458582723897120786458219630275616949619564099733542766297770682044561605344090394777570973725211713076201846942438883897078408067779325471589907041186423781580046903588316958615443196819133852367565049467076710376395085898875495653237178198379421129086523
'''

解题

经过圆子师傅的指点进行的推导:
∵c=me(modn)∴c1=c(modp)=me(modp)令ed1=1(modp−1)∴m=cd(modn)=c1d1(modp)\begin{aligned} &\because c=m^e \pmod n \\ &\therefore c_1=c \pmod p=m^e \pmod p \\ &令ed_1=1 \pmod{p-1}\\ &\therefore m=c^d \pmod n=c_1^{d_1} \pmod p \end{aligned} ​∵c=me(modn)∴c1​=c(modp)=me(modp)令ed1​=1(modp−1)∴m=cd(modn)=c1d1​​(modp)​

import gmpy2p=27405107041753266489145388621858169511872996622765267064868542117269875531364939896671662734188734825462948115530667205007939029215517180761866791579330410449202307248373229224662232822180397215721163369151115019770596528704719472424551024516928606584975793350814943997731939996459959720826025110179216477709373849945411483731524831284895024319654509286305913312306154387754998813276562173335189450448233216133842189148761197948559529960144453513191372254902031168755165124218783504740834442379363311489108732216051566953498279198537794620521800773917228002402970358087033504897205021881295154046656335865303621793069
c=350559186837488832821747843236518135605207376031858002274245004287622649330215113818719954185397072838014144973032329600905419861908678328971318153205085007743269253957395282420325663132161022100365481003745940818974280988045034204540385744572806102552420428326265541925346702843693366991753468220300070888651732502520797002707248604275755144713421649971492440442052470723153111156457558558362147002004646136522011344261017461901953583462467622428810167107079281190209731251995976003352201766861887320739990258601550606005388872967825179626176714503475557883810543445555390014562686801894528311600623156984829864743222963877167099892926717479789226681810584894066635076755996423203380493776130488170859798745677727810528672150350333480506424506676127108526488370011099147698875070043925524217837379654168009179798131378352623177947753192948012574831777413729910050668759007704596447625484384743880766558428224371417726480372362810572395522725083798926133468409600491925317437998458582723897120786458219630275616949619564099733542766297770682044561605344090394777570973725211713076201846942438883897078408067779325471589907041186423781580046903588316958615443196819133852367565049467076710376395085898875495653237178198379421129086523
e=0x10001
c1=c%p
d1=gmpy2.invert(e,p-1)
m=pow(c1,d1,p)
flag = bytes.fromhex(hex(m)[2:])
print(flag)

RSAssss

题目考点:

费马因式分解

题目

more factors,more strong
from Crypto.Util.number import *
from gmpy2 import next_primep = getPrime(512)
q = getPrime(512)n = p * q * next_prime(p) * next_prime(q)
e = 0x10001flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"
cipher = pow(bytes_to_long(flag), e, n)print(n, cipher)'''
n = 8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257
cipher = 3304124639719334349997663632110579306673932777705840648575774671427424134287680988314129312593361087606243819528298610131797078262351307396831985397555390640151391138633431951746748156610463582479645561779194981806129898009876517899450840875569675976765155608446799203699927448835004756707151281044859676695533373755798273892503194753948997947653100690841880925445059175494314198605475023939567750409907217654291430615102258523998394231436796902635077995829477347316754739938980814293304289318417443493019704073164585505217658570214989150175123757038125380996050761572021986573934155470641091678664451080065719261207
'''

解题
参考文章:https://github.com/pcw109550/write-up/tree/master/2019/ISITDTU/Easy_RSA_2

∵p2=next_prime(p1),q2=next_prime(q1)∴p1q1、p1q2、p2q1、p2q2的值相差不大由费马因式分解可知,对于任意一个奇数n,n=ab=x2−y2=(x+y)(x−y)即x=a+b2,y=a−b2因为n为奇数,a,b必也为奇数,所以(a+b)和(a−b)必为偶数,故能被2整除,x、y∈Z可以从x=[n]+i,i∈Z开始,当(x2−n)可被完全开方后即可求出x,y∵n=p1q1p2q2利用费马因式分解可求出p1q1、p1q2、p2q1、p2q2的值然后利用欧几里得算法求出p1、q1、p2、q2即p1=gcd(p1q1,p1q2)\begin{aligned} &\because p_2=next\_prime(p_1),q_2=next\_prime(q_1)\\ &\therefore p_1q_1、p_1q_2、p_2q_1、p_2q_2的值相差不大\\ &由费马因式分解可知,对于任意一个奇数n,n = ab = x^2-y^2 =(x+y)(x-y)\\ &即x = \frac{a+b}{2},y=\frac{a-b}{2}\\ &因为n为奇数,a, b必也为奇数,所以(a+b)和(a-b)必为偶数,故能被2整除,x、y \in \mathbb{Z}\\ &可以从x=[\sqrt{n}]+i,i \in \mathbb{Z}开始,当(x^2-n)可被完全开方后即可求出x,y\\ &\because n=p_1q_1p_2q_2 \\ &利用费马因式分解可求出p_1q_1、p_1q_2、p_2q_1、p_2q_2的值\\ &然后利用欧几里得算法求出p_1、q_1、p_2、q_2\\ &即p_1=gcd(p_1q_1,p_1q_2) \end{aligned} ​∵p2​=next_prime(p1​),q2​=next_prime(q1​)∴p1​q1​、p1​q2​、p2​q1​、p2​q2​的值相差不大由费马因式分解可知,对于任意一个奇数n,n=ab=x2−y2=(x+y)(x−y)即x=2a+b​,y=2a−b​因为n为奇数,a,b必也为奇数,所以(a+b)和(a−b)必为偶数,故能被2整除,x、y∈Z可以从x=[n​]+i,i∈Z开始,当(x2−n)可被完全开方后即可求出x,y∵n=p1​q1​p2​q2​利用费马因式分解可求出p1​q1​、p1​q2​、p2​q1​、p2​q2​的值然后利用欧几里得算法求出p1​、q1​、p2​、q2​即p1​=gcd(p1​q1​,p1​q2​)​

exp:

from Cryptodome.Util.number import *
from gmpy2 import *e = 0x10001
n = 8030860507195481656424331455231443135773524476536419534745106637165762909478292141556846892146553555609301914884176422322286739546193682236355823149096731058044933046552926707682168435727800175783373045726692093694148718521610590523718813096895883533245331244650675812406540694948121258394822022998773233400623162137949381772195351339548977422564546054188918542382088471666795842185019002025083543162991739309935972705871943787733784491735500905013651061284020447578230135075211268405413254368439549259917312445348808412659422810647972872286215701325216318641985498202349281374905892279894612835009186944143298761257
c = 3304124639719334349997663632110579306673932777705840648575774671427424134287680988314129312593361087606243819528298610131797078262351307396831985397555390640151391138633431951746748156610463582479645561779194981806129898009876517899450840875569675976765155608446799203699927448835004756707151281044859676695533373755798273892503194753948997947653100690841880925445059175494314198605475023939567750409907217654291430615102258523998394231436796902635077995829477347316754739938980814293304289318417443493019704073164585505217658570214989150175123757038125380996050761572021986573934155470641091678664451080065719261207def fermat_factorization(n):factor_list = []get_context().precision = 2048x = int(sqrt(n))while True:x += 1y2 = x ** 2 - nif is_square(y2):#print('x = ',x)y2 = mpz(y2)get_context().precision = 2048y = int(sqrt(y2))factor_list.append([x+y, x-y])if len(factor_list) == 2:breakreturn factor_listdef main():factor_list = fermat_factorization(n)#print(factor_list)[X1, Y1] = factor_list[0][X2, Y2] = factor_list[1]assert X1 * Y1 == nassert X2 * Y2 == np1 = gcd(X1, X2)q1 = X1 // p1p2 = gcd(Y1, Y2)q2 = Y1 // p2#print('p1 =',p1)#print('p2 =',p2)#print('q1 =',q1)#print('q2 =',q2)phi = (p1 - 1) * (q1 - 1) * (p2 - 1) * (q2 - 1)d = inverse(e, phi)flag = long_to_bytes(pow(c, d, n))print(flag)if __name__ == "__main__":main()

simpleRSA

题目考点:

低解密指数攻击

题目

Familiar and simple rsa
from Crypto.Util.number import *
import gmpy2p, q, r = [getPrime(512) for i in range(3)]
n = p * q * r
phi = (p - 1) * (q - 1) * (r - 1)
d = getPrime(256)
e = gmpy2.invert(d , phi)flag = b"flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}"c = pow(bytes_to_long(flag), e, n)print(e, n)
print(c)'''
e = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679
n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173
c = 1079929174110820494059355415059104229905268763089157771374657932646711017488701536460687319648362549563313125268069722412148023885626962640915852317297916421725818077814237292807218952574111141918158391190621362508862842932945783059181952614317289116405878741758913351697905289993651105968169193211242144991434715552952340791545323270065763529865010326192824334684413212357708275259096202509042838081150055727650443887438253964607414944245877904002580997866300452
'''

解题

参考lazzzaro师傅的文章。

低解密指数攻击的部分原理
∵φ(n)=(p−1)(q−1)=pq−(p+q)+1=n−(p+q)+1∵p,q很大,pq>>p+q∴φ(n)≈n∵ed≡1(modφ(n)),即ed=kφ(n)+1,k∈Z式子两边同除以dφ(n),移位得到:eφ(n)−kd=1dφ(n),k∈Z∵φ(n)≈n,dφ(n)又很大∴en略大于kde,n已知,计算出en后,可以通过en的连分数展开,依次算出这个分数的每一个渐进分数由于en略大于kd,Wiener证明了该攻击能精确覆盖kd\begin{aligned} &\because \varphi(n) = (p-1)(q-1)=pq - (p + q) + 1=n- (p + q) + 1 \\ &\because p,q很大,pq>>p+q \\ &\therefore \varphi(n) \approx n \\ &\because ed \equiv 1 \pmod{\varphi(n)},即ed=k \varphi(n)+1,k \in \mathbb{Z} \\ &式子两边同除以d\varphi(n),移位得到:\frac{e}{\varphi(n)}-\frac{k}{d}=\frac{1}{d\varphi(n)},k \in \mathbb{Z} \\ &\because \varphi(n) \approx n ,d\varphi(n)又很大 \\ &\therefore \frac{e}{n}略大于\frac{k}{d}\\ &e,n已知,计算出\frac{e}{n}后,可以通过\frac{e}{n}的连分数展开,依次算出这个分数的每一个渐进分数\\ &由于\frac{e}{n}略大于\frac{k}{d},Wiener证明了该攻击能精确覆盖\frac{k}{d} \end{aligned} ​∵φ(n)=(p−1)(q−1)=pq−(p+q)+1=n−(p+q)+1∵p,q很大,pq>>p+q∴φ(n)≈n∵ed≡1(modφ(n)),即ed=kφ(n)+1,k∈Z式子两边同除以dφ(n),移位得到:φ(n)e​−dk​=dφ(n)1​,k∈Z∵φ(n)≈n,dφ(n)又很大∴ne​略大于dk​e,n已知,计算出ne​后,可以通过ne​的连分数展开,依次算出这个分数的每一个渐进分数由于ne​略大于dk​,Wiener证明了该攻击能精确覆盖dk​​

在 e 过大或过小的情况下,可使用算法从 e 中快速推断出 d 的值。可以解决q<p<2q,d<13N14q<p<2q,d<\frac{1}{3}N^{\frac{1}{4}}q<p<2q,d<31​N41​的问题

exp:

from Cryptodome.Util.number import long_to_bytes
e = 1072295425944136507039938677101442481213519408125148233880442849206353379681989305000570387093152236263203395726974692959819315410781180094216209100069530791407495510882640781920564732214327898099944792714253622047873152630438060151644601786843683746256407925709702163565141004356238879406385566586704226148537863811717298966607314747737551724379516675376634771455883976069007134218982435170160647848549412289128982070647832774446345062489374092673169618836701679
n = 1827221992692849179244069834273816565714276505305246103435962887461520381709739927223055239953965182451252194768935702628056587034173800605827424043281673183606478736189927377745575379908876456485016832416806029254972769617393560238494326078940842295153029285394491783712384990125100774596477064482280829407856014835231711788990066676534414414741067759564102331614666713797073811245099512130528600464099492734671689084990036077860042238454908960841595107122933173
c = 1079929174110820494059355415059104229905268763089157771374657932646711017488701536460687319648362549563313125268069722412148023885626962640915852317297916421725818077814237292807218952574111141918158391190621362508862842932945783059181952614317289116405878741758913351697905289993651105968169193211242144991434715552952340791545323270065763529865010326192824334684413212357708275259096202509042838081150055727650443887438253964607414944245877904002580997866300452#连分数展开算法
def lf(x,y):arr=[]while y:arr+=[x//y]x,y=y,x%yreturn arr
#渐进分数算法
def jj(k):x=0y=1for i in k[::-1]:x,y=y,x+i*yreturn (y,x)
data=lf(e,n)for x in range(1,len(data)+1):data1=data[:x]d = jj(data1)[1]m = pow(c,d,n)flag = long_to_bytes(m)if b'flag{' in flag:print(flag)break

blowfishgame

自己太菜,当时没做出来。复现了一下,参考 Timeline Sec战队的文章。
由于环境已经没法访问了,自己搭了一个,去掉了Pow验证。

环境代码:

#!/usr/bin/pythonimport os, string, signal, sys
from Crypto.Cipher import Blowfish
from base64 import *
flag = b'flag{4a6e1679-ea78-63d0-aa39-1ad423b361a8}'
banner = '''____  _             __ _     _                        _  _
| __ )| | _____   __/ _(_)___| |__   __   _____  _ __| | __| |
|  _ \| |/ _ \ \ /\ / / |_| / __| '_ \  \ \ /\ / / _ \| '__| |/ _` |
| |_) | | (_) \ V  V /|  _| \__ \ | | |  \ V  V / (_) | |  | | (_| |
|____/|_|\___/ \_/\_/ |_| |_|___/_| |_|   \_/\_/ \___/|_|  |_|\__,_|
'''bk = 8
master_key = os.urandom(bk)
sendIV = os.urandom(bk)
class Blow_CBC_demo:def __init__(self, iv):self.key = master_keyself.iv = ivdef pad(self, message):pad_length = bk-len(message)%bkreturn message+chr(pad_length)*pad_lengthdef unpad(self, message):return message[:-ord(message[-1])]def encrypt(self, message):message = self.pad(message)blow = Blowfish.new(self.key, Blowfish.MODE_CBC, self.iv)ciphertxt = blow.encrypt(message)return ciphertxtdef decrypt(self, message):blow = Blowfish.new(self.key, Blowfish.MODE_CBC, self.iv)plaintxt = blow.decrypt(message)plaintxt = self.unpad(plaintxt)return plaintxtdef send_enc(message):sys.stdout.flush()handle = Blow_CBC_demo(sendIV)ciphertxt = handle.encrypt(message)message = sendIV+ciphertxtmessage = b64encode(message)print(message)returndef get_enc():sys.stdout.flush()message = sys.stdin.readline().strip()try:message = b64decode(message)if (len(message) > 600):exit(0)handle = Blow_CBC_demo(message[:bk])plaintxt = handle.decrypt(message[bk:])return plaintxtexcept:print('Error')exit(0)def send_pl(m):sys.stdout.flush()print(m)sys.stdout.flush()def get_pl():sys.stdout.flush()return sys.stdin.readline().strip()def pad(message):pad_length = bk-len(message)%bkreturn message+chr(pad_length)*pad_lengthif __name__ == '__main__':assert(len(flag) == 42)signal.alarm(180)send_pl(banner)send_enc('Blowfish_w0rld')while True:try:message = get_enc().strip()if message.startswith('get_flag'):user = get_pl().strip()blow = Blowfish.new(master_key)send_pl(b64encode(blow.encrypt(pad(user+flag))))elif message.startswith('exit'):exit()else:send_enc('Invalid command')except:exit()

然后使用命令开启监听

socat TCP4-LISTEN:10000,tcpwrap=script,reuseaddr,fork EXEC:"python blowfishgame.py"

这里用的是Blowfish算法的cbc模式。
cbc模式的加密解密示例图如下:

分析代码:

一开始send_enc('Blowfish_w0rld')

def send_enc(message):sys.stdout.flush()handle = Blow_CBC_demo(sendIV)ciphertxt = handle.encrypt(message)message = sendIV+ciphertxtmessage = b64encode(message)print(message)return

可以得到cbc模式的初始iv和密文。

然后经过message = get_enc().strip()后明文以get_flag开头:

def get_enc():sys.stdout.flush()#message为我们输入的内容message = sys.stdin.readline().strip()try:message = b64decode(message)if (len(message) > 600):exit(0)handle = Blow_CBC_demo(message[:bk])plaintxt = handle.decrypt(message[bk:])return plaintxtexcept:print('Error')exit(0)

如果我们就原样的将得到的密文重新输入进去,那么解密后肯定是Blowfish开头。
这里就用到了cbc翻转攻击
解密时密文第一块的c1c_1c1​,首先是使用密钥key解密得到密文c1′c_1^{'}c1′​,然后异或上iviviv得到明文m1m_1m1​,即Blowfish
∵Dk(c1)⊕iv=m1=Blowfish这里若是修改iv的值,使iv′=iv⊕Blowfish⊕get_flag∴Dk(c1)⊕iv′=Dk(c1)⊕iv⊕Blowfish⊕get_flag=get_flag\begin{aligned} &\because D_k(c_1) \oplus iv = m_1 = Blowfish\\ &这里若是修改iv的值,使iv^{'}=iv \oplus Blowfish \oplus get\_flag \\ &\therefore D_k(c_1) \oplus iv^{'} = D_k(c_1) \oplus iv \oplus Blowfish \oplus get\_flag = get\_flag & \end{aligned} ​∵Dk​(c1​)⊕iv=m1​=Blowfish这里若是修改iv的值,使iv′=iv⊕Blowfish⊕get_flag∴Dk​(c1​)⊕iv′=Dk​(c1​)⊕iv⊕Blowfish⊕get_flag=get_flag​​
这样修改了iv的值,就能使得到的明文变为get_flag

然后就是将我们输入的内容和flag一起进行加密:

if message.startswith('get_flag'):user = get_pl().strip()blow = Blowfish.new(master_key)send_pl(b64encode(blow.encrypt(pad(user+flag))))

这里就可以逐字节的爆破出flag。

举个例子:
由于输入的user部分可控,一开始如果我们输入47个x,那么被分组后得到明文块:

xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxx?

这里?代表未知的flag的第一个字节。通过爆破?,然后比较密文是否一致得到flag的第一个字节,比如为f
然后我们输入46个x,那么被分组后得到明文块:

xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxxx、xxxxxxf?

继续爆破得到flag的第二个字节。
这样逐位爆破最终即可得到flag。

exp

from pwn import *
from random import *
from string import *
import hashlib,re,base64strs = string.ascii_letters+string.digits
r = remote('127.0.0.1',10000)def xor(a,b):assert len(a)==len(b)return ''.join([chr(ord(a[i])^ord(b[i])) for i in range(len(a))])def main():r.recvuntil('\n\n')cipher=  r.recvuntil('\n')[:-1]message = base64.b64decode(cipher)sendIV = message[:8]ciphertxt = message[8:]de_c1 = xor('Blowfish', sendIV.decode('raw_unicode_escape'))newIV = xor('get_flag', de_c1)get_flag = base64.b64encode(newIV.encode('raw_unicode_escape')+ciphertxt)flag = ''alphabet = 'flag{}-bcde0123456789'for i in range(42):r.sendline(get_flag)target_m = 'x'*(47-i)r.sendline(target_m)target_c = base64.b64decode(r.recvline())for x in alphabet:r.sendline(get_flag)test_m = 'x'*(47-i) + flag + xr.sendline(test_m)test_c = base64.b64decode(r.recvline())if test_c[:48]==target_c[:48]:flag+=xprint('[%2d/42] %s'%(i+1,flag))breakr.interactive()if __name__ == '__main__':main()


========================================================
返回目录
========================================================
转载请注明出处
本文网址:https://blog.csdn.net/hiahiachang/article/details/109749551
========================================================

祥云杯2020(11.21-22)-CryptoWP相关推荐

  1. java 中1%3c1%3c1_祥云杯2020 部分WriteUp

    祥云杯 Web ★sign 1%09||%09ls%09/ 1%09||%09ca\t%09in\dex.p\hp时有个闪 1%09||find%09/%09-name%09`echo%09ZmxhK ...

  2. 祥云杯2020 Crypto wp

    Crypto: SimpleRSA wiener attack 利用自定义的m检验生成的d'来判断phi是否正确 e=10722954259441365070399386771014424812135 ...

  3. 生活就是这样充满一些小插曲的2020.11.21日记

    生活日记 又是一个早期的周六,早上上课,然后去食堂吃饭.好久不去食堂吃饭了,看见有我喜欢的平菇就点了一份,高兴的坐了下来准备品尝,第一口夹一个大的,一口包进嘴里等着满足感的反馈.???什么味道,怎么这 ...

  4. 计算机组成与体系结构——串联系统与并联系统——2020.11.21

    并联是一种冗余状态 冗余机制,提高系统的可靠性 --高岸为谷,深谷为陵--

  5. Jenkins持续集成学习笔记(2020.11.22)

    Jenkins持续集成学习笔记(2020.11.22) 前言: (官网) 以前很久学习过Jenkins持续集成进行快速部署项目进行测试, 最近换工作了, 发现新公司有用到, 现在来复习一下 官网介绍: ...

  6. 【豆瓣电影】2019/11/21/Python搜索豆瓣电影(Top100)爬虫+D3.js词云(票房和豆瓣评分)实现

    [豆瓣电影爬虫]2019/11/21/Python豆瓣电影爬虫+D3.js WordCloud 1.目标 今天临时需要将100部票房最高的电影[from艺恩网:如图1],找到对应的豆瓣评分,制作D3词 ...

  7. QIIME 2教程. 22命令行界面q2cli(2020.11)

    文章目录 命令行界面`q2cli` 基本用法 Basic usage 开启命令行补全Enable command-line tab completion Bash Zsh 验证标签页完成 Verify ...

  8. [2020首届祥云杯]带音乐家

    [2020首届祥云杯]带音乐家 题目: 下载好附件,打开,得到一个文件与一个rar包: 并且rar包是经过了加密的,我这里去010里看了下,发现并不是伪加密: 所以突破点就只有上面的decode_it ...

  9. 【微语】第一周(2020.11.16~11.22)

    11.16.时光,浓淡相宜,人心,远近相安.流年,长短皆逝.浮生,往来皆客.早安,打工人! 11.17.最艰难的时候,别老想着太远的将来,只要鼓励自己熬过今天就好. 11.18.如果没有躺赢的命,那就 ...

最新文章

  1. angular.isUndefined()
  2. java常用容器(集合)的总结
  3. fireworks做图的最高长度
  4. 搭建可视化网页的software package_网页制作与网站搭建步骤教程
  5. 2021-11-18Collections
  6. 问题战略[置顶] 十八年开发经验分享(四)问题解决篇(下)
  7. java设计模式之道文字版,Java Web设计模式之道 PDF
  8. 分享到facebook没有封面图_拾柒自制书封面图分享~
  9. Qt在线/离线安装包下载网址和说明
  10. 开源分布式数据库 TiKV 入选 CNCF 云原生项目!
  11. linux 嵌入式 快照_定制嵌入式 Linux 发行版
  12. 2018科大讯飞营销广告算法大赛
  13. Mac电脑快速断网详细
  14. 分布式session解决方案
  15. Markdown 中 LaTex 数学公式命令
  16. gtx1660是什么级别的_GTX1660Ti和1660区别对比 GTX1660和1660Ti差距大吗
  17. “掌上运维” – 下一代网管的思考
  18. 浅记录一下MATLAB安装心得
  19. python数据分析(一):列联分析与方差分析
  20. CVPR-2021 | RepVGG:极简架构,SOTA性能,让VGG式模型再次伟大

热门文章

  1. 安全基础--22--安全测试
  2. flash幻灯片动画模板
  3. 出海的成本越来越高,奈何
  4. FAST-LIVO论文翻译
  5. 字典型列表转化为csv文件格式
  6. 元宇宙与未来生活的100年畅想
  7. trainging contest#1(2011大连现场赛)G BY bly
  8. 执行 npm install -g grunt-cli 安装grunt发生错误问题
  9. minio的安装及使用
  10. 云计算基础及应用 第一章 云计算基础