有幸参与了本次比赛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 = m^e1^ mod n
c2 = m^e2^ 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.<X> = 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生成了一个的五次多项式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.<a, b, x> = 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.<X> = 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的曲线:
因此我们知道任何一点(x~0~,y~0~)有:
对于某个整数k~0~ 在曲线上取两个点,我们可以隔离dc^2^
目标是使用两个点来写出p的倍数,并执行此操作两次。然后我们可以从一对点的GCD恢复p
上述两式相减得到:
令
有
同样对另一点也如此然后作差会得到p的倍数:
去分母得到:
最后,我们可以采取另一种组合以及使用最大公约数得到p:
这里需要注意,我们得到的不是精确的p,而是p的倍数,但是我们可以通过分解来得到精确的p
有了p我们再回到上面的表达式从而计算c^2^d
有了这个我们就可以回到曲线上的任何一点并写出:
在已知所有曲线参数的情况下,我们可以继续求解离散对数
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形式。。
我们从爱德华兹曲线开始:
这是个不太常见的形式带有因子c,因此我们需要进行放缩(x,y,d)来去除c:
目的是为了获得更熟悉的Edwards曲线:
注意:这里指的是(x,y,d)使用相同的标签,以免感到困惑。
在这种我们更熟悉的曲线下,引用https://safecurves.cr.yp.to/equation.html将曲线映射到蒙哥马利曲线:
该曲线里存在因素B,但我不知道如何使用sage创建这条曲线(也许是可以创建的?)此映射是通过坐标变换来完成的:
曲线参数由下式关联:
最后,我们可以将这条曲线转换为Weierstrass形式(方程取自:https://en.wikipedia.org/wiki/Montgomery_curve https://www.ams.org/journals/mcom/1987-48-177/S0025-5718-1987-0866113-7/S0025-5718-1987-0866113-7.pdf https://www.jianshu.com/p/5dba044f67b1)
进行坐标变换:
曲线参数由下式关联:
在这种形式下,我们可以使用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.<x,y> = 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.<u,v> = 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却不是(解不出来),发现密文只有字母,猜测是字母加密:
在线解码:https://www.qqxiuzi.cn/bianma/wenbenjiami.php?s=zimu
得到:2024HappyNewYear
这个就是压缩包密码了,解压得到一个图片和一个WAV文件
Audacity音频分析wav文件,查看频谱图发现一段信息:
一眼丁真肯定是图片隐写密码,猜测是steghide隐写,输入密码解密得到:
steghide extract -sf steg.jpg
Enter passphrase:
steghide: could not extract any data with that passphrase!
得不到结果。。why? 思路应该没问题密码肯定也不会错。我们仔细思索发现wav文件名有问题
LagrangeisCapatlized
有经验的话这里可以猜测拉格朗日要大写?Capatlized?也不是大写字母单词拼写啊?哈哈哈?这里其实是个小彩蛋需要点脑洞。发挥师傅们的想象力还是可以猜测出来的。当然有道词典或者其他词典搜索这个单词会识别出你想要找的单词。这样一来我们就知道确实需要大写了
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(当然猜也能猜出来。。。。)
解压得到一个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")
得到图片:
music-sheet-cipher解码得到flag一部分:putitalltogether
扫描汉信码被嘲讽了。。。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!
还有最后一张图片需要分析:
根据题目提示:其中有一部分你知道是几星吗?猜测可能是武器星级
识图发现是游戏战双帕弥什里面的装备,找一下图签:
按提示查找它们的星级,最终得到结果如下:
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},没有空格等特殊符号)
出题人:@余
我的解答:
这道题属实是国内社工签到了。年前正好去了一趟四川省达州市凤凰山游玩
在红军亭顶峰拍了一张市全景图,感觉还不错就发给了余正好拿来社工。哈哈哈!
解法也很简单,百度识图可知道是四川省达州市凤凰山
百度地图搜索此地,图层换成卫星图,进行放缩旋转可发现图中标记地点。
点击达州市体育中心这个位置便可弹出具体信息:
SICTF{四川省_达州市_通川区_凤凰大道376号_达州市体育中心}