2024 SICTF Round#3出题 crypto misc osint

有幸参与了本次比赛crypto misc OSINT出题,难易程度循序渐进,下面记录一下本人题目题解((
比赛网址:https://yuanshen.life/

CRYPTO

SuperbRSA(85支队伍攻克)

题目

CRYPTO真的很难吗?Ö_O不会吧不会吧!,一定要相信自己咩~

出题人:Kicky_Mu

复制代码
#user:mumu666
from Crypto.Util.number import *
p=getPrime(1024)
q=getPrime(1024)
n=p*q
e1=55
e2=200
m=bytes_to_long("flag")
assert(pow(m,5) < n)
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print("n=",n)
print("c1=",c1)
print("c2=",c2)

n= 19006830358118902392432453595802675566730850352890246995920642811967821259388009049803513102750594524106471709641202019832682438027312468849299985832675191795417160553379580813410722359089872519372049229233732405993062464286888889084640878784209014165871696882564834896322508054231777967011195636564463806270998326936161449009988434249178477100127347406759932149010712091376183710135615375272671888541233275415737155953323133439644529709898791881795186775830217884663044495979067807418758455237701315019683802437323177125493076113419739827430282311018083976114158159925450746712064639569301925672742186294237113199023
c1= 276245243658976720066605903875366763552720328374098965164676247771817997950424168480909517684516498439306387133611184795758628248588201187138612090081389226321683486308199743311842513053259894661221013008371261704678716150646764446208833447643781574516045641493770778735363586857160147826684394417412837449465273160781074676966630398315417741542529612480836572205781076576325382832502694868883931680720558621770570349864399879523171995953720198118660355479626037129047327185224203109006251809257919143284157354935005710902589809259500117996982503679601132486140677013625335552533104471327456798955341220640782369529
c2= 11734019659226247713821792108026989060106712358397514827024912309860741729438494689480531875833287268454669859568719053896346471360750027952226633173559594064466850413737504267807599435679616522026241111887294138123201104718849744300769676961585732810579953221056338076885840743126397063074940281522137794340822594577352361616598702143477379145284687427705913831885493512616944504612474278405909277188118896882441812469679494459216431405139478548192152811441169176134750079073317011232934250365454908280676079801770043968006983848495835089055956722848080915898151352242215210071011331098761828031786300276771001839021

我的解答:

这题属实是第二天的签到题了。虽然有脚本可套,但尽量还是要懂原理。

我们不难发现e1和e2的GCD不为1,看这个代码:assert(pow(m,5) < n) 消息的五次方小于n,那么如果我们找到m的五次方然后取它的五次方根不就行了?

如何去求呢?这里需要一个转换:

我们令:

5ax + 5by = 5

然后我们将e1和e2同除以5,则得到a=11和b=40,这时他们彼此互为质数,这样一来,我们就可以利用数学证明得到m的五次方:

c1 = me1 mod n

c2 = me2 mod n

(c1^x^) mod n\] \* \[(c2^y^) mod n\] = (m^e1\*x+e2\*y^) mod n = m^5ax+5by^ mod n = m^5^ mod n 因此,便得到m^5^ 最后使用gmpy2的iroot函数来获得整数根。 exp: #mumu666 import gmpy2 from Crypto.Util.number import long_to_bytes def extended_euclid_gcd(a, b): """ Returns a list `result` of size 3 where: Referring to the equation ax + by = gcd(a, b) result[0] is gcd(a, b) result[1] is x result[2] is y """ s = 0; old_s = 1 t = 1; old_t = 0 r = b; old_r = a while r != 0: quotient = old_r//r # In Python, // operator performs integer or floored division old_r, r = r, old_r - quotient*r old_s, s = s, old_s - quotient*s old_t, t = t, old_t - quotient*t return [old_r, old_s, old_t] n= 19006830358118902392432453595802675566730850352890246995920642811967821259388009049803513102750594524106471709641202019832682438027312468849299985832675191795417160553379580813410722359089872519372049229233732405993062464286888889084640878784209014165871696882564834896322508054231777967011195636564463806270998326936161449009988434249178477100127347406759932149010712091376183710135615375272671888541233275415737155953323133439644529709898791881795186775830217884663044495979067807418758455237701315019683802437323177125493076113419739827430282311018083976114158159925450746712064639569301925672742186294237113199023 c1= 276245243658976720066605903875366763552720328374098965164676247771817997950424168480909517684516498439306387133611184795758628248588201187138612090081389226321683486308199743311842513053259894661221013008371261704678716150646764446208833447643781574516045641493770778735363586857160147826684394417412837449465273160781074676966630398315417741542529612480836572205781076576325382832502694868883931680720558621770570349864399879523171995953720198118660355479626037129047327185224203109006251809257919143284157354935005710902589809259500117996982503679601132486140677013625335552533104471327456798955341220640782369529 c2= 11734019659226247713821792108026989060106712358397514827024912309860741729438494689480531875833287268454669859568719053896346471360750027952226633173559594064466850413737504267807599435679616522026241111887294138123201104718849744300769676961585732810579953221056338076885840743126397063074940281522137794340822594577352361616598702143477379145284687427705913831885493512616944504612474278405909277188118896882441812469679494459216431405139478548192152811441169176134750079073317011232934250365454908280676079801770043968006983848495835089055956722848080915898151352242215210071011331098761828031786300276771001839021 e1=55 e2=200 # ax + by = 1 gcd, x, y = extended_euclid_gcd(e1//5, e2//5) m = (pow(c1, x, n) * pow(c2, y, n)) % n m = gmpy2.iroot(m, 5)[0] print(long_to_bytes(m)) #SICTF{S0_Great_RSA_Have_Y0u_Learned?} ## babyRSA(9支队伍攻克) 题目 树木想要一个baby题目,不说了。。那就来个吧! 出题人:Kicky_Mu p = random_prime(1<<512) with open("ffllaagg.txt", "rb") as f: flag = int.from_bytes(f.read().strip(), "big") assert flag < p a = randint(2, p-1) b = randint(2, p-1) x = randint(2, p-1) def h(): global a, b, x x = (a*x + b) % p return x PR. = PolynomialRing(GF(p)) f = h() + h()*X + h()*X**2 + h()*X**3 + h()*X**4 + h()*X**5 v_me_50 = [(i, f(i)) for i in range(1, 5)] print(p) print(v_me_50) print(f(flag)) p = 8432316544210923620966806031040552674652729976238765323782536889706914762471638598119051165931563126522925761119650997703305509546949570434637437942542827 v_me_50 = [(1, 5237331460408741346823741966490617418367283531029963248255318507187035341590236835730694472064897540292182231844047116067936691956970631907605500080014355), (2, 5798977431976767515500795413771120575460553181185728489626756434911307088093739452469315524092208822863785429164219547384598943937099787390543171055679780), (3, 5030862375386942201139427367618716490378481408210696947331523552250206476805124204780313138835912303941204343248384742875319182761611109448446270069831113), (4, 4705360705603328842229554954026497175574981026785287316439514185860486128679614980330307863925942038530792583274904352630757089631411920876914529907563209)] f_flag = 7251453750672416392395590357197330390627853878488142305852099080761477796591562813165554150640801022882531891827653530623183405183605476913024545431842867 我的解答: 我们可知题目使用LCG生成了一个![](https://file.jishuzhan.net/article/1759531464220741634/7f20b1be8517d5de3ec161117c06ccad.webp)的五次多项式f(x),并且给出了四个点和f(flag)以及p的值 显然恢复五次多项式需要知道6个点才行,但是题目的系数都是LCG产生的,而且LCG的模也是p 因此多项式的系数可以完美的表示为a b x 的组合 四个点能列出四个式子,以此便于恢复整个多项式,然后使用sage的roots()把flag找出即可 解联立的部分可使用sage的groebner basis exp: from Crypto.Util.number import * p = 8432316544210923620966806031040552674652729976238765323782536889706914762471638598119051165931563126522925761119650997703305509546949570434637437942542827 v_me_50 = [(1, 5237331460408741346823741966490617418367283531029963248255318507187035341590236835730694472064897540292182231844047116067936691956970631907605500080014355), (2, 5798977431976767515500795413771120575460553181185728489626756434911307088093739452469315524092208822863785429164219547384598943937099787390543171055679780), (3, 5030862375386942201139427367618716490378481408210696947331523552250206476805124204780313138835912303941204343248384742875319182761611109448446270069831113), (4, 4705360705603328842229554954026497175574981026785287316439514185860486128679614980330307863925942038530792583274904352630757089631411920876914529907563209)] f_flag = 7251453750672416392395590357197330390627853878488142305852099080761477796591562813165554150640801022882531891827653530623183405183605476913024545431842867 shu = [v[1] for v in v_me_50] P. = GF(p)[] def g(): global x x = a * x + b return x mu = [g() for _ in range(6)] print(mu) M = matrix.vandermonde([1, 2, 3, 4, 5, 6])[:-2] eqs = M * vector(mu) - vector(shu) I = P.ideal(list(eqs)) assert I.dimension() == 0 V = I.variety() sol = V[0] a = sol["a"] b = sol["b"] x = sol["x"] print(a, b, x) P. = PolynomialRing(GF(p)) f = g() + g() * X + g() * X ** 2 + g() * X ** 3 + g() * X ** 4 + g() * X ** 5 flag = (f - f_flag).roots()[0][0] print(flag) #10603559521836345227305379240054224406598915804878659960034174671004824270514372053024468093 print(long_to_bytes(flag)) #SICTF{Th3s_1s_a_high_l3vel_p0lyn0mial} ## \[进阶\]2024_New_Setback(10支队伍攻克) 题目 新的一年,我们总要有一个新的起点🕛,你们说对吧🎉! 出题人:Kicky_Mu #user:mumu666 from Crypto.Util.number import * from secret import flag, Curve def happy(C, P): c, d, p = C u, v = P return (u**2 + v**2 - c**2 * (1 + d * u**2*v**2)) % p == 0 def new(C, P, Q): c, d, p = C u1, v1 = P u2, v2 = Q assert happy(C, P) and happy(C, Q) u3 = (u1 * v2 + v1 * u2) * inverse(c * (1 + d * u1 * u2 * v1 * v2), p) % p v3 = (v1 * v2 - u1 * u2) * inverse(c * (1 - d * u1 * u2 * v1 * v2), p) % p return (int(u3), int(v3)) def year(C, P, m): assert happy(C, P) c, d, p = C B = bin(m)[2:] l = len(B) u, v = P PP = (-u, v) O = new(C, P, PP) Q = O if m == 0: return O elif m == 1: return P else: for _ in range(l-1): P = new(C, P, P) m = m - 2**(l-1) Q, P = P, (u, v) return new(C, Q, year(C, P, m)) c, d, p = Curve flag = flag.lstrip(b'SICTF{').rstrip(b'}') l = len(flag) l_flag, r_flag = flag[:l // 2], flag[l // 2:] m1, m2 = bytes_to_long(l_flag), bytes_to_long(r_flag) assert m1 < p and m2 < p P = (398011447251267732058427934569710020713094, 548950454294712661054528329798266699762662) Q = (139255151342889674616838168412769112246165, 649791718379009629228240558980851356197207) print(f'happy(C, P) = {happy(Curve, P)}') print(f'happy(C, Q) = {happy(Curve, Q)}') print(f'P = {P}') print(f'Q = {Q}') print(f'm1 * P = {year(Curve, P, m1)}') print(f'm2 * Q = {year(Curve, Q, m2)}') """ happy(C, P) = True happy(C, Q) = True P = (398011447251267732058427934569710020713094, 548950454294712661054528329798266699762662) Q = (139255151342889674616838168412769112246165, 649791718379009629228240558980851356197207) m1 * P = (730393937659426993430595540476247076383331, 461597565155009635099537158476419433012710) m2 * Q = (500532897653416664117493978883484252869079, 620853965501593867437705135137758828401933) """ 我的解答: **题目分析**: 本挑战是在给定曲线上有两对点的情况下,求解两次离散对数问题。但是,我们在执行此操作之前首先需要恢复曲线参数(c,d,p) 整个过程分为两部分:首先是恢复参数,然后将Edwards曲线映射为Weierstrass形式,以便我们使用sage求解。 **求解步骤:** **1、恢复曲线参数** 我们的目标是恢复(c,d,p),故我们可以重建曲线并求解离散对数。我们可以首先尝试获得p,然后可以采用反转模组p。需要恢复c,d 我们有关于c,d的曲线: ![](https://file.jishuzhan.net/article/1759531464220741634/7a5c77b9a7c4d0e82f435b6b381a66a9.webp) 因此我们知道任何一点(x~0~,y~0~)有: ![](https://file.jishuzhan.net/article/1759531464220741634/48aa5ce79449d6d18b12a6a7543f30bf.webp) 对于某个整数k~0~ 在曲线上取两个点,我们可以隔离dc^2^ ![](https://file.jishuzhan.net/article/1759531464220741634/dd679abe600c97856a57d512fa1ad870.webp) 目标是使用两个点来写出p的倍数,并执行此操作两次。然后我们可以从一对点的GCD恢复p 上述两式相减得到: ![](https://file.jishuzhan.net/article/1759531464220741634/0e88a69e3bb3f2421edc58705fd1636c.webp) 令 ![](https://file.jishuzhan.net/article/1759531464220741634/53ec7c6ea24cbfcaa8b9a6c7743d491c.webp) 有 ![](https://file.jishuzhan.net/article/1759531464220741634/564e30affea8630162ed6f10747f6572.webp) 同样对另一点也如此然后作差会得到p的倍数: ![](https://file.jishuzhan.net/article/1759531464220741634/ac93497512c742d89deba30a8e46576b.webp) 去分母得到: ![](https://file.jishuzhan.net/article/1759531464220741634/35c7a613134a38f02f3ba3dfdcc67462.webp) 最后,我们可以采取另一种组合以及使用最大公约数得到p: ![](https://file.jishuzhan.net/article/1759531464220741634/4ad34fc77b46a20e8839800321b0ad90.webp) 这里需要注意,我们得到的不是精确的p,而是p的倍数,但是我们可以通过分解来得到精确的p 有了p我们再回到上面的表达式从而计算c^2^d ![](https://file.jishuzhan.net/article/1759531464220741634/8b3ca7123ede58b9b918d5519f4e2fb1.webp) 有了这个我们就可以回到曲线上的任何一点并写出: ![](https://file.jishuzhan.net/article/1759531464220741634/25c18f14fd7d56c662ebec97da700e85.webp) 在已知所有曲线参数的情况下,我们可以继续求解离散对数 exp1: from math import gcd def happy(C, P): """ Verification points are on the curve """ c, d, p = C u, v = P return (u**2 + v**2 - cc * (1 + d * u**2*v**2)) % p == 0 def a_and_b(u1,u2,v1,v2): """ Helper function used to simplify calculations """ a12 = u1**2 - u2**2 + v1**2 - v2**2 b12 = u1**2 * v1**2 - u2**2 * v2**2 return a12, b12 def find_modulus(u1,u2,u3,u4,v1,v2,v3,v4): """ Compute the modulus from four points """ a12, b12 = a_and_b(u1,u2,v1,v2) a13, b13 = a_and_b(u1,u3,v1,v3) a23, b23 = a_and_b(u2,u3,v2,v3) a24, b24 = a_and_b(u2,u4,v2,v4) p_almost = gcd(a12*b13 - a13*b12, a23*b24 - a24*b23) for i in range(2,1000): if p_almost % i == 0: p_almost = p_almost // i return p_almost def c_sq_d(u1,u2,v1,v2,p): """ Helper function to computer c^2 d """ a1,b1 = a_and_b(u1,u2,v1,v2) return a1 * pow(b1,-1,p) % p def c(u1,u2,v1,v2,p): """ Compute c^2, d from two points and known modulus """ ccd = c_sq_d(u1,u2,v1,v2,p) cc = (u1**2 + v1**2 - ccd*u1**2*v1**2) % p d = ccd * pow(cc, -1, p) % p return cc, d P = (398011447251267732058427934569710020713094, 548950454294712661054528329798266699762662) Q = (139255151342889674616838168412769112246165, 649791718379009629228240558980851356197207) m1P = (730393937659426993430595540476247076383331, 461597565155009635099537158476419433012710) m2Q = (500532897653416664117493978883484252869079, 620853965501593867437705135137758828401933) u1, v1 = P u2, v2 = Q u3, v3 = m1P u4, v4 = m2Q p = find_modulus(u1,u2,u3,u4,v1,v2,v3,v4) cc, d = c(u1,u2,v1,v2,p) C = cc, d, p assert happy(C, P) assert happy(C, Q) assert happy(C, m1P) assert happy(C, m2Q) print(f'Found curve parameters') print(f'p = {p}') print(f'c^2 = {cc}') print(f'd = {d}') #Found curve parameters #p = 903968861315877429495243431349919213155709 #c^2 = 495368774702871559312404847312353912297284 #d = 540431316779988345188678880301417602675534 **2、转换为Weierstrass形式** 已知曲线后,我们要做的就是解爱德华兹曲线上的离散对数问题。可以通过使用Pohlih-Hellman和BSGS来完成。但相反,我们将Edwards曲线映射到Weierstrass,并在构建的dlog中使用sage来求解。可能有更好的方法来进行这种转换。这里我们使用已知的映射从Edwards到Montgomery形式再到Weierstrass形式。。 我们从爱德华兹曲线开始: ![](https://file.jishuzhan.net/article/1759531464220741634/49bf9faaa9bd85c4d2fa12517bb43a0a.webp) 这是个不太常见的形式带有因子c,因此我们需要进行放缩(x,y,d)来去除c: ![](https://file.jishuzhan.net/article/1759531464220741634/cbb54cf8f6520f29ebbe18f24e021434.webp) 目的是为了获得更熟悉的Edwards曲线: ![](https://file.jishuzhan.net/article/1759531464220741634/b0e1a4e08d99dbac6cfb7c85055b647f.webp) 注意:这里指的是(x,y,d)使用相同的标签,以免感到困惑。 在这种我们更熟悉的曲线下,引用将曲线映射到蒙哥马利曲线: ![](https://file.jishuzhan.net/article/1759531464220741634/628fa5b5f6938a183c22fe802d9ee220.webp) 该曲线里存在因素B,但我不知道如何使用sage创建这条曲线(也许是可以创建的?)此映射是通过坐标变换来完成的: ![](https://file.jishuzhan.net/article/1759531464220741634/521a08ceba9b1a961a8944b852b30017.webp) 曲线参数由下式关联: ![](https://file.jishuzhan.net/article/1759531464220741634/199cae64d7722caa2009f0ffcc2c3fda.webp) 最后,我们可以将这条曲线转换为Weierstrass形式(方程取自: ) ![](https://file.jishuzhan.net/article/1759531464220741634/01399efa00c00fc5aaa18898cf7154a3.webp) 进行坐标变换: ![](https://file.jishuzhan.net/article/1759531464220741634/157b13602d7162e53642b37903a39cb2.webp) 曲线参数由下式关联: ![](https://file.jishuzhan.net/article/1759531464220741634/9804b39504731c4d3ab4097a5a011eed.webp) 在这种形式下,我们可以使用sage将点带入曲线并求解离散对数。实现方式如下: exp2: from Crypto.Util.number import * # Recovered from previous section p = 903968861315877429495243431349919213155709 F = GF(p) cc = 495368774702871559312404847312353912297284 c = F(cc).sqrt() d = 540431316779988345188678880301417602675534 # Point data from challenge P = (398011447251267732058427934569710020713094, 548950454294712661054528329798266699762662) Q = (139255151342889674616838168412769112246165, 649791718379009629228240558980851356197207) m1P = (730393937659426993430595540476247076383331, 461597565155009635099537158476419433012710) m2Q = (500532897653416664117493978883484252869079, 620853965501593867437705135137758828401933) x1, y1 = P x2, y2 = Q x3, y3 = m1P x4, y4 = m2Q R. = PolynomialRing(F) g = (x^2 + y^2 - cc * (1 + d * x^2*y^2)) # Check the mapping worked! assert g(x=x1, y=y1) == 0 assert g(x=x2, y=y2) == 0 assert g(x=x3, y=y3) == 0 assert g(x=x4, y=y4) == 0 # Scale: x,y,d to remove c: # x^2 + y^2 = c^2 * (1 + d * x^2*y^2) # to: # x^2 + y^2 = (1 + d * x^2*y^2) d = F(d) * F(cc)^2 x1, y1 = F(x1) / F(c), F(y1) / F(c) x2, y2 = F(x2) / F(c), F(y2) / F(c) x3, y3 = F(x3) / F(c), F(y3) / F(c) x4, y4 = F(x4) / F(c), F(y4) / F(c) h = (x^2 + y^2 - (1 + d * x^2*y^2)) # Check the mapping worked! assert h(x=x1, y=y1) == 0 assert h(x=x2, y=y2) == 0 assert h(x=x3, y=y3) == 0 assert h(x=x4, y=y4) == 0 # Convert from Edwards to Mont. # https://safecurves.cr.yp.to/equation.html def ed_to_mont(x,y): u = F(1 + y) / F(1 - y) v = 2*F(1 + y) / F(x*(1 - y)) return u,v u1, v1 = ed_to_mont(x1, y1) u2, v2 = ed_to_mont(x2, y2) u3, v3 = ed_to_mont(x3, y3) u4, v4 = ed_to_mont(x4, y4) e_curve = 1 - F(d) A = (4/e_curve - 2) B = (1/e_curve) # Mont. curve: Bv^2 = u^3 + Au^2 + u R. = PolynomialRing(ZZ) f = B*v^2 - u^3 - A* u^2 - u # Check the mapping worked! assert f(u=u1, v=v1) == 0 assert f(u=u2, v=v2) == 0 assert f(u=u3, v=v3) == 0 assert f(u=u4, v=v4) == 0 # Convert from Mont. to Weierstrass # https://en.wikipedia.org/wiki/Montgomery_curve a = F(3 - A^2) / F(3*B^2) b = (2*A^3 - 9*A) / F(27*B^3) E = EllipticCurve(F, [a,b]) # https://en.wikipedia.org/wiki/Montgomery_curve def mont_to_wei(u,v): t = (F(u) / F(B)) + (F(A) / F(3*B)) s = (F(v) / F(B)) return t,s X1, Y1 = mont_to_wei(u1, v1) X2, Y2 = mont_to_wei(u2, v2) X3, Y3 = mont_to_wei(u3, v3) X4, Y4 = mont_to_wei(u4, v4) P = E(X1, Y1) Q = E(X2, Y2) m1P = E(X3, Y3) m2Q = E(X4, Y4) # Finally we can solve the dlog s = P.discrete_log(m1P) t = Q.discrete_log(m2Q) # This should be the flag, but s is broken print(long_to_bytes(s)) print(long_to_bytes(t)) #b'\x05\x9e\x92\xbfO\xdf1\x16\xb0>s\x93\xc6\xc7\xe7\xa3\x80\xf0' #b'Ds_3LlipT!c_CURv3' # We have to do this, as we picked the wrong square-root. print(long_to_bytes(s % Q.order())) print(long_to_bytes(t)) #b'nOt_50_3a5Y_Edw4r' #b'Ds_3LlipT!c_CURv3' #SICTF{nOt_50_3a5Y_Edw4rDs_3LlipT!c_CURv3} # MISC ## 真💨签到(39支队伍攻克) 题目 月月最近玩了一款新的游戏:无尽的拉格朗日。她觉得实在是太好玩了!很想推荐给大家\~ 出题人:Kicky_Mu 我的解答: 首先打开压缩包,发现带有密码。010查看一下文件尾有一串16进制,嘿嘿 5456545454565458414259555854585458434152595958415a435959595558563d 解码得到 TVTTTVTXABYUXTXTXCARYYXAZCYYYUXV= 看似base却不是(解不出来),发现密文只有字母,猜测是字母加密: 在线解码: 得到:2024HappyNewYear 这个就是压缩包密码了,解压得到一个图片和一个WAV文件 Audacity音频分析wav文件,查看频谱图发现一段信息: ![](https://file.jishuzhan.net/article/1759531464220741634/69ba68e502ad3aba9253d17b3deb39d4.webp) 一眼丁真肯定是图片隐写密码,猜测是steghide隐写,输入密码解密得到: steghide extract -sf steg.jpg Enter passphrase: steghide: could not extract any data with that passphrase! 得不到结果。。why? 思路应该没问题密码肯定也不会错。我们仔细思索发现wav文件名有问题 LagrangeisCapatlized 有经验的话这里可以猜测拉格朗日要大写?Capatlized?也不是大写字母单词拼写啊?哈哈哈?这里其实是个小彩蛋需要点脑洞。发挥师傅们的想象力还是可以猜测出来的。当然有道词典或者其他词典搜索这个单词会识别出你想要找的单词。这样一来我们就知道确实需要大写了 ![](https://file.jishuzhan.net/article/1759531464220741634/5c9b4ffa84a326bd0f2f1ad7121afd78.webp) OK!我们把密码改为:givemeyourLAGRANGE 再次解码得到: steghide extract -sf steg.jpg Enter passphrase: wrote extracted data to "flag.txt". 打开flag.txt得到: SICTF{T3e_endless_Lagrange_is_really_fun!} ## New Year's regret(14支队伍攻克) 题目 2024 月月经历了一些遗憾的事,她没能帮树木解决物理难题,愧疚气愤之下就把旗帜给拆的七零八落,聪明的你可以找到它们吗? 出题人:Kicky_Mu hint1:月月在设置压缩包密码的时候不小心把一些内容弄脏了,依稀记得格式是xxxxSICTF,丢掉了什么呢?让我想想。。呜呜呜\~记不清了呜呜呜 hint2:其中有一部分你知道是几星吗? 我的解答: 根据提示,压缩包掩码攻击得到密码:2024SICTF(当然猜也能猜出来。。。。) ![](https://file.jishuzhan.net/article/1759531464220741634/0419e25a1ef35be335a03b72b14d7a73.webp) 解压得到一个txt文件和一个汉信码,先看看txt文件是哈?一堆01,一眼丁真01画图。但需要知道x,y坐标。010分析附件压缩包文件尾发现 43637d135333 hex解码无果,逆一下再解码试试 得到:351×64 s = '43637d135333' print(s[::-1]) #333531d73634 这样一来就可以画图了: from PIL import Image MAX1 = 351 MAX2=64 pic = Image.new("RGB",(MAX1, MAX2)) str = "这里把txt文件内容复制进来" i = 0 for y in range (0,MAX2): for x in range (0,MAX1): if(str[i] == '1'): pic.putpixel([x,y],(0, 0, 0)) else: pic.putpixel([x,y],(255,255,255)) i = i+1 pic.show() pic.save("flag.png") 得到图片: ![](https://file.jishuzhan.net/article/1759531464220741634/dda876705c0fd10e69c6d8fb53bb5b3c.webp) [music-sheet-cipher](https://www.dcode.fr/music-sheet-cipher)解码得到flag一部分:putitalltogether ![](https://file.jishuzhan.net/article/1759531464220741634/ec8f08e8fb64829ba9744b76483f6f75.webp) 扫描汉信码被嘲讽了。。。010分析发现里面有压缩包和png图片 kali分离(foremost指令) 压缩包解压得到base64,解码发现是base64循环: #脚本 import re from base64 import b64decode def process_data(data): try: # 删除包含'flag'或汉字字符的部分 data = re.sub(r'flag|[一-龥]', '', data) # 进行Base64解码 decoded_data = b64decode(data) return decoded_data.decode(), True except: # 如果无法解码,返回原始数据和False表示无法继续解码 return data, False # 读取文本文件内容 with open('flag_new.txt', 'r', encoding='utf-8') as file: data = file.read() iterations = 0 # 循环处理数据,直到无法继续解码 while True: data, can_decode = process_data(data) iterations += 1 # 如果无法继续解码,输出结果并结束循环 if not can_decode: print("最终结果:", data) print("循环次数:", iterations) break 得到: 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 循环次数: 35 结果形式一看就知道是base64转图片,可得到二维码,解码得到:SICTF{Congratulation_to_you! ![](https://file.jishuzhan.net/article/1759531464220741634/8940d18c2d31dd974ad06a4ff44d6625.webp) 还有最后一张图片需要分析: ![](https://file.jishuzhan.net/article/1759531464220741634/791a82396611e957b25b76147b410467.webp) 根据题目提示:其中有一部分你知道是几星吗?猜测可能是武器星级 识图发现是游戏战双帕弥什里面的装备,找一下图签: [战双帕弥什武器图签](https://wiki.biligame.com/zspms/%E6%AD%A6%E5%99%A8) 按提示查找它们的星级,最终得到结果如下: 44664654464566654465645644544664654654644546445446646565444454544664654664544545646454544454466465465645644 发现只有三种数字考虑到摩斯密码:4换成"." 6换成"-" 5换成空格 ..--.- ..-. --- ..- -. -.. ..--.- .- .-.. .-.. ..--.- - .... . ..--.- .--. .. . -.-. . ... ..--.- .- -. -.. 解码得到: _FOUND_ALL_THE_PIECES_AND 改为小写字母:_found_all_the_pieces_and 最后把三部分拼接即可: SICTF{Congratulation_to_you!_found_all_the_pieces_and_put_it_all_together} # OSINT ## 树木的压迫(143支队伍攻克) 题目 因为树木觉得社工过于简单,所以整了一道抽象的社工。 (flag格式:SICTF{x省_x市_x区_x(街道名)×号_xx},没有空格等特殊符号) 出题人:@余 ![](https://file.jishuzhan.net/article/1759531464220741634/61dcfd7fad6079e83dd8951564ae1e2c.webp) 我的解答: 这道题属实是国内社工签到了。年前正好去了一趟四川省达州市凤凰山游玩 在红军亭顶峰拍了一张市全景图,感觉还不错就发给了余正好拿来社工。哈哈哈! 解法也很简单,百度识图可知道是四川省达州市凤凰山 百度地图搜索此地,图层换成卫星图,进行放缩旋转可发现图中标记地点。 ![](https://file.jishuzhan.net/article/1759531464220741634/b8fff025a8972f8bcdefe655c8e31199.webp) 点击达州市体育中心这个位置便可弹出具体信息: SICTF{四川省_达州市_通川区_凤凰大道376号_达州市体育中心} ![](https://file.jishuzhan.net/article/1759531464220741634/d369f370a67cce984061b9427182099e.webp)