1
2
$ ./reverse_box ${FLAG}
95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a

题目提示如上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int a1, char **a2)
{
size_t i; // [esp+18h] [ebp-10Ch]
int v4; // [esp+1Ch] [ebp-108h]
unsigned int v5; // [esp+11Ch] [ebp-8h]

v5 = __readgsdword(0x14u);
if ( a1 <= 1 )
{
printf("usage: %s flag\n", *a2);
exit(1);
}
sub_804858D(&v4);
for ( i = 0; i < strlen(a2[1]); ++i )
printf("%02x", *((unsigned __int8 *)&v4 + a2[1][i]));
putchar(10);
return 0;
}

载入ida后发现在sub_804858D中很乱懒得看,在v4处生成了一张表,然后用a2[1]argv[1]flag的字符当做下标取生成的表里的字节,然后以十六进制字符串形式打印出来

sub_804858D这个函数中生成表的时候产生了一个随机数,根据随机数来生成表,随机种子是当前时间time(0),出题人当时运行的时候的结果是上边提示的那一串,看一眼会发现在sub_804858D函数中他把rand函数的返回值强转成了unsigned __int8类型,这样就直接爆破随机数就好了,只有256种可能性。

这里通过patch二进制程序来进行爆破,把0x80485AC处的五字节指令改成mov eax,xmov eax的机器码是0xB8,脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
with open("reverse_box","rb") as f:
a=f.read()
for t in range(1,256):
opcode=("\xB8"+p32(t))
tmp=a[:0x05ac]+opcode+a[0x05b1:]
f=open("./tmp"+str(t),"wb")
os.system("chmod 777 tmp"+str(t))
f.write(tmp)
f.close()
p=process(["./tmp"+str(t),"TW"])
c=p.recv()
print c
if "95ee" in c:
exit()

运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
·····
[+] Starting local process './tmp211': pid 2933
[*] Process './tmp211' stopped with exit code 0 (pid 2933)
90eb

[+] Starting local process './tmp212': pid 2937
[*] Process './tmp212' stopped with exit code 0 (pid 2937)
97ec

[+] Starting local process './tmp213': pid 2941
[*] Process './tmp213' stopped with exit code 0 (pid 2941)
96ed

[+] Starting local process './tmp214': pid 2945
[*] Process './tmp214' stopped with exit code 0 (pid 2945)
95ee

[*] Process './tmp127' stopped with exit code 0 (pid 2597)
·····

可知当时出题人运行的时候产生的随机数是214

