realloc_hook
有时one_gadget因为环境原因全都不可用,这时可以通过realloc_hook来调整堆栈环境。
将realloc_hook设置为选好的one_gadget,malloc_hook设置为如图某条push指令
注意sub rsp,0x18
从而调整改变栈环境。
因为realloc_hook和malloc_hook相邻,所以有机会同时修改两个值。
通过main_arena获取libc基地址
main_arena储存在libc.so.6的.data段,通过这个偏移我们可以获取libc基地址。
将libc.so.6拖入IDA中,找到malloc_trim()函数
__malloc_trim源码
强行加载不同版本glibc
通过environ环境变量改写main返回地址
在历史上,大多数unix系统都支持main函数带三个参数,其中第三个参数就是表示环境表的地址,在glibc中储存程序运行需要的环境变量。
int main(int argc,char *argv[],char *envp)
通过 libc.symbols[‘__environ’] 找到environ变量在glibc中的地址,从而确定main函数在栈中的返回地址。
scanf & printf
scanf输入大量字符会调用malloc和free
scanf(“%d”)输入+、- 不会更改栈上的值(比如绕过canary
printf(“%10000c”,x) 当宽度过大时会调用malloc和free
seccomp会调用calloc
pass
绕过seccomp沙盒保护
未检查arch
当未检查arch参数时,可以尝试转换当前的处理器模式。
i386和x86-64拥有有不同的系统调用号,例如在x86_64下禁用了0x3b(execve)号系统调用,那么可以欺骗cpu目前在运行i386的程序,那么就可以使用系统调用号0xb(i386下的execve),当然要求0xb不在黑名单中。
1 | to32: |
x64下使用X32
如果开启了arch检查,使用X32的方式绕过。
X32为x86-64下的一种特殊的模式,它只工作在原来为64位的程序下,它使用64位的寄存器和32位的地址,此时nr会在原来的基础上加上__X32_SYSCALL_BIT (0X40000000),即原本的sys_number + 0x40000000,这会达到一样的效果。
reference
https://blog.betamao.me/2019/01/23/Linux沙箱之seccomp/
magic gadgets
1 | pwndbg> x/10xi 0x0000000000400618 |
这是一个在栈溢出时很好用的gadget,通过csu中的通用gadgets可以控制rbx,在使用one_gadget时加上参数-l 2,可以找到一个要求r12 r14为0的rce,因为csu我们可以轻易控制这俩参数,十分好用。甚至不需要leak就可以getshell,如果Partial RELRO 那么直接add GOT 通过计算偏移修改为rce;如果Full RELRO,那么通过返回到libc_start_main会在栈上写入libc地址也可以利用。cscctf_2019_quals_signal
1 | 0x7ffff7f197a0 <getkeyserv_handle+576>: mov rdx,QWORD PTR [rdi+0x8] |
这是一个存在与glibc2.31的gadget,因为在此版本的setcontext参数被改为了rdx,那么可以通过这个gadget再次实现利用。2020_GACTF_card。另外提一下glibc2.29后vtable可写
reference
https://publicki.top/2020/06/17/cscctf_2019_qual_signal/
libc.got[‘__free_hook’]
1 | 0x7ffff7a9154a <free+10> mov rax, qword ptr [rip + 0x33f9a7] |
free时会先拿出free_hook@got的值,再判断这里面是否为空