文件上传之闯关

https://github.com/c0ny1/upload-labs

黑名单

第一关 修改html代码

image-20220718140517704

# 游览器F12  删除 onsubmit  提交校验的语句,绕过前端限制 ,上传成功,shell拿到。

image-20220718140817891

第二关 修改游览器的content-type的类型 绕过mime包检查

image-20220718141504919

#后台代码判断 依据content-type 的文件类型,不符合的文件类型,不通过
# if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif'))
# 

修改游览器content-type 的文件类型,欺骗后端的逻辑认证。

第三关 上传特殊可解析后缀

黑名单: 不允许文件类型的文件上传。php  asp  py    
白名单: 只允许某一种或者几种文件的上传 比如 mime类型 TXT  tar jpg等等
不论白名单或者黑名单,如何绕过?都是绕过检测的手段。

黑名单的绕过就是 保证上传到文件和限制文件的类型不同,同时又能让web服务器的命令解释器解析执行。
               (比如 一个webshell.php变形123.php3 ,同时 命令解释器还可以执行123.php3)
    
白名单的绕过就是 保证上传到文件和限制文件的类型相同,同时又能让web服务器的命令解释器解析执行。
               (比如 一个webshell.png变形123.png ,同时 命令解释器还可以执行123.png)

web服务环境:
windows iis   
windows apache
windows nginx
linux  apache or nginx


本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!

明显一个黑名单的限制。

# php的配置可以识别 后缀名加数字的文件,比如 xx.php3 ,直接修改文件的后缀名,能绕过黑名单的限制

image-20220718145928052

image-20220718145853627

image-20220718151030240

当前php的配置文件,无法解析php43,当成了静态文件返回了游览器。

如何修改php参数,让解释器执行这个php3这个文件,

# php的某一些低版本的解释器是具有可以解释php3这个中文件的设置。


php动态修改配置文件 

第四关一个黑名单的限制 windows的iis特性 解析漏洞绕过。

提 示
关闭
本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.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后缀文件!
根据提示 代码把php asp 一些低版本的漏洞,过滤掉了。

针对黑名单,常见的就是 图片挂马
windows 上的iis服务解析漏洞 
会自动把文件中的特殊字符 ; 分号后面的内容丢弃。文件系统接收到文件后会过滤文件名,
webshell.php 加上 ;.jpg 组合成一个jpg格式的文件  ,上传到服务器上后,变成 webshell.php;.jpg  ----> webshell.php

image-20220718160924340

我使用了另外一个 iis  asp的环境模拟上传后的情况,查看webshell.asp;.jpg  iis服务可以执行webshll.asp文件

image-20220718162351528

windows+ php的特性  
会自动把文件中的特殊字符 : 分号后面的内容丢弃。文件系统接收到文件后会过滤文件名,
webshell.php 加上 :.jpg 组合成一个jpg格式的文件  ,上传到服务器上后,变成 webshell.php;.jpg  ----> webshell.php

image-20220718172702258

image-20220718172800677

证明: 使用windows 特殊符号不能应用于文件命名,使用:成功跳过逻辑代码。 
但是文件创建了,PHP代码没有追加进去。

使用特殊的追加内容符号,把内容追加进去

123.<   123.<<<   123.>>> 123.>><
实验一下

测试使用.>>> 能够追加进去内容

正常访问到 webshell

image-20220719103349258

image-20220719103527711

第五关 windows 特性对大小写不敏感

不严谨的说法  就是在windows系统上  1.PHP  1.PHp  1.Php  1.php 是同一个文件
那么黑名单的状态不一定都能包含所有的文件的变形
所以上传 一个 大小写的文件 绕过黑名单 是可行。

实验
# 游览器是可以获取到webshell 的

image-20220719104620034

image-20220719104657021

第六关 利用windows特性 文件命名 特性绕过

后台代码对于来源文件名,统一改成小写后上传
使用windows 的文件命名特性 1.php .  混淆后缀名,让后台代码提取的后缀名是空值,
# windows文件系统写入文件的时候因为不允许空格 点的存在,会自动把1.php . ---变形成--》 1.php

实验正常 获取到正常的weshell

image-20220719132932171

web.php::$DATA --特殊文件数据流


过黑名单 -- 利用文件命名的特殊性。

第七关 都是使用 点空格,或者空格点,混淆后缀名称,绕过黑名单

ubuntu 镜像下载
http://mirrors.aliyun.com/ubuntu-cdimage/releases/22.04/release

kali 镜像下载
https://mirrors.aliyun.com/kali-images/kali-2022.2/

rocky linux
https://rockylinux.org/download

历史版本下载
https://archive.kernel.org/

第八关 特殊文件数据流

web.php::$DATA --特殊文件数据流

过黑名单 -- 利用文件命名的特殊性。
成功上传 绕过

