- RE1:迷宫
- RE2:so层
最后一个好像是php?告辞
RE1
程序逻辑很简单,就是一个迷宫,迷宫的每一个位置写成了一个函数,一开始想手动推一下试试,结果发现有的格子可能有多条路径,然后想反着推,然后发现有相同的问题…
考虑写自动化脚本,一开始想试试angr,同样有很多问题,想用idaapi又只能现查各种api
后来在手动执行的时候,发现错误输入和正确输入之间的区别是反馈不同,而且走错路径的话不需要退出,直接原路返回就行,于是考虑直接用pwntools模拟手动执行
直接简单回溯
import sys
sys.setrecursionlimit(20000)
from pwn import *
success = [
b'Just do it\n',
b'GOGOGO\n',
b'Wuhu~!\n',
b'Wuhu\n',
b'You are so good\n',
b'Nice.\n',
b'Yeah~~\n',
b'Yeah~~~\n',
b'Let\'s go.\n',
b'Never stop\n',
b'So smart\n',
]
p = process('./maze')
# solvepath = "SSSSSSSSSDDDDDDWWWWAAWWAASSSSD"
# context(os='linux', arch='amd64', log_level='debug')
# solveend = "AASSDDSSSSDDS"
# solvepath = 'S' * 8
solvepath = 'S' * 8
direct = ['W', 'A', 'D', 'S']
p.recvuntil(b'You can only go south.\n')
for i in solvepath:
p.send(i)
print (p.recvline(), i)
def dfs():
global solvepath
for cur in direct:
if direct.index(solvepath[-1]) + direct.index(cur) != 3:
p.send(cur)
rev = p.recvline()
# print (rev, cur)
if rev in success:
solvepath += cur
# print (solvepath)
dfs()
# print (direct[3 - direct.index(solvepath[-1])])
p.send(direct[3 - direct.index(solvepath[-1])])
solvepath = solvepath[:-1]
p.recvline()
elif b'Good Job.' in rev:
print (solvepath + cur)
exit(0)
dfs()
运行结果拿去算个md5就行
RE2
这题才是传统的逆向啊,为什么做的人反而比第一题少…
看一下jeb,发现加密在so层,直接ida看so层
发现先进行了一个RC4,然后是一个XXTEA
直接解密
解密代码来自 NewBieReer 师傅
先上XXTEA模板
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[4]) {
uint32_t y, z, sum;
unsigned p, rounds, e;
rounds = 6 + 52/n; //12 52/6 = 8 n
sum = rounds*DELTA;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--) {
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
int main(){
uint32_t v[9] = {0x68E5973E, 0x0C20C7367,
0x98AFD41B, 0xFE4B9DE2,
0x1A5B60B, 0x3D36D646,
0xDBCC7BAF, 0xA0414F00,
0x762CE71A
};
uint32_t const k[4] = {0x1,0x10,0x100,0x1000};
int n = 9;
btea(v,n,k);
printf("解密后的数据:0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x %08x\n",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8]);
}
然后再接一个RC4
def __rc4_init(key):
keylength = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + int(key[i % keylength])) % 256
S[i], S[j] = S[j], S[i]
return S
def rc4_crypt(key, data):
S = __rc4_init(key)
i = j = 0
result = b''
for a in data:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = (a ^ S[(S[i] + S[j]) % 256]).to_bytes(1, 'big')
print (hex(S[(S[i] + S[j]) % 256]))
result += k
return result
if __name__ == "__main__":
from libnum import n2s, s2n
key = b'\x01\x00\x00\x00\x10\x00\x00\x00\x00\x01\x00\x00\x00\x10\x00\x00'
data = n2s(0x5604b0d49c634d3096cec00593be3b82524b16b28a33b74d6d7b9950c2b10c12e1840a93)
def convert(k):
ret = []
while k > 0:
ret.append(k & 0xff)
k >>= 8
return ret[::-1]
result_rc4 = rc4_crypt(key,data)
print(result_rc4)
注意一下大小端就行