The challenge can be downloaded from: Download Link (Password: 0000)
Solution Approach
ret2libc involves hijacking program control flow to execute funcsions from the standard C library (libc). Typically, this is achieved by redirecting execution to a function's PLT entry or a specific address within the GOT table. Usual, the goal is to invoke system("/bin/sh"). This challenge resembles the previous one but lacks the hardcoded string "/bin/sh", requiring us to inject it into a writable and executable memory region—typically the BSS section.
Security Analysis
We first examine the binary's protection mechanisms:
root@pwn_test1604:/ctf/work/wolf/ret2libc# checksec ./ret2libc2
[*] '/ctf/work/wolf/ret2libc/ret2libc2'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
The binary is a 32-bit little-endian executable with NX bit enabled, indicating stack-based bufffer overflows are not directly exploitable without alternative techniques.
Reverse Engineering with IDA Pro
After analyzing the binary in IDA Pro, we identify that the program does not contain the string "/bin/sh". Therefore, we must write this string to a suitable location using the gets function. The most common target is the BSS segment, which is both writable and executable.
GDB Debugging to Determine Stack Layout
To determine how far the input buffer is from the base pointer (ebp), we use GDB:
root@pwn_test1604:/ctf/work/wolf/ret2libc# gdb ./ret2libc2
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 171 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./ret2libc2...done.
pwndbg> r
Starting program: /ctf/work/wolf/ret2libc/ret2libc2
Something surprise here, but I don't think it will work.
What do you think ?
[Inferior 1 (process 254) exited normally]
pwndbg> b main
Breakpoint 1 at 0x8048651: file ret2libc.c, line 20.
pwndbg> r
Starting program: /ctf/work/wolf/ret2libc/ret2libc2
Breakpoint 1, main () at ret2libc.c:20
20 ret2libc.c: No such file or directory.
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────
EAX 0xf7fc6dbc (environ) —▸ 0xffffd79c —▸ 0xffffd8f1 ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
EBX 0x0
ECX 0x166be5d2
EDX 0xffffd724 ◂— 0x0
EDI 0xf7fc5000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
ESI 0xf7fc5000 (_GLOBAL_OFFSET_TABLE_) ◂— 0x1b1db0
EBP 0xffffd6f8 ◂— 0x0
ESP 0xffffd670 —▸ 0xf7ffcd00 (_rtld_global_ro) ◂— 0x0
EIP 0x8048651 (main+9) ◂— mov eax, dword ptr [0x804a060]
────────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────────────────────────
► 0x8048651 <main+9> mov eax, dword ptr [0x804a060]
0x8048656 <main+14> mov dword ptr [esp + 0xc], 0
0x804865e <main+22> mov dword ptr [esp + 8], 2
0x8048666 <main+30> mov dword ptr [esp + 4], 0
0x804866e <main+38> mov dword ptr [esp], eax
0x8048671 <main+41> call setvbuf@plt <0x80484d0>
0x8048676 <main+46> mov eax, dword ptr [stdin@@GLIBC_2.0] <0x804a040>
0x804867b <main+51> mov dword ptr [esp + 0xc], 0
0x8048683 <main+59> mov dword ptr [esp + 8], 1
0x804868b <main+67> mov dword ptr [esp + 4], 0
0x8048693 <main+75> mov dword ptr [esp], eax
0x8048696 <main+78> call
This output shows the initial state of the program’s registers and stack. We proceed to step through the code to analyze the stack layout and locate the offset for our payload.