image-20220719133919106

第九关 点 空格 点 windows特性,后缀混淆

第十关 后台代码针对文件名称的后缀过滤机制

后台代码删除后缀名 的机制是 正则的匹配, 全部匹配成功后,删除匹配的
1.phpphpphpphp 针对字符的完全匹配删除,不存在匹配一次的就不匹配了
1.phphpp  ---- > 把php 分段隔开,完全匹配不上即可	

image-20220719135802157

对于文件名和后缀都在匹配的规则下

image-20220719150130469

白名单

第十一关 url数据包头 %00截断

PHP软件版本要低5.3.4一下,magic_quotes_gpc 关闭,才能实现这个漏洞-- 一般老网站才有这种漏洞

image-20220719180048272

# 不严谨的说法 可以这么理解
在上传目录中不光可以利用windows 文件的命名的特性
也可以使用windows 目录命名的特性
比如在拼接文件目录的时候,http://127.0.0.1/user/abc.txt%00  
在网络传输协议中,能够使用的特殊符号是因为游览器使用的url编码格式
windows文件系统的命名规则中没有和url编码 不兼容,所以就会存在目录和文件命名 不一样的现象出现。
比如目录拼接 123%00 这个字符串,操作系统命名目录时或者文件时,会自丢弃%00

# 严谨的说法
'''
%00截断 是使用在网络传输中的,网络传输使用使用ascll表进行编码的
在ascll编码中 %00 在编码中是0 的意思,而ascll表又把零 作为特殊字符保留,,作为字符串的结束含义,所以在url中出现%00 时,就代表url已经全部读取完毕了,所以称为00截断

0x00 是linux中的截断

/00  也是一种截断
'''


问题:  post http://127.0.0.1/user/123.php%00 



实验完全成功

# POST 请求的路径中有在最后一个/  后,就是文件名称+%00截断,没有该文件,会被新建,所携带的数据会被追加到该文件中。

image-20220719181632333

第十二关 url 数据体 16进制00 截断

在 POST请求中,  url 的请求头中没有具体的文件名,那么就一定在数据体中,针对请求体的修改让数据进行截断。达到上传到目的。

看图一 数据体中包含 form表单的  包含文件名称
单纯的修改请求体数据没有用,因为url 发送要进行编码,所以好的做法是进行16进制编码进行修改

image-20220720105544786

请求体中找到手动写入一个文件名称,空一个空格,为填入隔断符,创造条件

image-20220720110346683

观察 16进制 编码定位 空格,

image-20220720110520954

20 这个位置就是空格,更改为 16进制的 00截断

image-20220720110723684

空格已经被替换了

image-20220720111516192

上传成功!shell 正常访问

image-20220720112126125

此关开始组合手法上传

第十三 十四 十五关 上传文件内容检查 -- getinmagesize exif_imagetype 函数

随着对文件的校验的等级不断升级,单纯的对文件的类型判断满足不了,需求更新手段
对于文件来说,每一种类型的文件 通常的内容开头的值是不变的,比如
图片开头值是xxxx  ,那么后台代码decode 文件开头的数据, 对比是否一致确实是图片类型,才予以放行。
还有的做法是 把文件全部解码以后,对文件所有的内容进行扫描关键字,匹配,然后才放行。

'''
JPEG (jpg), 文件头:FFD8FF

PNG (png), 文件头:89504E47

GIF (gif), 文件头:47494638   GIF89a

TIFF (tif), 文件头:49492A00

Windows Bitmap ( bmp),文件头:424D

CAD (dwg), 文件头:41433130

Adobe Photoshop (psd), 文件头:38425053

Rich Text Format (rtf), 文件头:7B5C727466

XML (xml), 文件头:3C3F786D6C

HTML (html), 文件头:68746D6C3E

Email [thorough only] (eml), 文件头:44656C69766572792D646174653A

Outlook Express (dbx), 文件头:CFAD12FEC5FD746F

Outlook (pst), 文件头:2142444E

MS Word/Excel (xls.or.doc), 文件头:D0CF11E0

MS Access (mdb), 文件头:5374616E64617264204A

WordPerfect (wpd), 文件头:FF575043

Adobe Acrobat (pdf), 文件头:255044462D312E

Quicken (qdf), 文件头:AC9EBD8F

Windows Password (pwl), 文件头:E3828596

ZIP Archive (zip), 文件头:504B0304

RAR Archive (rar), 文件头:52617221

Wave (wav), 文件头:57415645

AVI (avi), 文件头:41564920

Real Audio (ram), 文件头:2E7261FD

Real Media (rm), 文件头:2E524D46

MPEG (mpg), 文件头:000001BA

MPEG (mpg), 文件头:000001B3

Quicktime (mov), 文件头:6D6F6F76

Windows Media (asf), 文件头:3026B2758E66CF11

MIDI (mid), 文件头:4D546864

'''

