准备工作
环境搭建
uoload-labs下载地址:https://kgithub.com/c0ny1/upload-labs
下载好后启动phpStudy文件
我这里因为80端口被占用,所以无法启动Apache服务
解决80端口被占用问题
打开windows命令提示符,输入netsatt -ano|findstr 80
查看80端口使用情况
可以看到80端口已经被占用了,并且PID为4(PID为4的进程都是系统进程,要谨慎关闭)
一般情况下80端口被占用都与HTTP服务有关系,所以在这里我们可以查看一下HTTP服务信息netsh http show servicestate
这张图是在网上找的,他这里查看的结果是80端口被SQLServer日志服务占用了,下面有进程PID,直接在任务管理器中找到对应的PID然后关闭就行了。
我的查询结果在HTTP://+:80/
后面是没有提示的,后面也没有显示PID,这种情况下就是被system进程占用了,处理起来就要复杂一点了(忘了截图了)。
首先输入net stop http
(停止系统http服务)
然后再输入sc config http start= disabled(禁止服务自启动)
这时候80端口就释放出来了
到这一步可能还是启动不了Apache,因为http服务被关闭了,所以要到对应的目录下手动启动httpd.exe文件
然后就可以正常使用了
upload-labs通关
Pass-01
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
查看代码提是,可以看出来这个验证是在前端进行的,想办法禁掉前端就行了
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name + "|") == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}
在谷歌的网站设置中禁用JavaScript
然后就能上传了
pass-16
源码
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
// 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
$filename = $_FILES['upload_file']['name'];
$filetype = $_FILES['upload_file']['type'];
$tmpname = $_FILES['upload_file']['tmp_name'];
$target_path=UPLOAD_PATH.'/'.basename($filename);
// 获得上传文件的扩展名
$fileext= substr(strrchr($filename,"."),1);
//判断文件后缀与类型,合法才进行上传操作
if(($fileext == "jpg") && ($filetype=="image/jpeg")){
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefromjpeg($target_path);
if($im == false){
$msg = "该文件不是jpg格式的图片!";
@unlink($target_path);
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".jpg";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagejpeg($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {
$msg = "上传出错!";
}
}else if(($fileext == "png") && ($filetype=="image/png")){
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefrompng($target_path);
if($im == false){
$msg = "该文件不是png格式的图片!";
@unlink($target_path);
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".png";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagepng($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {
$msg = "上传出错!";
}
}else if(($fileext == "gif") && ($filetype=="image/gif")){
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefromgif($target_path);
if($im == false){
$msg = "该文件不是gif格式的图片!";
@unlink($target_path);
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".gif";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagegif($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {
$msg = "上传出错!";
}
}else{
$msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
}
}
分析:
该php代码中允许上传图片,但会对图片进行二次渲染,因此我们需要绕过二次渲染的部分,也就是在在二次渲染不会改变的部分加入我们需要的php木马的代码
满足move_uploaded_file就可以上传成功!!!
实操如下:
我们需要安装winhex软件,在winhex中打开图片,首先我们需要准备一个木马图(操作步骤和第13关一致),文件名后缀为gif的图片,下面两张图是进行二次渲染(左边)之后的和未进行二次渲染(右边)的图片的内容,因为制作图片马时,PHP代码放在了最后,在进行二次渲染时,该代码部分被改变了。
对比两张图片的内容,很容易在靠近头部的位置有很多位置是是二次渲染之后没有改变的部分,那么我们就可以尝试将我们的Php木马写入这段区间中喽!(注意:不要在头部插入Php代码,会破坏gif文件头,验证图片会失败,就上传不了图片喽)
将php代码隐藏在二次渲染不会改变的部分
再次将隐藏好Php代码的图片进行上传,发现该区间没有被改变,因此,图片马上传成功。
接下来就是使用Include.php包含漏洞的原理进行解析该图片马,成功啦啦啦!!!
pass-17
源码
$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 = '上传出错!';
}
}
科普:
条件竞争漏洞是一种服务器端的漏洞,是由于开发者设计应用程序并发处理时操作逻辑不合理而造成。当应用面临高并发的请求时未能同步好所有请求,导致请求与请求之间产生等待时出现逻辑缺陷。该漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。
分析:
从源码看,服务器是将上传的文件保存下来,在对该文件的后缀名与白名单中的进行比较,若果为白名单中的后缀名,就会将文件进行重命名,否则,就会通过unlink()函数进行删除该文件。首先,代码执行过程是需要消耗时间的,因此我们要在上传的php文件被删除之前,成功的解析访问它,因此我们需要使用burp进行发送无限多的数据包,并使用python脚本去连接该文件,以此来判断该文件是否上传成功,并且在浏览器不停访问该文件的默认上传路径,一直不停刷新,直至访问成功,实验就成功啦啦啦!!!!
点击attack进行攻击,无限次发包
使用以下的python进行判断,当文件上传成功时,会出现ok
import requests # 第三方库
import os # 为了让屏幕停留导入的库
url = "http://localhost/upload-labs/upload/4.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
break
os.system('pause') # 停留
疯狂点击刷新,直至访问到该php文件