window.onload=function(){ /*页面加载完成之后生成博客目录*/ BlogDirectory.createBlogDirectory("cnblogs_post_body","h2","h3",20); }

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

[(c1x) mod n] * [(c2y) mod n] = (me1*x+e2*y) mod n = m5ax+5by mod n = m5 mod n

因此,便得到m5 最后使用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的曲线:

因此我们知道任何一点(x0,y0)有:

对于某个整数k0 在曲线上取两个点,我们可以隔离dc2

目标是使用两个点来写出p的倍数,并执行此操作两次。然后我们可以从一对点的GCD恢复p

上述两式相减得到:

 

同样对另一点也如此然后作差会得到p的倍数:

去分母得到:

最后,我们可以采取另一种组合以及使用最大公约数得到p:

这里需要注意,我们得到的不是精确的p,而是p的倍数,但是我们可以通过分解来得到精确的p

有了p我们再回到上面的表达式从而计算c2d

有了这个我们就可以回到曲线上的任何一点并写出:

在已知所有曲线参数的情况下,我们可以继续求解离散对数

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号_达州市体育中心}

 

posted @ 2024-02-19 18:47  Kicky_Mu  阅读(519)  评论(0编辑  收藏  举报