强网拟态2022pwn
pwn1
直接利用格式化字符串
1 |
|
pwn2-1
存在uaf,且print_note函数是通过引用堆块上print_note_content函数的地址来实现,修改堆上print_note_content函数的地址为magic函数地址。
1 |
|
bfbf
bf解释器类型的题
通过输入的‘><+-‘等这些符号可以对栈上v3的数据进行读写,而且没有对偏移量进行限制,这就可以对栈上的任意数据读写。
打印出__libc_start_main
函数的地址,减去相应的偏移就可得到libc的基地址,利用libc找到相应的gadget,再覆盖栈上__libc_start_main
的地址,直接ROP。
程序开启沙盒对read函数的第一个参数进行了限制,我们无法直接orw读取flag文件中的信息,这里改用sendfile函数即可。
完整exp
1 |
|
改用readv函数也可以读取flag
1 |
|
也可以使用close函数先关闭标准输入close(0)
,再直接orw,这里就不再展示了。
only
本地环境:2.31-0ubuntu9_amd64
程序在开始时就已经有很多堆块已经被分配释放了(通过动态链接库libseccomp.so.2引入沙盒规则导致的)
使用increase函数是对堆块的申请,次数限制为11次;使用decresae函数是释放堆块,次数限制为4次,虽然有uaf,但程序没有edit函数和show函数这种功能,无法对uaf完成有效利用,唯一可以利用的是initial函数,还只能使用一次
如果已经完成了一次堆块的申请并且释放,在此过程就将tcache中的tcache_perthread_struct *key
破坏,配合uaf就可以实现tcache的double free。由于申请堆块的大小,释放次数这些限制,我们无法一次性泄漏出libc的基地址。
在完成double free后,劫持到tcache的结构体头部,就可以直接控制tcache的申请和数量。直接释放tcache的结构体头部得到unsorted bin后,攻击_IO_2_1_stdout_
以实现libc基地址的泄漏:
沙盒的存在无法直接拿到shell,需要利用mov rdx, qword ptr [rdi + 8] ; mov qword ptr [rsp], rax ; call qword ptr [rdx + 0x20]
和setcontext劫持rsp,执行ROP或者shellcode。
在此过程中需要爆破两次地址,有1/256的概率拿到flag,在本地运行时可以加上 aslr=False,节省本地爆破的时间。
完整exp
1 |
|
store
程序只能使用两次申请堆块,虽然后续也能申请,但无法去使用;留了一个uaf的漏洞,free的次数也只能是4次,edit和show这种函数可以正常使用。如果使用tcache去实现任意写,这两次申请是远远不够用的。这里是使用house of apple2,主要就是利用一次largebin attack攻击去实现劫持IO控制流。
Roderick师傅的文章已经很详细了:[原创] House of apple 一种新的glibc中IO攻击方法 (2)-Pwn-看雪论坛-安全社区|安全招聘|bbs.pediy.com
当然构造IO_FILE也需要注意_IO_flush_all_lockp
函数中的if判断:
满足前者fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base
,或者后者``_IO_vtable_offset (fp) == 0&& fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base`即可
进入_IO_wfile_overflow
后会有rdx直接赋值为fp->_wide_data
,所以可以直接配合setcontext函数使用
题目中存在沙盒,64位和32的限制都有
但seccomp-tools将32位系统调用号也看成64位的,这就很迷惑人。对比32位的系统表就会发现open的系统调用在32位中的系统调用号为5,这里就先使用32位的open调用号去打开flag文件,再去用64位的读写。由于32位寄存器大小的限制,直接使用pwntools生成的open系统调用会出错,所以先mmap一段低地址内存再去使用。
完整exp
1 |
|