HSCTF ZmxhZw==队 Csome‘s writeup
Misc
修复后的签到题
扫码获取flag
base64
是真的靠眼睛
ichizero
FL studio 永远的神
HSCTF{ISSHONIIIKOANOSEKAIHE}
Web
signin
简单的302
Pwn
guess
猜数字是不可能猜数字的(虽然我还爆破了一下)
开个IDA
曾经我的写数组是,下表填了负数,现在…只有负下标有用
0x80 - 0x64 = 28
28 / 4 = 7
一直输入-7
取到change=1 == 1是就可以了
PwnMe
这题要构建有限字符数量的shellcode
先checksec
太开放了吧
上IDA
main函数
没有system
也没有/bin/sh
没有RElRO不是FULL
那就想到发送shellcode
buf再bss段上
考虑跳转到buf上并执行shellcode
现在就是要个32字符内的shellcode
上网找
http://shell-storm.org/shellcode/
\x6a\x42\x58\xfe\xc4\x48\x99\x52\x48\xbf
\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54
\x5e\x49\x89\xd0\x49\x89\xd2\x0f\x05
构造exp
运行
搞定
Reverse
Base64
用linux运行一下
zMXHz3TKzwrMnZnLys03mJuYltq4otiTyJG4mI05otKYnZa4zJbMnJj9
欸,有点眼熟,我们队名叫ZmxhZw==,是由flag进行base64加密来的
这个zMXHz也太像了吧,只有一点不同,大小写转换了一下
写个exp
运行
base64解密
flag到手
Magic_switch
用ExeinfoPE分析一下
64位,拖入IDA
直接看secret
数据源
计算方法
写个exp
不知道为什么最后老是会越界,推测少了个g
Re_is_reaIIy_e4sy_and_int3rest1ng
搞定
Bytecode
就硬翻
死磕python字节码-手工还原python源码
再运用import dis
调试
def foo1(s):
arr = [51, 42, 67, 2, 100, 48, 94, 29, 25, 26, 9, 43, 25, 21, 53, 11, 11, 91, 0, 12, 14, 19, 122, 0, 44, 26, 58, 26, 28, 24, 50, 3, 93, 21]
if s == arr:
return True
else:
return False
def foo2(s):
arr1 = list(map(ord, s))[::-1]
print(arr1)
arr2 = [74, 117, 115, 116, 84, 111, 111, 108, 109, 97, 110]
for i in range(len(arr1)):
arr1[i] ^= arr2[i % 11]
return arr1
def foo3(s):
#将s反转
a = 1
b = -6
c = len(s) - 33
a = (a + 2 * c) * 3 + (4 * c)
b = (b + 2 * a) + 4 * c + c
return s[b:a:-1] + s[:b:-1] + s[:a + 1]
def main():
flag = input('No Flag No Entry <(_^_)>:\n')
if len(flag) == 34 and foo1(foo2(foo3(flag))):
print('\nAcc3pTed: You g0t iT! :D')
else:
print('\nErr0r: Unm4tched str1ng. :/')
main()
逆向
def foo1(s):
arr = [51, 42, 67, 2, 100, 48, 94, 29, 25, 26, 9, 43, 25, 21, 53, 11, 11, 91, 0, 12, 14, 19, 122, 0, 44, 26, 58, 26, 28, 24, 50, 3, 93, 21]
arr2 = [74, 117, 115, 116, 84, 111, 111, 108, 109, 97, 110]
for i in range(len(arr)):
arr[i] ^= arr2[i % 11]
print(chr(arr[i]), end='')
if s == arr:
return True
else:
return False
得到
y_0v0_1qt{galfA_d4lao}0u_nnust_b3_
再foo3逆向就可解出flag(也可以猜一猜题意
flag{tq1_0v0_y0u_nnust_b3_A_d4lao}
tql you must be a dalao
Maze
迷宫?
模拟一下
map = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1,
0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1,
0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
print(len(map))
def showmap():
global map
for i in range(256):
if i % 16 == 0 and i != 0:
print()
# print(map[i],end=' ')
if map[i] == 1:
print("@", end=' ')
elif map[i] == 0:
print('.', end=' ')
elif map[i] == 2:
print('#', end=' ')
print()
def isnotzreo(v8, v7):
global map
if map[16 * v8 + v7] == 0:
map[16 * v8 + v7] = 2
return False
else:
return True
flag = ''
inp = ''
v8 = 13
v7 = 0
def move(c):
global flag
global v8, v7
if c == 'l':
v7 += 1
if isnotzreo(v8, v7):
v7 -= 1
else:
flag += c
# return True
elif c == 'k':
v8 -= 1
if isnotzreo(v8, v7):
v8 += 1
else:
flag += c
# return True
elif c == 'h':
v7 -= 1
if isnotzreo(v8, v7):
v7 += 1
else:
flag += c
# return True
elif c == 'j':
v8 += 1
if isnotzreo(v8, v7):
v8 -= 1
else:
flag += c
# return True
else:
return False
c = ''
while c != '\n':
showmap()
c = str(input())
move(c)
showmap()
print(flag)
#flagl = 'flag{llllkkkhhhkkkkkkkkklllljjjjllljjljjjjjjjlllkkkklljjjl}'
#print(len(flagl))
有兴趣的可以运行一下
搞定
funny_game
先用IDA分析一下
有个getflag
代码审计
有个全局变量
录入python写个exp(我是用excel录入的,毕竟手上工具不多)
exp
v10 = [0x6E,0x94,0x61,0x6F,0x9B,0x71,0x9D,0x51,0x9C,0x6D,0x67,0x61,0x67,0x6E,0x9D,0x96,0x96,0x99,0x67,0x6F,0x5C,0x95,0x6D,0x67,0x69,0x93,0x96,0x7C,0x67,0x69,0x9C,0x85]
v1 = [0 for i in range(32)]
print(len(v10))
for i in range(32):
v1[i] ^= v10[i]
v1[i] ^= 0x14
v1[i] -= 20
print(bytes(v1).decode())
nice!!
Crypto
cbc
乍一看,好难,cbc,什么鬼
面向百度,搜索,找出一堆字符反转攻击,但这个都是建立在知道key或是可以得到用key在加密一次的密文
但这一题,加密过程不可复制
先审计代码
from Crypto.Cipher import AES
from secret import key, flag
from base64 import b64decode,b64encode
admin = b'{name:admin}\x00\x00\x00\x00'
plain = b'{name:f2ng}\x00\x00\x00\x00\x00'
iv = b'try it,get flag!'
enc = AES.new(key, AES.MODE_CBC, iv)
cipher = enc.encrypt(plain)
print(b64encode(cipher).decode())
# HYrjg5jJAqBqxN/8/dlayw==
assert(len(flag) == 30)
assert(flag[:5] == 'flag{')
assert(flag[-1] == '}')
new_iv = b64decode(flag[5:-1])
enc = AES.new(key, AES.MODE_CBC, new_iv)
token = enc.decrypt(cipher)
if token == admin:
print("GET FLAG!")
print(flag)
with open('hintForXor.py', 'rb') as r, open('hintForXor', 'wb')as w:
key = b'1234567890abcdef'
enc = AES.new(key, AES.MODE_CBC, new_iv)
p = r.read()
p += b'\x00' * (16 - len(p) % 16)
c = enc.encrypt(p)
w.write(c)
else:
print("ERROR,not admin")
逻辑大概是这样,用cbc的模式,加密plain(key未知,iv已知)
得到的密文在用base64加密
绿色表示是可知的,那不是很简单了
admin = b'{name:admin}\x00\x00\x00\x00'
plain = b'{name:f2ng}\x00\x00\x00\x00\x00'
iv = b'try it,get flag!'
设key_encode是用key加密后的密文
则有
抽象成式子
key_encode = plain ^ iv
key_encode = admin ^ new_iv
new_iv = base64_decode(flag)
那么就可以有
plain ^ iv = admin ^ new_iv
admin ^ plain ^ iv = admin ^ admin ^ new_iv
admin ^ plain ^ iv = new_iv
flag = base64_encode(new_iv)
ok,开始写exp
admin = b'{name:admin}\x00\x00\x00\x00'
plain = b'{name:f2ng}\x00\x00\x00\x00\x00'
iv = b'try it,get flag!'
admin = list(admin)
plain = list(plain)
iv = list(iv)
print(iv)
print(bytes(iv))
for i in range(16):
iv[i] ^= plain[i]
iv[i] ^= admin[i]
print(b64encode(bytes(iv)).decode())
结果
搞定
xor
先审计代码
文件xor.py
import os
from base64 import b64encode
from secret import flag
assert(flag.startswith(b'flag'))
k1 = os.urandom(10)
k2 = os.urandom(21)
def xor(p,k):
p = list(p)
for i in range(len(p)-1):
p[i] ^= k[i % len(k)]
return b64encode(bytes(p))
with open('hintForCBC.py','rb') as r, open('cipher','wb') as w:
hint = r.read()
p = flag + hint
c1 = xor(p, k1)
c2 = xor(p, k2)
w.write(b'%s\n%s\n' % (c1, c2))
文件cipher
c1= iUcEVflhi4gS9YpPAB/mZoSPDKPXSVUf4zCDgAyv3klQBrBhgY0QoN5WA0DtPJP6U+6fXwocwTjD0UTlz0IIQu0jx5lg0rwhA0DtPJPbQOSKHVES6zzD1lPjz0lTBuc/0NZF8sNJUwbmNNDWRfLlIRAComyT2wbxikUCbvphg+VZp993HQKyDcuJEcuXG1Vu+mGD5Vmn33cdArINy4kRy5cbVW76YYPlWaffDG9Hs3GOmUOwiRoLVd4pg4l9798bOUqyYe/BEaezU1UC3imDiX3v3xs5SrJh78ERp7NTVQLeKYOJfe/fG0I492OThAH1yE1XXOUNy4kRy5cbVW76YYPlWaffdx0Csg3LiRHLlxtVbvphg+VZp993HQKyDcuJEcuXG1UViFvY3Fi30gsHFbNjgI0UodgTXALjM9DdRPHIIRFd6TTdmRy3jQwGRtMU3+kRxItdP1CzNoOAbPjXGhNzv2yUsyv+mQtYEuB2gosSo9odUgq7YdLbQvOKTUI45z/QmRy3rm42HOw0xJFK8pYHJHfRf/72ZdKwaCdxrjjFkCvn3wtYEuc/0JdF8oxZHEL2edGPFfOKSApW53nH1krygQJMOIg4xZkct40MVFSxZYaPFq/WGwRQ4TXW3wadikUGEr9x8vxyuYFOEhrpNMqVYNK8BSh9xhTs+mPUw0ITG4ghgpkct4pFBhzmNNDLWOebAwcEtjXW2k7zigMRXek03ZAIneVCExK/cdGeEPLcH1AEtWmKiUD1jE8AVKVb1tdCt9ILJHfRf93cVr+EThwewxTgl2zYq246ccASn9BXvuVbVxK/cdbXQrmLTgZA+yHHkUOh208AUe011pFV+IROCxurW7nYUuSKWREa8mGThBy3mhtMOOMiwNxT48dbVBK/bJPMEL7lShZB5yPHkVGlzxZYEvdjmrMr/pkLWBLgdoWKEa20HVIKu2HS20Lzik1COOc/0Jkct65uNhzsNMSRSvKWByR30X/+9mXSsGgnca44xZAr59YSRQ+iNN3aD/OKSBdL8iWb2xeji04GXeY0m81O/IpFTBuIW9LKUvKdX01QpTDX1Ej5yAsMXKIhioAp
c2= 1ijSnzmvbQlxljwZoA8o7g6Fh6Zr0nSemSOvbBV6xTtI8RB86w2CnaMu1jbclWLcJ0EygDZThks8sVzBivs+wCvBjGLeEGtIkisSqAIuuErWnKZz2SnDlzDrdVp0wDwTpk0ovBXRnKY31SfcnCeVX01y1GRdpwUqvFfU9upjgBjLyHLDLQhyqCFN9X406Qnv0qJj7DyDyB7nZQgejGlNmVp86WXLmqIPyHSD30jqZBh/1DtaoxMivmXLmqIPyHSDpDqvZWQ6xGkhvRJ8hUGDms4rgHTvgHKvCUByxAUF9RIQoQmD9upjgGO5jXC/aBgg0z9Pq0UQoQmD9upjgBjLyHLDLQhyqCFN9X406Qnv0qJj7DyDyB7nZQgejGlNmVp86WXLmqJ0uk7YnTu/aBgg02hP9hZ57w6Lk6Iy0ifXnSS4X0wtnzwT5R9sux7Q3sMW3BSDqybpD1pzk2lEiE106E/yl690uk7ajmKidVplxWtO8Rd67gGKmvMx0yDWnmWVMFYh1GRdhGcf91fW3bo41T2fuQfMe3UNsBwihmAP9VDFg5gjgGSO2CfxNhYmkToPvFI48VuFnvY20yvXnWrrOlMnmnBUzyglrxmOivB0gSKAzHepYgB7xDgfpkYpvx65z/wwkHmTuQfMe1Yng3EWoFtgmHzghN8c9AHsuwDceVE03VMN9AJx+Vzdybw31SfBgTLrfVp0wD0Ypk0ovBHHxfk23m2a8kj2Ixh/1Dta9Ed/7QyFnapqgCXRmyb6Mx9IkTce5R9smHzghPw2x2zYnTuzFH0R2hQygWcTmnvwhvslmU7DymKidV0sl3cZoEE+oEnHgvBlhCDWmy37MBA2mzIYqwtl0zPS2eE2wjCbiHK/aAVigWlUz0M/qlzB3rojgWSOxWLqZBFIlSoOoFA48UmBiq9ukDGB0UiVPE5iyXkf4hR/6QPonKVriXTSmiH7MF5l/jwTpgJx+Xj2+bw91TObkyfmeXkHp3cwimYJhnrx6b46xm25iHumdQVikTce60YpukvK2uZ70nKHnCf8Olwn3C0Srkci8BC5oPMgwyHBjGr9clkmmTAT4gIltxnDk6sp
整理已知
len(k1) = 10
len(k2) = 21
c1,c1
抽象为式子
i从0到len(c1)(len(c2))
c1[i] = k1[i % 10] ^ p[i]
c2[i] = k2[i % 21] ^ p[i]
则有
c2[i] ^ c1[i] = k1[i % 10] ^ k2[i % 21]
k = [0 for i in range(len(c1))]
for i in range(len(c1)):
k[i] = c1[i] ^ c2[i]
k1[i % 10] ^ k2[i % 21]
这个是循环体长度为210的循环列表
由于len(k1) = 10,len(k2) = 21
互素就可以求出所有k2中元素与k1[0]异或的值
while i <= 209:
k10k2[i % 21] = kn[i]
i += 10
k10k2 = [116, 114, 121, 32, 105, 116, 44, 103, 101, 116, 32, 102, 108, 97, 103, 33]
猜测一波
p[0] = 'f'
c1[0] = k1[0] ^ 'f'
尝试一下
写个exp
from base64 import b64decode,b64encode
line1 = c1(上文的c1)
line2 = c2(上文的c2)
c1 = b64decode(line1)
c2 = b64decode(line2)
c1 = list(c1)
c2 = list(c2)
k = [0 for i in range(len(c1))]
for i in range(len(c1)):
k[i] = c1[i] ^ c2[i]
print(k[:210])
print(k[210:])
print(len(k))
kn = k[:210]
k10k2 = [0 for i in range(21)]
i = 0
while i <= 209:
k10k2[i % 21] = kn[i]
i += 10
print(k10k2)
k1ey = c1[0] ^ ord('f')
for i in range(21):
k10k2[i] ^= k1ey
# print(chr(k10k2[1] ^ c2[1]))
def xor(p,k):
p = list(p)
for i in range(len(p)-1):
p[i] ^= k[i % len(k)]
return bytes(p)
p = xor(c2,k10k2)
print(p.decode())
flag到手