# 破解这种手段的方式,就是图片 + 木马整合成一个文件,进行把木马的字符串和图片的字符串进行交融杂糅,既让文件能够显示,又能绕过后台的检测机制,木马又能正常使用


具体的方式
#1、粗暴做法, 把木马的代码追加到文件的最后,躲避文件头的检测
 使用 copy  /b  1.png/b  muma.php/b  000.png   以二进制的方式整合成一个png文件 ,然后在结合利用 文件命名或者url编码 或者请求截断的方式,把后缀名更改成php
   比如  123.php.jpg  ----- 上传到服务端是123.php
 
逆向思维讲:  解释在 webshell.php木马中添加 图片属性的标志字符串,变形成 webshell.php.jpg 混淆服务端的检测,通过截断方式上传到服务端为webshell.php
   

#2、使用工具注入一句话木马  只是混淆服务端的检测的升级手段 ,无论怎么变形,该文件必须能被php解释器执行。
 使用工具把把木马程序随机的 注入到图片文件中的任意位置,躲避检查,提高上传成功的几率
    
此关 要求能上传即可 过关,
function getReailFileType($filename){
    $file = fopen($filename, "rb");
    $bin = fread($file, 2); //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);    
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
    $fileType = '';    
    switch($typeCode){      
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';
        }    
        return $fileType;
}
# 分析一下代码 getReailFileType函数 提取文件的2字节和自己的类型库做对比,作为新建文件的类型

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);

    if($file_type == 'unknown'){
        $msg = "文件未知,上传失败!";
    }else{
        $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传出错!";
        }
    }
}
# 把上传的文件读到临时文件中,以上传目录/ 10-99随机数--时间. func抓的内容的类型 。


'''
如何获取webshell  
    
因为文件的数据没有被改变,只是文件的后缀名被改了
要想办法 让php 识别gif文件就是 php 文件就能到达shell
'''
    

第十六关 二次渲染

梳理一下文件上传的流程防范流程
1、前端页面对文件进行限制 代码删除
2、post 请求中 截断 请求头 请求体 
3、利用系统文件命名特性,软件命名特性 ,游览器编码特性,使文件落地到系统中发生变形
以上方式都被防御后,针对内容变异
4、 注入标准文件头,绕过类型检测
5、文件内容的检测
针对文件内容进行二次渲染
大白话就是 把一句话木马或者其他代码 通过各种方式,各种编码注入到文件的不同位置去,
,
比如 使用 100个图片,分别注入一句话,哪个能够欺骗绕过,那么这个图片就代表注入成功   -- 笨方法

第十七关 文件上传的时间竞争

根据网站的规模不断的壮大,从原本的单机架构,到集群架构演变,CDN,负载均衡,反向代理,缓存系统,读写分离,MHA主从数据库等。
在为了追求效率的情况下,越来越多的文件上传对于代码检测的压力越来越大,相对的文件检测不再是实时性,变成异步检测 ,
具体的做法是 后台代码会文件做一个简单的检查,放到临时目录中,然后再去做内容检查,如果检查到恶意代码的话就会被删除。
'''
所以上传文件的数量和访问文件的时间 与 后台查杀代码,做一个时间的赛跑 
上传文件的并发量足够的大,使检查代码的队列处于满载状态,就能做到,
使用测试器 并发发包
使用测试器 并发请求访问的文件内容就  是创建一个木马文件,创建的文件逻辑代码不会检查,所以就能够是使用shell
'''

image-20220721154007413

第十八关 重命名竞争

apache 低版本对于 文件解析的漏洞
当一个文件 test.php.7z 时,他的判断逻辑是从右到左的,7z不认识,那就跳过,检查到php时,认识,那么就会把 这个文件当做 php文件进行解析。
所以这个shell 能够使用。

image-20220721160551132

image-20220721160815726

image-20220721161009430

第十九关 二进制 00 截断

抓包, 文件名 00截断

image-20220721162750271

第二十关 代码审计相关 (不会,保留!)

htacess文件

在上述渗透过程中,一般过白名单的方式,基本都是利用 系统 、软件的命名规则使 文件的后缀名变成 php
那么有没有方式让 iis  nginx  apache  自动认为不同后缀的文件都当成php文件来解析那
ok  那就是htaccess文件 (分布式配置文件) 能够让apache 识别不同后缀的文件当做 php文件解析 ,跟  7z文件有这异曲同工之妙。

.htaccess
'''
<FilesMatch "">
setHandler application/x-httpd-php
</FilesMatch>
'''

image-20220721175714603

posted @ 2019-04-11 22:17  mmszxc  阅读(316)  评论(0)    收藏  举报