打stdout泄露地址
开启了沙盒保护,所以需要利用ORW读取flag。
程序分析
只有一次UAF和一次show。最大申请0x90大小的chunk。libc-2.31.so版本。
思路
先利用UAF 和show,释放Unsortedbin来泄露libc地址。此时没有show功能了,但是想要ORW的,需要配合栈,分配到栈区构造ROP即可读取flag。所以需要通过environ泄露栈地址。既然需要泄露,所以此时就需要利用攻击IO_FILE_stdout结构。
IO_FILE_stdout利用链
1234567891011121314151617181920212223int _IO_new_file_overflow (_IO_FILE *f, int ch){ // 判断标志位是否包含_IO_NO_WRITES => _flags需要不包含_IO_NO_WRITES if (f->_flags & _IO_NO_WRITES) { f->_flags |= _IO_ERR_SEEN; __set_errno (EBADF); ...
利用exit_hook
linux程序调用过程
在Linux下一个程序真正的入口点是_start()函数,在该函数中会调用__libc_start_main()函数,这个函数会调用__libc_csu_init()函数进行一系列的初始化工作,之后才会调用main函数,来到用户代码空间
同样的,无论用户代码中是否调用exit()函数,在用户代码结束后程序都会缺省调用exit函数
exit函数调用链
关键点在于exit调用的__run_exit_handler函数里面调用了 __call_tls_dtors、_dl_fini、_IO_cleanup、_exit函数,最后是在_exit函数里面利用系统调用结束程序。
重点在于_dl_fini函数。
这个函数中先后调用:rtld_lock_default_lock_recursive、_dl_sort_map、rtld_lock_default_unlock_recursive、__do_global_dtors_aux、_fini。
并且其中rtld_lock_default_lock_recursive和rtld_lock_default_unlock_recu ...
堆上ORW
程序分析
四个功能
根据add函数中的对index的判断,发现程序只能创建一个chunk。
并且程序开启了沙盒,所以需要利用ORW来打
漏洞点
delete函数中存在UAF
攻击思路
由于开启了沙盒,所以会在堆区开辟许多堆区,此时bin中很杂乱
所以,可以先将这些bin申请出来,清空bin,便于接下来利用
因为存在UAF,利用edit函数功能构造double_free。因为有一个key值在防止double_free,所以将其填充为0绕过检测
12345678910add(0,0x40)delete(0)edit(0,p64(0)*2)delete(0)show(0)rl("Content: ")heap_leak = u64(p.recv(6).ljust(8,'\x00'))lg("heap_leak",heap_leak)heap_base = heap_leak-0x1920lg("heap_base",heap_base)
先泄露heap_addr,根据偏移计算出heap_base。然 ...
触发malloc_consolidate利用double_free
前言
根据题目所给的libc-2.31.so确定libc版本
1strings ./libc-2.31.so | grep ubuntu
glibc–all-in-one如果没有的话,就从ubuntu launchpad上下载
1https://blueprints.launchpad.net/ubuntu/+source/glibc/2.31-0ubuntu9.9/+build/23546070
上面的是带有debug符号表的,下面的是源码。
patchelf后pwndbg加载对应符号表
前面ab是指debug下的ab文件夹,后面的是debug文件,用pwndbg直接加载即可
1add-symbol-file /home/zhuyuan/libcs/2.31-0-9.9/sym/usr/lib/debug/.build-id/ab/9302212dbf9aa238be80d83b3f64a135af9ca7.debug
这样就相当于加载了libc–2.31.so的符号表了。
程序分析
三个功能,没有edit功能,只有malloc和free。
漏洞点
存在UAF漏洞
攻击思 ...
UAF修改tcache_perthread_struct
漏洞点
存在UAF
思路
只能一直对下标为0的堆块进行修改。
因为这个是glibc-2.27-1.4相较于glibc-2.27-1.0多了一个key机制,是为了防止double_free机制的。
利用edit()将其修改为0即可绕过检查,然后再利用double free
利用double free对tcache_perthread_struct结构体进行劫持,然后将0x250对应counts修改为7,因为tcache_perthread_struct结构体chunk大小为0x250,所以这样当我们将这个chunk释放掉后,由于counts为7,表示tcache满了,就会将其free进unsortedbin中。
接着就是再次申请chunk,然后修改tcache_perthread_struct中tcache_entry指针,tcache_entry指针指向的就是当前tcache中对应大小的链的指针,将此指针修改到malloc_hook范围。
需要注意的是,tcache_perthread_struct对应的counts也要讲0x70处修改为1,然后再次申请这个大小的chu ...
UAF申请stack打ORW
开启了沙盒保护。
所以利用ORW。
攻击思路
存在UAF,所以利用就比较简单。泄露libc,泄露heap_key,泄露heap_base,然后利用environ泄露栈地址,再申请到栈区,覆盖edit返回地址为ORW的ROP链。
EXP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102from pwn import *from ctypes import *from libcfind import *from LibcSearcher import*import base64import syscontext(os='linux', arch='amd64', log_level='debug& ...
UAF
程序四个功能,存在UAF。
漏洞点
攻击思路
123add(0x20,'/bin/sh\x00','/bin/sh\x00')add(0x30,'ccc','dddd')add(0x30,'eee','ffff')
根据堆块的内容,发现添加堆块的模式是先分配一个管理content的chunk,这个chunk被用来存放name和content的堆块指针以及堆块的free状态和size。
show和edit以及delete功能都是通过这个管理chunk中保存的content指针来进行操作的,所以我们的目的是可以控制到这个管理chunk,然后修改对应的content指针以及size和free状态即可随意控制。
12delete(1)delete(2)
因为delete功能是先释放content的chunk,然后再释放掉管理chunk,那么先释放掉两个size不等于0x30的chunk,此时为0x30大小的
tcachebins中有两个管理chunk
那么直接再申请一 ...
off-by-null利用堆块向前合并
存在off-by-null漏洞,所以可以修改下一chunk的inuse位和pre_size位。修改pre_size位前面堆块大小之和,然后当释放此堆块时由于inuse位是0,所以会判断前面chunk处于释放状态,再根据pre_size向前合并。就会将一个处于malloc状态的chunk带入到unsortedbin中。
EXP
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798from pwn import *from ctypes import *from libcfind import *from LibcSearcher import*import base64import syscontext(os='linux', arch='a ...
Chunk_Extend
漏洞点
原本只能malloc十个堆块,但是当i等于10的时候,从for循环退出的时候还是会经过下面的malloc。所以是创建了11个chunk,并且第11个chunk的位置覆盖了第一个chunk的size。这就导致了chunk1的size变得很大,可以利用edit进行溢出。
攻击过程
利用chunk1的溢出修改chunk2的size字段,将后面的chunk3范围也算进去,然后释放chunk2就会连带着chunk3这个chunk一起进入Bin中,但是此时chunk3还是处于malloc可以利用其进行泄露以及后续申请到free_hook。
因为是在libc-2.27.so中,所以需要将tcachebin填满,这样释放chunk2后才能进入到unsortdbin中。
EXP
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848 ...
House_of_Einherjar
这个跟利用off-by-one或者off-by-null堆块向前合并重叠的大致一样。都是修改pre_size位和inuse位。堆块可以向前合并。
EXP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100from pwn import *from ctypes import *from libcfind import *from LibcSearcher import*import base64import syscontext(os='linux', arch='amd64', log_level='debug')context.terminal = ["tmux"," ...