条件竞争漏洞

条件竞争:系统中,最小的运算调度单位是线程,而每个线程又依附于一个进程,条件竞争则是多进程 或多线程对一个共享资源操作,因为操作顺序 不受控的时候所产生的问题。

进程:进程是为了更好的利用CPU的资源;进程是系统进行资源分配和调度的一个独立单位;每个进程都有自己的独立内存空间,不同进程 通过进程间通信来通信;由于进程比较重要,占据独立的内存,所以上 下文进程间的切换开销(栈、寄存器、虚拟内 存、文件句柄等)比较大,但相对比较稳定安 全。

线程:线程的是为了降低上下文切换的消耗,提高系 统的并发性,并突破一个进程只能干一样事的 缺陷,使到进程内并发成为可能。 线程是进程的一个实体,是CPU调度和分派的基 本单位,它是比进程更小的能独立运行的基本单 位。线程自己基本上不拥有系统资源,只拥有一点在 运行中必不可少的资源(如程序计数器,一组寄 存器和栈),但是它可与同属一个进程的其他的 线程共享进程所拥有的全部资源。 线程间通信主要通过共享内存,上下文切换很 快,资源开销较少,但相比进程不够稳定容易 丢失数据。

协程:协程通过在线程中实现调度,避免了陷入内核 级别的上下文切换造成的性能损失,进而突破 了线程在IO上的性能瓶颈。协程拥有自己的寄存器上下文和栈。 程调度切换时,将寄存器上下文和栈保存到其 他地方,在切回来的时候,恢复先前保存的寄 存器上下文和栈,直接操作栈则基本没有内核 切换的开销。

并发编程:并发编程在实际情况是为了提高执行效率,提高系统的利用率。 

条件漏洞成因:

当一个系统运行结果依耐于不可控的事情的先 后顺序的时候,就可能发生竞争。 

往往程序员可能无法注意到这些事情,因为在 编写程序的时候,往往认为程序一条线执行下 来,但是一个线程在运行中是可能被随时打断 ,并且挂起,然后去执行其他线程的逻辑。导 致出现了设计人员意料之外的情况,最终出现 bug。

漏洞产生条件:task1先对共享的空间进行了一个安全性检查,检查完之后,task2紧 接着修改了共享空间的内容,导致task1的安全性检查边的不可控, 甚至可以是一个不安全的数据,然而再次在获取数据的时候,就可能 出现预期之外的情况,严重的可能导致程序执行流被劫持。 

但是在程序员的角度,从check到get这个过程中共享空间的内容是 不会变的,但是对于多线程来说,这个是未知的。

并发,即至少存在两个并发执行流

       这里的执行流包括线程,进程,任务等级别的执行流

共享对象,即多个并发流会访问同一对象

      常见的共享对象有共享内存,文件系统,信号,这些 共享对象是用来使得多个程序执行流相互交流。

改变对象,即至少有一个控制流会改变竞争对象 的状态。

      因为如果程序只是对对象进行读操作,那么并不会产 生条件竞争。

 

竞争条件示例分析

我们的程序的总体流程如下:

我们看看 init_main()函数:

Login函数 :从逻辑上可以看出,read(0, share_buf, 0x100)是先让用户输 入了一个password,长度可以为0x100,然后将这个数据保 存到&share_buf 中,&share_buf 是局部变量,保存在栈上 的bss段上 。再通过pthread_create创建一个check_password的函数去 检测&share_buf 中保存的password是否为一个合法的值

binary乍一看没有什么逻辑上的问题,唯一调 用的危险函数只有strcpy,但是前面也根据长度,动态的在栈上开辟空间,这也就导致这儿 正常逻辑下无法溢出。

这里需要注意的是,bss上的share_buf是作 为参数传递给check_password的 。也就是说,主线程和子线程共同操作同一块内 存空间 。如果在子线程调用alloc之后,调用strcpy之前 通过主线程去修改位于bss段上的share_buf 的话,就可以在strcpy出产生溢出。

然后在程序中,子进程的的strcpy之前有一个 sleep(1)这个操作 。导致了alloc到strcpy之间有足够的时间让主线 程去修改共享变量 。例如将共享变量share_buf里面的数据长度改的超 过一开始alloc的长度,这样就会造成栈溢出。

checksec发现这个程序开启了canary,所以直接 溢出覆盖返回值是不行的,无法劫持程序流 。 但是如果登陆成功,程序会自动起一个shell,如 果想要登陆成功,就需要控制strncmp返回值为0 。 要么就是控制dest的地址指向password,要么就 是控制n为0

控制dest是不行的,因为dest指向的是stack上,stack的 地址一般是一般是0x7f开头的,而password的地址为 0x06020E0又是通过strcpy复制过去的,不能有过多的 \x00,所以这里覆盖dest是不可行的

可以利用strcpy会在结尾加\x00的特性去覆盖n,使得n的 值为0,这样也可以成功的时候strncmp返回0,以达到绕 过登陆的目的。

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值