GCTF 2017 reverse
【原理】
动态调试
【目的】
通过动态调试得到某数据,然后异或得答案
【环境】
linux,windows
【 工具】
python,ida,gdb
【步骤】
首先看代码逻辑,看到内容如下:大致还是很清晰的,虽然这个判断只有10个字符串,但是实际上需要输入的字符串是22位。。从这里面随机选择一个数字i,然后从byte_6B4270和input中分别取出第i个字符v9和v8,将v8的内容和一个根据i+1的算法进行异或运算与v9比较。整体逻辑如上,而且我们发现,这个i具体是多少其实是不需要的,因为我们的运算中取出的第i个数字必定是要进行i+1次的加密,所以我们只需要遍历这个答案即可。 这里附上解题脚本:
```python t1 = [0x11,0xa,0x11,0xd,0x1,0xf,0,0x6,0x3,0x1] t2 = [0x3a53ef4e,0xd6cd80b7,0x3a53ef4e,0xe87f5342,0x8bee779e,0x9cdfa830,0x03039,0x6848c19b,0x81c794ec,0x8bee779e] code = [95, 242, 94, 139, 78, 14, 163, 170, 199, 147, 129, 61, 95, 116, 163, 9, 145, 43, 73, 40, 147, 103] t = [0xf2] ans = ['#']*22 for i,c in enumerate(code): tmp = 0 for j in range(i+1): tmp = 0x6D01788D * tmp + 12345 ans[i] = chr((tmp^code[i])&0xff)
print(''.join(ans))
su-ctf-quals-2014:guess the number
反编译class后得到
java public static void main(String args[]) { int guess_number = 0; int my_num = 0x14d8f707; int my_number = 0x5c214f6c; int flag = 0x149b861a; if(args.length > 0) { try { guess_number = Integer.parseInt(args[0]); if(my_number / 5 == guess_number) { String str_one = "4b64ca12ace755516c178f72d05d7061"; String str_two = "ecd44646cfe5994ebeb35bf922e25dba"; my_num += flag; String answer = XOR(str_one, str_two); System.out.println((new StringBuilder("your flag is: ")).append(answer).toString()); } else { System.err.println("wrong guess!"); System.exit(1); } }
Step 2
0x5c214f6c/5 = 1545686892/5 = 309137378
输入309137378得到flag
攻防世界 流浪者
这个题进行了两次加密
第一次:根据if条件判断对每个字符操作
if判断
第二次:将第一次加密的值作为数组下标,取另一数组里的值再组成“原料数组”
脚本
table = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
s = "KanXueCTF2019JustForhappy"
ff = []
for i in s:
ff.append(table.index(i))
flag = ""
for i in ff:
if 0 <= i <= 9:
flag += chr(i + 48)
elif 9 < i <= 35:
flag += chr(i + 87)
elif i > 36:
flag += chr(i + 29)
print (flag)
flag{j0rXI4bTeustBiIGHeCF70DDM}
(os:这两天事情比较多,这几道题也比较难,这一周就这样吧)