这样就可以把tmp214拿出来用gdb调试然后获取那张表了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
gdb-peda$ set args TW
gdb-peda$ b *0x80486DB
Breakpoint 1 at 0x80486db
gdb-peda$ r
·····
gdb-peda$ ni
·····
gdb-peda$ print $esp+0x1c
$3 = (void *) 0xffffce9c
gdb-peda$ x/256b 0xffffce9c
0xffffce9c: 0xd6 0xc9 0xc2 0xce 0x47 0xde 0xda 0x70
0xffffcea4: 0x85 0xb4 0xd2 0x9e 0x4b 0x62 0x1e 0xc3
0xffffceac: 0x7f 0x37 0x7c 0xc8 0x4f 0xec 0xf2 0x45
0xffffceb4: 0x18 0x61 0x17 0x1a 0x29 0x11 0xc7 0x75
0xffffcebc: 0x02 0x48 0x26 0x93 0x83 0x8a 0x42 0x79
0xffffcec4: 0x81 0x10 0x50 0x44 0xc4 0x6d 0x84 0xa0
0xffffcecc: 0xb1 0x72 0x96 0x76 0xad 0x23 0xb0 0x2f
0xffffced4: 0xb2 0xa7 0x35 0x57 0x5e 0x92 0x07 0xc0
0xffffcedc: 0xbc 0x36 0x99 0xaf 0xae 0xdb 0xef 0x15
0xffffcee4: 0xe7 0x8e 0x63 0x06 0x9c 0x56 0x9a 0x31
0xffffceec: 0xe6 0x64 0xb5 0x58 0x95 0x49 0x04 0xee
0xffffcef4: 0xdf 0x7e 0x0b 0x8c 0xff 0xf9 0xed 0x7a
0xffffcefc: 0x65 0x5a 0x1f 0x4e 0xf6 0xf8 0x86 0x30
0xffffcf04: 0xf0 0x4c 0xb7 0xca 0xe5 0x89 0x2a 0x1d
0xffffcf0c: 0xe4 0x16 0xf5 0x3a 0x27 0x28 0x8d 0x40
0xffffcf14: 0x09 0x03 0x6f 0x94 0xa5 0x4a 0x46 0x67
0xffffcf1c: 0x78 0xb9 0xa6 0x59 0xea 0x22 0xf1 0xa2
0xffffcf24: 0x71 0x12 0xcb 0x88 0xd1 0xe8 0xac 0xc6
0xffffcf2c: 0xd5 0x34 0xfa 0x69 0x97 0x9f 0x25 0x3d
0xffffcf34: 0xf3 0x5b 0x0d 0xa1 0x6b 0xeb 0xbe 0x6e
0xffffcf3c: 0x55 0x87 0x8f 0xbf 0xfc 0xb3 0x91 0xe9
0xffffcf44: 0x77 0x66 0x19 0xd7 0x24 0x20 0x51 0xcc
0xffffcf4c: 0x52 0x7d 0x82 0xd8 0x38 0x60 0xfb 0x1c
0xffffcf54: 0xd9 0xe3 0x41 0x5f 0xd0 0xcf 0x1b 0xbd
0xffffcf5c: 0x0f 0xcd 0x90 0x9b 0xa9 0x13 0x01 0x73
0xffffcf64: 0x5d 0x68 0xc1 0xaa 0xfe 0x08 0x3e 0x3f
0xffffcf6c: 0xc5 0x8b 0x00 0xd3 0xfd 0xb6 0x43 0xbb
0xffffcf74: 0xd4 0x80 0xe2 0x0c 0x33 0x74 0xa8 0x2b
0xffffcf7c: 0x54 0x4d 0x2d 0xa4 0xdc 0x6c 0x3b 0x21
0xffffcf84: 0x2e 0xab 0x32 0x5c 0x7b 0xe0 0x9d 0x6a
0xffffcf8c: 0x39 0x14 0x3c 0xb8 0x0a 0x53 0xf7 0xdd
0xffffcf94: 0xf4 0x2c 0x98 0xba 0x05 0xe1 0x0e 0xa3

把表整理一下,就可以查找题目提示的输出的每个字节在表中的索引从而得到flag了。

1
2
3
4
5
6
7
8
9
10
11
(py27) C:\Users\sayhi>python
Python 2.7.16 |Anaconda, Inc.| (default, Mar 14 2019, 15:42:17) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> a="d6c9c2ce47deda7085b4d29e4b621ec37f377cc84fecf2451861171a2911c77502482693838a427981105044c46d84a0b1729676ad23b02fb2a735575e9207c0bc3699afaedbef15e78e63069c569a31e664b558954904eedf7e0b8cfff9ed7a655a1f4ef6f88630f04cb7cae5892a1de416f53a27288d4009036f94a54a466778b9a659ea22f1a27112cb88d1e8acc6d534fa69979f253df35b0da16bebbe6e55878fbffcb391e9776619d7242051cc527d82d83860fb1cd9e3415fd0cf1bbd0fcd909ba91301735d68c1aafe083e3fc58b00d3fdb643bbd480e20c3374a82b544d2da4dc6c3b212eab325c7be09d6a39143cb80a53f7ddf42c98ba05e10ea3".decode("hex")
>>>
>>> b="95eeaf95ef94234999582f722f492f72b19a7aaf72e6e776b57aee722fe77ab5ad9aaeb156729676ae7a236d99b1df4a".decode("hex")
>>>
>>> "".join([chr(a.index(i)) for i in re.findall(".",b)])
'TWCTF{5UBS717U710N_C1PH3R_W17H_R4ND0M123D_5-B0X}'
>>>