这个比赛密码题难度比较简单,pwn题难度偏难,有涉及到SMM、UEFI、BootKit。可以花时间学一学这些如何PWN。不过先把密码复现了。
Crypto
the shortest crypto chal*
1 2 3 4 5 6 7 8 from Crypto.Cipher import AESfrom hashlib import md5from secret import a,b,c,d, FLAGassert a**4 + b**4 == c**4 + d**4 + 17 \ and max (a,b,c,d) < 2e4 \ and AES.new( f"{a*b*c*d} " .zfill(16 ).encode() , AES.MODE_ECB).encrypt(FLAG).hex () == "41593455378fed8c3bd344827a193bde7ec2044a3f7a3ca6fb77448e9de55155"
这题算是一个类似于小游戏,并且题目中已经给出max(a,b,c,d) < 2e4,这样其实就可以确定a,b,c,d < 20000,但是如果要单纯爆破的话还是不太行。
我们不妨考虑一下对这个等式做因式分解,但是发现分解不出来什么东西:
1 2 3 4 5 6 PR.<a,b,c,d> = PolynomialRing(ZZ) f = a^4 + b^4 - c^4 - d^4 -17 f.factor() """ (-1) * (-a^4 - b^4 + c^4 + d^4 + 17) """
那接下来就要考虑其他东西了,接下来我们考虑这个式子:
$$
\begin{array}{l}
a^{4}-c^{4}+b^4 - d^{4} = 17\
(a^2+c^2)(a^{2}-c^{2})+(b^{2}+d^{2})(b^{2}-d^{2})=17\
(a^2+c^2)(a+c)(a-c)+(b^2+d^{2})(b+d)(b-d)=17
\end{array}
$$
$$
\begin{array}{l}
a^4-c^4+b^{4}-d^4>0\
a^4-c^4>d^4-b^4\
a-c>d-b\
a+b>d+c
\end{array}
$$
其实还可以确定以下两种可能:
可能性1:$a-c>0$且$b-d<0$
可能性2:$a-c < 0$且$b-d>0$
继续推:
$$
\begin{array}{l}
a^4+b^4 ≥2a^2b^2\
c^4+d^4+17≥2a^2b^2
\end{array}
$$
$$
t = abcd
$$
too many primes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from sympy import nextprime, randprimefrom sympy.core.random import seedfrom math import prod, gcdfrom Crypto.Util.number import bytes_to_longp = randprime(2 **127 , 2 **128 ) N = 1 while N < 2 **2048 : N *= p p = nextprime(p) assert gcd(phi_N, 65537 ) == 1 pt = bytes_to_long(FLAG) ct = pow (pt, 65537 , N) print ("N = " , N)print ("ct = " , ct)
这题是RSA变种之一,多素数RSA加密的分解N的题,这题可以直接factordb.com分解出来
这题还有一个方法,就是费马分解法,先确定到底有多少个128位的素数相乘,爆破一下,发现是17个素数相乘,因为开17次方后的结果就可以得到128字节的一个数。
1 2 a = gmpy2.iroot(N,17 )[0 ] print (int (a).bit_length())
此时只要利用费马分解的思想,就可以稍微爆破出大于N开17次方的素数,发现有9个素数已经被找到了
1 2 3 4 5 6 7 8 9 10 11 12 N = a = gmpy2.iroot(N,17 )[0 ] p = [] while True : x = N % a if x == 0 : p.append(int (a)) print (p) N = N//a a = a + 1
接下来就是用sympy库中的prevprime,求解出钱8个素数。就可以解密了。
exp如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import gmpy2from sympy import nextprime, randprime, prevprimefrom Crypto.Util.number import bytes_to_long, inverse , long_to_bytesN = ct = e = 65537 a = gmpy2.iroot(N,17 )[0 ] p = [242444312856123694689611504831894231761 , 242444312856123694689611504831894231779 , 242444312856123694689611504831894231927 , 242444312856123694689611504831894232161 , 242444312856123694689611504831894232301 , 242444312856123694689611504831894232523 , 242444312856123694689611504831894232581 , 242444312856123694689611504831894232599 , 242444312856123694689611504831894232623 ] q = p[0 ] for i in range (17 -len (p)): q = prevprime(q) p.append(q) phi = 1 for i in p: phi = phi * (i-1 ) d = inverse(e,phi) m = pow (ct,d,N) flag = long_to_bytes(m) print (flag)""" b'uiuctf{D0nt_U5e_Cons3cUt1vE_PriMeS}' """
back to roots
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from random import randintfrom decimal import Decimal, getcontextfrom hashlib import md5from Crypto.Cipher import AESfrom Crypto.Util.Padding import padfrom secret import FLAGK = randint(10 **10 , 10 **11 ) print ('K' , K)leak = int ( str ( Decimal(K).sqrt() ).split('.' )[-1 ] ) print (f"leak = {leak} " )ct = AES.new( md5(f"{K} " .encode()).digest(), AES.MODE_ECB ).encrypt(pad(FLAG, 16 )) print (f"ct = {ct.hex ()} " )""" leak = 4336282047950153046404 ct = 7863c63a4bb2c782eb67f32928a1deceaee0259d096b192976615fba644558b2ef62e48740f7f28da587846a81697745 """
此题考察的就是Decimal这个东西,Decimal算是一个精度保存的东西。
首先就是随机选取一个值K,然后对这个K值转换为Decimal精度存储。
之后就是对精度存储的这个K值进行开根,开根后会保存小数点。
而题目中的leak,泄露的就是开根后的小数点部分。
经过测试,randint(10**10,10**11)开根后的整数范围大概在randint(10**5,10**6)的范围就行了。所以只需要爆破就行
具体的exp如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from random import randintfrom decimal import Decimal, getcontextfrom hashlib import md5from Crypto.Cipher import AESfrom Crypto.Util.Padding import padimport tqdmct = '7863c63a4bb2c782eb67f32928a1deceaee0259d096b192976615fba644558b2ef62e48740f7f28da587846a81697745' r = '0.4336282047950153046404' s = Decimal(r) for i in tqdm.tqdm(range (10 ^5 ,10 ^6 ),leave=True ): k = str (int ((Decimal(i)+s)^2 )) ci = AES.new(md5(k.encode()).digest(),AES.MODE_ECB) flag = ci.decrypt(bytes .fromhex(ct)) if b'ctf' in flag: print (flag) """ b'uiuctf{SQu4Re_Ro0T5_AR3nT_R4nD0M}\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' """
symmetric
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 from Crypto.Util.number import *from secret import FLAGp, q, r, s = [getPrime(512 ) for _ in "1234" ] print (f"h1 = {p + q + r + s} " )print (f"h2 = {p**2 + q**2 + r**2 + s**2 } " )print (f"h3 = {p**3 + q**3 + r**3 + s**3 } " )N = p*q*r*s print (f"N = {N} " )pt = bytes_to_long(FLAG) ct = pow (pt, 65537 , N) print (f"ct = {ct} " )""" h1 = 44626154099651354925697068610752642661842459492769931945027538340211738148995902544351457443643808803963130274930824732652561687395268828472477422919262224 h2 = 516671113554555861164166966331322883848052630063409185414998284127910160310316421085219788291486248715029393774584960034375836715001130337767354512063372620828300201147366138270597133744747341658011663632381219284289144790858167258162656417236910634201286428763727072739569460623482985066956478781223378673732 h3 = 6147718474663450187001867904227777991349731066494841442199681943204194617136760567222545181562592364728655444222576167723225771866335920325045525027985716792468801076590684892140052786942251780392395274059384743594570343510311801194684613435002073956759521242578078411431891501758484581445964234548107005826532945720412531638919892681259687552977883437895032963223761216846303917338652743754915155934118353066174102436448393348040719582422022713292561416343278608 N = 14184841414933523698606245433393907034474143715949896731683874356940146602876788990832087413915033843120975580859113356518777762025417525571528638829956003882418585702756644491932279294535883798799580861254646149745925137179207140600356428758736111639677698862407787386573263961111978517446397007747429416079059195916290615125084899002162504424765939524455434579218079962808920072946861658695379491917567048202142417165204141307476222251547098848515065051745905180788313450494477967398727631152936238366581978379130450660235139256967936160718128731512409111209840405772933034600016694225294481603355934917366484109057 ct = 720607330561370237459911161481490697044029472780348552630924063963226757984368356580217337982783395620115957442082471977614781910209933696251479615689667675958354681196823652299435457532944189300223816303315625302472302494905575910600277892375951366031061219173465155686586206246661009612156094695841741309002508535764511343569015518587247600796520847856011377777228749182958947015029731456117404560626347774985507275302882865400315045173501559082431672490227728580592379740508214726249635835834752208899970446910850569489282065524329936561486377823093465841715608716032843259935185417766702677708267102415636848129 """
此题还是一个多素数RSA的题型,这个题型还是分解模数类型的题型,但是这个题目中泄露的是:
$$
\begin{array}{l}
p+q+r+s=h_1\
p^2 + q^2 + r^2 + s^2=h_2\
p^3 + q^3 + r^3 + s^3=h_3
\end{array}
$$
直接用sagemath解方程即可,因为算上h1、h2、h3、n恰好就是4个未知数,4个方程能求解出来。
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 from Crypto.Util.number import *p,q,r,s = var('p,q,r,s' ) h1 = h2 = h3 = N = ct = e = 65537 eq1 = p*q*r*s == N eq2 = p+q+r+s == h1 eq3 = p^2 + q^2 + r^2 + s^2 == h2 eq4 = p^3 + q^3 + r^3 + s^3 == h3 result = solve([eq1,eq2,eq3,eq4],p,q,r,s)[0 ] p = result[0 ].rhs() q = result[1 ].rhs() r = result[2 ].rhs() s = result[3 ].rhs() phi = (p-1 )*(q-1 )*(r-1 )*(s-1 ) d = inverse(e,phi) m = pow (ct,d,N) flag = long_to_bytes(int (m)) print (flag)""" b'uiuctf{5yMmeTRiC_P0lyS_FoRM_A_B4S15}' """
PWN