“竞争条件”是什么?
竞争条件发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中。
开发者在进行代码开发时常常倾向于认为代码会以线性的方式执行,但他们忽视了并行服务器会并发执行多个线程,这就会导致意想不到的结果。
线程同步机制确保两个及以上的并发进程或线程不同时执行某些特定的程序段,也被称之为临界区(critical section),如果没有应用好同步技术则会发生“竞争条件”问题。
条件竞争漏洞其实也就是当同时并发多个线程去做同一件事,导致处理逻辑的代码出错,出现意想不到的结果。
条件竞争漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。
例子1:银行提现
假设现有一个用户在系统中共有2000元可以提现,他想全部提现。于是该用户同时发起两次提现请求,第一次提交请求提现2000元,系统已经创建了提现订单但还未来得及修改该用户剩余金额,此时第二次提现请求同样是提现2000元,于是程序在还未修改完上一次请求后的余额前就进行了余额判断,显然如果这里余额判断速度快于上一次余额修改速度,将会产生成功提现的两次订单,而数据库中余额也将变为-2000。而这产生的后果将会是平台多向该用户付出2000元。
实例:
这是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 =
'上传出错!';
-
}
-
}
-
?>
这里是先move_uploaded_file函数将上传文件临时保存,再进行判断,如果不在名单白里则unlink删除,在的话就rename重命名,所以这里存在条件竞争。
我们可以如下进行绕过。
用burp开启两个intruder模块,一个用于重复上传,另一个用于重复访问。
1:首先,上传1.php文件,抓包,放到intruder模块中
2:然后访问我们上传文件后的路径,抓包,也放到intruder模块中
3:设置这两个intruder的payloads,Payload type设置为Null payloads,然后设置访问次数,我这里设置的50000
4:同时放两个intruder模块,可以看到,访问了50000次,最后只有4次成功了。其他的访问次数里,有小部分是状态码返回200,但执行出错。大部分是返回404
参考文章:测试Web应用程序中的竞争条件