八月 | 2016 | jinzihao's homepage

注:这篇文章本来是一门课程的(大)作业,由于课程报告题目自选,本文其实就是对CTF中几个很基础的二进制的题写了比较详细的write-up,也算记录了一下自己从零基础开始学习的过程吧。

0. 写在前面

操作系统这门课程对系统如何管理内存做了详细的介绍,这是计算机安全的一个重要分支——内存安全的背景知识。我对计算机安全比较感兴趣,而内存安全也是其中绕不开的一个领域。在计算机安全中,内存安全相比起Web安全等领域门槛较高,需要站在操作系统的视角看内存,才能发现潜在的内存漏洞。这学期选了操作系统这门课,也希望能起到“扫盲”的作用,借此机会入门一下内存安全。这篇课程报告主要关注内存安全问题中最常规的缓冲区溢出漏洞,总结了缓冲区溢出漏洞的一些入门知识,也算是一个初学者的一点学习笔记。

1. 什么是缓冲区溢出漏洞

这是一个很难一言以蔽之的概念,维基百科的描述如下:

缓冲区溢出(buffer overflow),是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序运行、并获取程序乃至系统的控制权。[1]

而缓冲区溢出漏洞的利用,则是通过精心构造的输入数据,向内存的特定位置写入特定信息,进而使程序运行发生异常。注意,这里的异常是对于程序开发者而言的,对于攻击者而言则是预期结果。

利用缓冲区溢出漏洞的一般流程如下:

(1) 使用反编译工具(如IDA)对程序进行反编译

(2) 分析反编译得到的C语言代码和汇编代码,设计攻击方法

(3) 按照设计好的攻击方法设计输入数据

(4) 把设计好的输入数据传入到程序中,获得系统权限

下面结合几个实例,对缓冲区溢出漏洞做些简要介绍。

2. 实例1——基本思路

(本题出自Bluelotus-Exercise题集中的shellcode题目[2])

使用IDA反编译得到:

全局变量:

main函数:

这段程序的功能是,从stdin(控制台输入)读入1023个字节,存入shellcode变量,然后通过强制类型转换把shellcode变量作为一个无参数、返回int的函数,调用shellcode变量。由于程序指令本质上也是数据,因此只要将合适的数据写入到shellcode变量,便可以使这段程序执行这段数据对应的程序指令。

shellcode本质上是一段机器码,直接编写难度很大。可以先按照需求编写C语言程序,然后编译,将编译得到的二进制文件用十六进制编辑器打开,便可以得到这段C语言程序对应的机器码。另外,网络上也有很多现成的shellcode,例如本题中可使用这样一段来自EggRun主页的shellcode [3]:

6a 0b 58 99 52 68 6e 2f 73 68 68 2f 2f 62 69 89 e3 52 53 89 e1 cd 80

这段用16进制数表示的机器码对应的C语言程序为execve(/bin/sh),在包括Linux在内的类Unix系统中可以启动一个shell,从而可以执行任意命令。

另外,shell-storm也提供了大量shellcode,可以根据不同的运行环境和预期效果选择不同的shellcode。[4]

(阅读全文 …)


为您推荐了相关的技术文章:

  1. ne2der
  2. 会找漏洞的时光机: Pinpointing Vulnerabilities
  3. 蝴蝶效应与程序错误 —— 一个渣洞的利用
  4. Windows 10下MS16-098 RGNOBJ整数溢出漏洞分析及利用
  5. 内存中的猎者

原文链接: jinzihao.me