【原理】
竞争条件漏洞就是多个进程访问同一资源时产生的时间或者序列的冲突。Linux系统中大量使用并发编程,对资源进行共享,如果产生错误的访问模式,便可能产生内存泄露,系统崩溃,数据破坏等问题。
举一个小例子,下面这段代码定义了两个函数,不看get_flag正常情况下function是输出“NO permission!”但由于变量access是全局变量,在get_flag中被global了,于是在线程运行的过程中利用时间差,get_flag函数就可以改变access的初值,即改变了函数的执行流程,最后会输出“You are root,this flag!”,然后就可以做一些root权限下的操作。代码time.sleep(3)的地方在实际情况下可能会是一些耗时较长的函数,或是某个中断的/耗时的执行(如重新连接数据库的行为)
【利用场景】
条件竞争就是不断重复发包,数据库或者程序对于操作的内容没有进行锁死造成绕过之前的条件判断。如果一个特权程序存在竞争漏洞,此时就可以运行一个平行的进程去和这个特权用户竞争,目的是期望改变这个特权程序的行为或是获取root权限。
拿GCTF的赛题举例,在题目中点击获取源码,其中存在条件竞争漏洞的是下面这段,这是重置密码的执行过程,对于初次访问的用户,首先会在session中判断是否存在登陆成功的name,不存在就在数据库中插入新用户,用户名是后台通过uniqid()函数生成的唯一值,然后再插入用户权限。下一步是清理用户信息,根据上一步中得到的$user在用户上传新的密码后,后台首先会删除user表里的用户信息,接着删除priv表里的用户权限,然后在user表中加入新的密码和原用户名$user,再加入该用户的权限
很关键的一点,后台在判断用户权限时是根据notadmin字段,如果该字段为Flase则是root权限。那么重置和登录操作之间就可能存在一段时间差,因为重置和登录的逻辑没有做好访问的控制,正常情况下,应该是成功登录的用户才可执行重置的操作,但这里的两个操作成为了平级的关系,无论你是否登录均可重置当前用户的密码(原登录的初始密码是用户名),故存在条件竞争。这里登录操作通过竞争要达到的目的是,在重置过程中,删除了旧的权限信息后,到设定用户新权限之前的这段时间内成功登录该用户,此时用户没有设定权限即为Flase,可绕过后台对权限查询的判断,导致用户成为root用户。
Payload:
其中data是共享资源,就相当于正常业务逻辑中默认所用访问的用户均已登录成功,具备重置密码的权限
Flag:
简单点的方式,还可以直接用burp多线程发包