前言

之前看到星盟Q群里面的消息,Freedom师傅在B站直播关于虚拟pwn入门的公开课,然后就去听了一波,感觉受益匪浅。之前一直以为虚拟pwn是超级复杂的东西,今年打比赛也遇到了好几次,一直无从下手。所以借着公开课学到的内容,复现了去年国赛虚拟pwn的那道题。这里写一篇博客记录下来,当作自己博客园的第一篇技术博文吧!主要是为了水周五的分享会

漏洞分析

就像Freedom师傅所说的,虚拟pwn的难点不是在于漏洞的利用,而是在于漏洞的分析,在于逆向分析能力。首先说明一点,这里我是直接在网上搜到了一个已经逆好的i64文件,自己跟着去逆向了一波。虽然感觉那位师傅逆的还是有点小瑕疵,但是u1s1,这么大的工程量,给我自己单独从头逆的话,真的逆不了这么清楚(留下了没技术的泪水)。

先在虚拟机运行一下:



从这里可以大致了解程序的功能,就是类似一个虚拟机一样执行我们输入的指令。

然后,直接拉进ida,找到main函数,f5反编译



可以看到,程序一开始便申请了三个段(利用堆申请出来的),一般虚拟pwn就是这三个段吧:代码段,栈段(运行栈),数据段(缓冲区),所以这个程序也不例外。(代码段主要用来放置我们的伪汇编指令,数据段放置我们一开始输入的数据,运行栈段就是执行add等这些指令时的栈段)

但是作为一个段的话,肯定会需要例如索引,段里面元素个数等信息,所以根据初始化函数sub_4013B4,我们可以重构一个结构体(上图是已经重构完的了)



然后就是一系列程序名,指令,数据等的输入,这里不作详细分析,直接查看run这个函数



发现这里的汇编ida并不能识别出来,所以只能肝汇编代码。



可以发现,其实图中左侧部分的代码块就是典型的for语句,但是问题出现在左下角的代码块



我一开始看到这里的汇编,感到很奇怪,于是就去利用gdb动态调试了一波,感觉更加奇怪了,虽然隐约感觉得出来他是一个跳转表,但是发现他是靠溢出实现得跳转(之前了解到的条状表是像switch那种具有一定规律的),然后那晚的话,教授刚好在工一,向他讨教之后,发现其实这里就是简单依靠目标地址减去数组本身地址得到的跳转表(ORZ)。然后再观察以下图中右上角以及结合gdb动态调试,右上角应该就是我们输入伪指令时的执行了。



这里给出了所有我们可以使用的伪汇编,除了load和save,其他的和我们80-86平台的无异,这里不一一分析,直接看save和load这两个漏洞指令。



