漏洞理解
条件竞争漏洞(Race condition)官方概念是——竞争条件发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中。这个漏洞存在于操作系统、数据库、web等多个层面,像有名的脏牛(dirty cow)。
开发者在进行代码开发时常常倾向于认为代码会以线性的方式执行,而且他们忽视了并行服务器会并发执行多个线程,这就会导致意想不到的结果。这个漏洞的思想和参数污染漏洞(HPP)比较像(传送门),都是通过附加的情况使得程序异常,但原理不同。
线程同步机制确保两个及以上的并发进程或线程不同时执行某些特定的程序段,也被称之为临界区(critical section),如果没有应用好同步技术则会发生“竞争条件”问题。
漏洞实例
负数购买
对于条件竞争漏洞比较经典的案例是转账、购买,也是条件竞争漏洞的高发场景。这里从数据库层面还原一个星巴克无限购买案例,直观解释下这个漏洞的原理。
假设我们使用账户里的1000元购买10件100元的商品,正常购买流程为:购买物品 —> 查询余额是否大于商品价格 —> “购买成功,余额-1000,商品数+1” 或者 “购买失败,提示余额不足”。
1、查看数据库账户余额及物品数:
2、点击购买,拦截数据包,设置intruder发送50个数据包,线程调到25后发进行并发请求:
3、查看数据库的日志,可以看到对count的查看SELECT和更新UPDATE并不是线性依次执行的,所以导致在完成对count-1000的操作之前进行了另一次查询count仍为1000,最终结果是购买数量大于10,而余额为负数:
4、解决方案通常是加“锁”,mysql执行事务前加BEGIN,后加COMMIT,从而锁定一次事务处理,使按序进行:
文件上传
这是upload-libs上面的一个题,题目代码如下:
<?php
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_name = $_FILES['upload_file']['name'];
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_ext = substr($file_name,strrpos($file_name,".")+1);
$upload_file = UPLOAD_PATH . '/' . $file_name;
if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
rename($upload_file, $img_path);
$is_upload = true;
}else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
unlink($upload_file);
}
}else{
$msg = '上传出错!';
}
}
?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
这里是先通过move_uploaded_file函数将上传文件临时保存,再对文件类型进行判断,如果不在名单白里则删除,在白名单里的话就进行重命名,所以这里存在条件竞争。
我们使用多线程并发的访问上传的文件,总会有一次在上传文件到删除文件这个时间段内访问到上传的php文件,一旦我们成功访问到了上传的文件,那么它就会向服务器写一个shell。
我们可以使用如下方式进行绕过:用Burp开启两个intruder模块,一个用于重复上传木马文件,另一个用于重复访问木马文件。
1、首先上传1.php文件,抓包,放到intruder模块中:
2、然后访问我们上传文件后的路径,抓包,也放到intruder模块中:
3、设置这两个intruder的payloads,Payload type设置为Null payloads,然后设置访问次数(我这里设置的50000):
4、最后同时重放两个intruder模块,可以看到访问了50000次,最后只有4次成功了。其他的访问次数里,有小部分是状态码返回200但执行出错,大部分是返回404:
进阶挖掘
漏洞场景
挖掘条件竞争漏洞需要关注的功能点有:
购买:付款/购买/积分/订单操纵相关的漏洞(上文案例1);
上传:多过程处理,如文件上传处理(上文案例2);
兑换:积分/优惠券/注册邀请码(下文案例1);
绕过数量限制(下文案例2);
此外还可能存在DOS攻击(下文案例3)。
特点总结来说就是——共享同一资源,生成其他结果。
【注意】这个漏洞具有偶现性,很受环境因素的影响,比如网络延迟、服务器的处理能力等,所以只执行一次可能并不会成功,尽量多尝试几次。
其他实例
1、积分兑换
Hackerone上一个flag兑换邀请码的案例,使用同一Flag请求70次并获得了2次邀请:
2、绕过数量限制
Shopify商店具有添加地址的功能,但拥有的地点数量最多是4个,可以通过多线程发包绕过软限制:
可以看到成功成功创建了8个地址:
同样的案例也有:绕过员工帐户数量限制、单次投票机会等,有数量上限的场景都可以尝试多线程绕过。
3、DOS攻击
一个在建议提交处无频率限制从而导致DOS的案例:
漏洞防御
1、对于业务端条件竞争的防范,一般的方法是设置锁;
2、对于文件上传,一定要经过充分完整的检查之后再上传;
3、在操作系统的角度,共享数据要进行上锁保护。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39190897/article/details/106355153