在NSS上做了两道 希望能给想要WP但网上找不到的师傅一点帮助~
穿越反恐火线精英
题目描述:花指令confusion既是CS也是CF
确实一大堆花指令 这种jz/jnz可以用idapython去掉
start = 0x400000
end = 0x403AD8
while start<end:
if((get_wide_byte(start)==0x74) and (get_wide_byte(start+2)==0x75)):
ida_bytes.patch_byte(start+4,0x90)
start += 1
print("[+] OK !")
但只是这么去也去不干净...
后面有一大堆没有识别的代码 稍微patch不好就容易识别错关键代码
注意到这里
这里可以动态调试几组 在memcmp下断点
比如我输入1234+14*'0' 得到
[0x01, 0x5B, 0x51, 0xD5, 0x36, 0xB6, 0x9C, 0xF5, 0x7D, 0xF9, 0x2D, 0x44, 0xC4, 0xB6, 0xA6, 0x8D, 0x50, 0xB9]
那么我换成 12345678+21*'0' 得到
[0x01, 0x5B, 0x51, 0xD5, 0x33, 0xB0, 0x9B, 0xFD, 0x7D, 0xF9, 0x2D, 0x44, 0xC4, 0xB6, 0xA6, 0x8D, 0x50, 0xB9, 0x49, 0xA7, 0xA4, 0x9D, 0xEE, 0xFB, 0x4D, 0x72, 0xD1, 0x7A, 0xD7]
发现什么? 这个是逐字节加密的 猜都能猜到是一个29长度的keytable一一进行xor
那么已知明文和密文xor回去得到key 再在cmp处提取出enc xor回去就行了
enc = [0x56, 0x05, 0x03, 0x86, 0x7D, 0xEC, 0xF9, 0xAB, 0x26, 0xAA, 0x2D, 0x10, 0xB1, 0xD9, 0xD5, 0x8D, 0x0F, 0xC6, 0x49, 0xA7, 0xFB, 0x9D, 0xB1, 0xA4, 0x4D, 0x2D, 0x85, 0x2F, 0x9A]
my_enc = [0x01, 0x5B, 0x51, 0xD5, 0x33, 0xB0, 0x9B, 0xFD, 0x7D, 0xF9, 0x2D, 0x44, 0xC4, 0xB6, 0xA6, 0x8D, 0x50, 0xB9, 0x49, 0xA7, 0xA4, 0x9D, 0xEE, 0xFB, 0x4D, 0x72, 0xD1, 0x7A, 0xD7]
my_input = "12345678000000000000000000000"
for i in range(0x1D):
print(chr(enc[i]^(ord(my_input[i])^my_enc[i])),end='')
flag{jUnkc0dE_C0oO00o0oo0ode}
Crack Me
题目描述:
你很会逆向?只会工具有什么用!出来混,讲的是调试,讲的是写注册机。你是哪个道上的?原来是脚本小子。
yysy 这倒是真的...
看题 给了1000个username让我们找到对应的序列号
采用IDA+x32结合调试
这里IDA漏了一个点没反编译...
整体流程就很清晰了
我们输入的小写字母username先转大写 然后累加ord sum xor 0x137
我们输入的序列号先str->int 然后sum xor 0x6666 两者进行cmp check
注册机代码:
def Crack(username:str):
ans = 0
for c in username:
ans += ord(c)-32
ans ^= 0x137
ans ^= 0x6666
return ans
总exp:
def Crack(username:str):
ans = 0
for c in username:
ans += ord(c)-32
ans ^= 0x137
ans ^= 0x6666
return ans
username = """
...
"""
username = username.split('\n')
flag = ""
cnt = 0
for c in username:
try:
if(c!=''):
flag += str(Crack(c))+"-"
cnt += 1
except:
pass
print(flag)
print(cnt)
md5一下 NSSCTF{0cf22b5e6d17eac617cfe99806f7b0ce}