upload-labs靶场通关详解:第18关 条件竞争
一、分析源代码
// 初始化上传状态标志和消息变量
$is_upload = false;
$msg = null;// 检查是否通过POST方式提交了表单(用户点击了提交按钮)
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 = '上传出错!';}
}
这里会将上传的文件临时储存在服务器的某个路径下,再对文件进行判断,如果文件合法就转移保存,否则删除文件。
二、解题思路
仔细思考代码,无论上传什么文件它都会先临时保存再判断,不合法就删除。但是服务器做出判断是需要时间的,尽管这个时间非常短,那么能不能和时间去做一个竞争呢?假设攻击者不停地上传木马,并且不停地尝试访问,服务器也会不停地判断并删除,只要存在一个时间空隙(木马上传到临时目录正在判断还没删除的时候)让攻击者访问到了木马并执行操作,那么就成功了。
这里我们写一个父木马6.php。
<?php fputs(fopen('5.php','w'),'<?php phpinfo();?>');?>
解释如下:
<?php
// 1. 打开文件5.php(不存在则创建,存在则覆盖)
$file = fopen('5.php', 'w');// 2. 向文件中写入PHP代码
fputs($file, '<?php phpinfo();?>');// 3. 关闭文件(代码中省略了fclose,但PHP会自动处理)
?>
父木马的作用是创建一个子木马并写入恶意代码。通过不断上传父木马并访问,只要父木马在时间间隙中被成功执行过一次,那么它就会在服务器中生成一个恶意的子木马,子木马由于不是上传的文件,所以不会被检查,就这样保存下来,从而达到目的。
三、解题步骤
1.将写好的木马通过bp工具不断上传并尝试访问。
配置并攻击。
这里在不断地上传木马。
2.打开浏览器访问父木马,多刷新几次,会在某个时间间隙中成功访问,生成子木马5.php。
3.访问子木马,成功。