这里可以看到,load指令将我们运行栈栈顶的元素取出来,当作一个索引idx,然后再将data_addr->section_ptr + 8 * (data_addr->numb + idx 这个元素给放到栈顶,由于没有对我们输入的栈顶的元素给检查,所以这里可以产生任意写功能。



再来看看save函数,这里的save主要是将运行栈的栈顶取出来,作为index,然后将后来的栈顶元素取出,作为value,然后将对应将对应的位置赋值为value:*(8 *(data_addr->idx + index) + data_addr->section_info_ptr) = value

这样的话,save便实现了任意写。

漏洞利用

这里我主要时参考了知乎上认识的四川大学的一个pwn爷的思路

Step one

攻击思路:

instruction='push push save'

data=str(0x0404088)+' '+str(-3)

查看一开始堆的分配



查看正常运行时,运行栈(靠堆实现)的情况(push push add pop || 1 1)



对比我们攻击脚本时的运行栈的情况



可以看到,运行栈中实际放置我们输入数据的地址已经被修改了

Step two

攻击思路:

instruction='push push save push load'

data=str(0x0404088)+' '+str(-3)+' '+'-12'

先看看实现的效果



可以看出,我们的0x404088已经被覆盖成我们的put@got了,这就是load实现的效果,因为我们的0x404088和我们的puts@got刚好相隔13(12+1)

Step three

既然已经修改0x404088为我们的put@got表,那么我们可以根据libc里面system函数和puts@got的偏移,再利用add这个指令去修改puts@got这个值为system函数

攻击思路:

instruction=’push push save push load push add’

offset = -(libc.sym[‘puts’] - libc.sym[‘system’])

data=str(0x0404088)+’ ‘+str(-3)+’ ‘+’-12’+str(offset)

看看实现的效果



可以看到,这个地址已经被我们覆盖为system函数了

Step four

前面已经做到把ystem函数写到puts@got表附近了,再看看我们ida



可以看到,这里调用了puts函数去打印我们的程序名,我们第二步的时候实现了利用save指令去修改0x404088这个地址,反过来,我们也可以用save去修改我们的puts@got表为system函数,那只要我们把程序名设置为system函数的‘/bin/sh\x0’,然后程序最后打印时便会触发这个函数,从而提权成功。

攻击思路:

ins=’push push save push load push add push save’

data=[data_addr,-3,-12,offset,-12]

最后本地提权成功

总结

这是我本人第一次去做的虚拟pwn相关题目,这道题是十分基础的,但是其实这么基础的题,在比赛中如果真的给我遇到了,自己真的不一定可以找得到思路去解决。回头看看思路,其实感觉就是利用了idx越界,然后去修改一些关系表的指针实现的,感觉不少题目都是这种思路,像今年国赛的那道nofree,亦或者说tcache heap的常用套路。

其实这篇博客因该在三天前就应该搞定的了,但是最近实在是有点忙,而且之前编辑一半的时候忘了保存了,昨天又是广外的羊城杯,说起羊城杯,自己真的是拉跨,给一道简单题卡了两三个小时,后面发现只是一个版本数据问题(一度质疑服务器或者docker出问题了),然后去搞了一道REpwn最后一直没有思路,逆向水平太差了,看汇编能力不够,后来一点多的时候就睡觉了,起床后发现,俺们的师兄jb大佬居然肝到凌晨五点,肝出来了,对比以下,自己真的是羞愧。



最终队里web大佬差一道web就把web全AK了,而二进制只是输出了一道(惭愧)

最后说一下最近打算更的博文的,明后两天打算学习Linux内核的进程线程基础(看源码,一些重要的数据结构,以及结合自己本身的教科书),然后去学一下iot安全入门(了解架构基础吧),应该会总结两篇博客出来。

虚拟PWN初探的更多相关文章

  1. KingPaper初探 wamp下本地虚拟主机的搭建

    在本地我们进行网站或系统开发时,因为我们本地的地址以localhost为主机名的  我们上传到服务器会有很多东西要修改 为了避免这些不必要的修改,我们可以在本地搭建虚拟主机 一下是在wamp下搭建虚拟 ...

  2. IIS虚拟目录与UNC路径权限初探

    最近在一个项目中涉及到了虚拟目录与UNC路径的问题,总结出来分享给大家. 问题描述 某客户定制化项目(官网),有一个图片上传的功能.客户的Web机器有10台,通过F5负载均衡分摊请求. 假设这10台机 ...

  3. Vue 虚拟Dom 及 部分生命周期初探

    踏入前端,步入玄学 17年底至18年初附带做了vue的一些框架搭建,中途断断续续用了部分vue,时隔几个月后的工作又拾起vue,对于一些原理性的知识淡忘了,正值这段时间使用中遇到了一些坑,又拨了部分代 ...

  4. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

  5. Unity3D游戏开发初探—1.跨平台的游戏引擎让.NET程序员新生

    一.Unity3D平台简介 Unity是由Unity Technologies开发的一个让轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的 ...

  6. Unity3D游戏开发初探—2.初步了解3D模型基础

    一.什么是3D模型? 1.1 3D模型概述 简而言之,3D模型就是三维的.立体的模型,D是英文Dimensions的缩写. 3D模型也可以说是用3Ds MAX建造的立体模型,包括各种建筑.人物.植被. ...

  7. nginx平台初探(100%)

    http://tengine.taobao.org/book/chapter_02.html 初探nginx架构(100%)¶ 众所周知,nginx性能高,而nginx的高性能与其架构是分不开的.那么 ...

  8. 物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探

    物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探 唐朝实验室 · 2015/10/30 10:22 Author: FengGou 0x00 目录 0x00 目录 0x01 前言 0x02 BLE概 ...

  9. React 初探

    React 简单介绍 先说 React 与 React Native 他们是真的亲戚,可不像 Java 和 Javascript 一样. 其实第一次看到 React 的语法我是拒绝的,因为这么丑的写法 ...

随机推荐

  1. Java中编写代码出现异常,如何抛出异常,如何捕获异常

    异常的产生过程解析 先运行下面的程序,程序会产生一个数组索引越界异常ArrayIndexOfBoundsException.我们通过图解来解析下异常产生的过程. 工具类 class ArrayTool ...

  2. C#LeetCode刷题之#367-有效的完全平方数(Valid Perfect Square)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3869 访问. 给定一个正整数 num,编写一个函数,如果 num ...

  3. Quartz.Net的基础使用方法,多任务执行

    接着上面单任务执行的代码做一下简单的扩展 主要看下面这段代码,这是Quartz多任务调度的方法,主要就是围绕这个方法去扩展: // // 摘要: // Schedule all of the give ...

  4. speedtest测速网站测速节点添加流程

    一.准备一台服务器: 系统需求:常见Linux系统: 二.服务器入网(确保可以访问互联网): 三.ssh登录到服务器安装speedtest守护程序程序包: 安装和启动,执行以下命令: curl -O ...

  5. mysql无法远程连接问题(ERROR 1045 (28000): Access denied for user 'root')

    mysql版本 : 8.0.21 使用mysql 作为nextcloud的数据库.之前使用挺正常的,因为被黑客勒索过一次,重新启动了一个mysql的docker镜像. 结果数据库配置老是失败,next ...

  6. Jmeter 常用函数(7)- 详解 __time

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 返回各种格式的当前时间 语法格式 ${ ...

  7. AOP计算方法执行时长

    AOP计算方法执行时长 依赖引入 <dependency> <groupId>org.springframework.boot</groupId> <arti ...

  8. cpu相关信息(进程、线程、核...)

    cpu的相关信息. 1.cpu 1.1 物理cpu 实际Server中插槽上的CPU个数.物理cpu数量,可以数不重复的 physical id 有几个 1.1.1 查看物理CPU的个数 cat /p ...

  9. 升级的华为云“GaussDB”还能战否?

    摘要:芯片.操作系统.数据库是现代信息技术领域的三大核心基础,做数据库,不仅需要技术和投入,对华为这种做通讯起家的企业,更需要的是一种并非玩票性质的态度. GaussDB,不仅蕴含着华为对数学和科学的 ...

  10. .net core 3.0 web api 重点设置,主要为了解决axios post不到参数问题

    这两天研究.net core 3.0升级,前端vue+axios 后端web api.测试过程中发现post的时候,由于提交的是json对象,后端web api获取不到数据. 今天贴了下解决过程.主要 ...