• 对文件上传的地方按照要求上传文件,查看返回结果(路径,提示等)
  • 尝试上传不同类型的“恶意文件”,比如xx.php文件,分析结果
  • 查看html源码,看是否通过js在前端做了上传限制,可以绕过
  • 尝试使用不同方式进行绕过:黑名单绕过/MIME类型绕过/目录0x00截断绕过等
  • 猜测或者结合其他漏洞(比如敏感信息泄露等)得到木马路径,连接测试
  • Pass 1-JS脚本

    上传脚本,提示文件类型不对,可能是前端js脚本检验文件

    查看源代码,限制上传文件后缀名

    可以通过burpsuite阻断抓包修改文件后缀名

    将脚本修改为png,阻断抓包修改文件后缀名,转发给服务器

    验证上传脚本

    通过火狐中插件Script Blocker Ultimate,阻止js脚本运行

    选择脚本进行上传

    验证上传脚本

    Pass 2-Content-Type

    上传脚本,文件类型不正确,可能是前端js脚本检验文件

    查看源代码,检验上传文件媒体类型,

    方法一(步骤同上)

    先将脚本后缀名修改为png,通过burpsuite阻断抓包修改文件后缀名

    通过burpsuite阻断抓包修改文件媒体类型

    选择脚本进行上传,阻断抓包将Content-Type:修改为image/png,转发给服务器

    验证上传脚本

    Pass 3-黑名单

    上传脚本,不允许上传.asp,.aspx,.php,.jsp后缀文件!,可能是前端js脚本设置黑名单

    查看源代码,分析源代码

    设置文件后缀名黑名单,先删除文件末尾的点,在将文件后缀分离

    将文件后缀名转成小写(不能进行后缀名大小写绕过黑名单)

    去除字符串::$DATA(不能通过后缀名::$DATA绕过黑名单)----(这个绕过方法只适用于windows系统,在window的时候如果文件名+"::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名)

    最后将过滤的后缀名对照黑名单进行判断

    末尾去空格(不能通过末尾加空格绕过黑名单)

    修改上传文件名,进行存储

    通过使用黑名单之外的可以被解析的后缀名,进行绕过

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

    AddType application/x-httpd-php .php .phtml .php2 .php3 .php4 .php5 .phpt
    

    ::$D::$DATAATA

    网站的js脚本只进行一遍过滤,通过::$DATA嵌套的方式,绕过上传检验

    可以通过burpsuite阻断抓包修改文件名+::$D::$DATAATA

    js脚本::$DATA将替换成空格,但是只是替换一次,::$DATA绕过黑名单依然有效

    验证上传脚本时,将链接中::$DATA去掉

    Pass 4-.htaccess

    上传脚本,此文件不允许上传!

    查看源代码,检验脚本除黑名单增加后缀名,代码几乎一致

    还是存在着黑名单过滤,所以需要找到黑名单之外的一个文件后缀

    找到的就是.htaccess文件,可以重写规则

    htaccess文件:是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

    .htaccess文件生效,

    需要两个条件

    一、在Apache的配置文件中写上:AllowOverride All

    二、Apache要加载mod_Rewrite模块

    原理:他没有过滤 .htaccess后缀,我们可以构建一个htaccess配置文件,让所有格式文件都解析为php,然后再上传图片马(只要后缀是允许的,随便都可以)就会被解析了。

    上传.htaccess文件

    上传图片木马

    验证上传脚本

    Pass 5(适用于php-nts版本).user.ini

    上传脚本,此文件类型不允许上传!

    查看源代码,检验脚本除黑名单增加后缀名,代码几乎一致

    上传.user.ini配置文件,在当前目录下生效,将1.gif包含到文件夹中php文件中

    将脚本修改为1.gif,进行上传

    打开文件夹中readme.php,验证上传脚本

    Pass 6-大小写绕过

    上传脚本,此文件类型不允许上传!

    查看源代码,没有进行后缀名的大小写绕过

    将脚本后缀名修改为.Php,进行绕过,转发给服务器

    验证上传脚本

    Pass 7-空格绕过

    上传脚本,此文件类型不允许上传!

    查看源代码,没有对首尾的空格进行限制

    Pass 3的方法二

    网站的js脚本没有对首尾的空格进行限制

    可以通过burpsuite阻断抓包将文件修改文件名+空格,绕过黑名单

    选择脚本进行上传,进行抓包,修改

    验证上传脚本

    Pass 8-点号绕过

    查看源代码,没有去除末尾的点

    网站的js脚本没有对末尾的点进行限制

    可以通过burpsuite阻断抓包将文件修改文件名+.,绕过黑名单

    选择脚本进行上传,进行抓包,修改

    验证上传脚本

    Pass 9-::$DATA

    查看源代码

    没有对::$DATA进行限制,同PASS 3 方法一,但是不用进行嵌套

    Pass 10-.点空格点绕过

    查看源代码

    删除末尾的点,以点切割后缀名,去空格,去::$DATA,最后用的删除末尾的点的文件名

    原理同Pass 7 方法二,将文件名修改为文件名. .,即可绕过

    Pass 11-(黑名单验证,双写绕过)

    查看源代码

    将符合的字符串,替换为空,可以通过后缀名嵌套,绕过

    例如:555.pphphp

    Pass 12-GET-%00

    查看源代码,设置白名单

    漏洞利用条件

    截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

    1、php版本小于5.3.4

    2、php的magic_quotes_gpc为OFF状态

    白名单判断,但$img_path是直接拼接,因此可以利用%00截断绕过。

    Pass 13-POST-%00

    查看源代码

    与Pass-12的区别是这里使用POST传地址

    为何POST型需要进行URL编码:

    这是因为 %00 截断在 GET 中被 url 解码之后是空字符。

    但是在 POST 中 %00 不会被 url 解码,

    所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。

    Pass 14-图片马绕过

    查看源代码,只检查前两个字节,判断是否图片,并将判断的图片类型作为文件

    伪造头部GIF89A

    在脚本第一行写上GIF89a,将脚本伪造gif文件

    将图片和脚本合成新的图片

    Cmd: copy /b 6png + 111.php ccc.png

    使用010Editor软件在图片中写入脚本

    结合文件包含漏洞,进行利用

    http://localhost/upload-labs-master/include.php?file=./upload/3120210813181355.jpg

    Pass 15-图片马绕过

    方法同Pass 14

    Pass 16-图片马绕过

    方法同Pass 14

    注:适用于php-nts版本,需要勾选php扩展php_exif

    Pass 17-图片马加二次渲染

    二次渲染后的图片,使用用户上传图片生成的新图片,上传图片,和原图片对照,将脚本插在未被渲染的位置

    Pass 18-白名单验证-条件竞争

    直接上传图片马

    当我们上传webshell后,没有第一时间做文件后缀名的校验,而是临时存放,移动到新位置后,再做文件名检验。

    这时系统代码执行过程会有时间消耗,我们利用这个极短的时间,利用Burp进行发包和范文,就有可能访问到没来得及做文件校验的webshell

    1.php 执行php在创建一个php文件

    使用burp suite分别抓取上传文件和打开上传文件地址的数据包,传到Intruder模块,设置数据包无限重发

    上传文件数据包

    手工打开浏览器快速点击URL访问1.php,抓取数据包

    http://localhost/upload-labs-master/upload/1.php 上传文件地址

    将两个数据包进行无限重发

    访问http://localhost/upload-labs-master/upload/shell.php

    Pass 19-白名单验证-图片马

    验证过程:依次检查文件是否存在、文件名是否可写、检查后缀(白名单)、检查文件大小、检查临时文件存在、保存到临时目录里、然后再重命名

    直接上传图片马

    Pass 20-代码审计-黑名单验证-点号绕过

    pathinfo($file_name,PATHINFO_EXTENSION)

    获取获取上传文件后缀名

    pathinfo(string $path [,int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME])

    返回一个关联数组包含有path的信息。返回关联数组还是字符串取决于options

    PATHINFO_DIRNAME:文件所在目录

    PATHINFO_BASENAME:文件+后缀名

    PATHINFO_EXTENSION:后缀名

    PATHINFO_FILENAME:文件名

    方法一( . 绕过)

    使用 . 进行绕过文件后缀名检查

    http://localhost/upload-labs-master/upload/111.Php.

    方法二(post的%00截断)

    截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

    方法三(适用于php-nts版本)

    上传.user.ini配置文件,将1.gif包含到php文件中

    Pass 21-代码审计-白名单验证-数组绕过

    验证过程:先检查MIME,通过后检查文件名,保存名称为空的就用上传的文件名。再判断文件名是否是array数组,不是的话就用explode()函数通过.号分割成数组。然后获取最后一个,也就是后缀名,进行白名单验证。不符合就报错,符合就拼接数组的第一个和最后一个作为文件名,保存。

    绕过过程:绕过MIMIE,改一下包的Content-Type,为了绕过explode()函数,需要传入数组,绕过白名单,由于取的是end()也就是数组最后一个,需要传入数组的最后一个为jpg|png|gif,最后是拼接文件名,取的是reset()第一个,即索引为0,和索引count()-1(数组内元素个数-1)。所以令索引0为1.php,索引2为jpg(只要是索引1之后都可),这样数组元素个数为2,拼接的就是索引0和索引1,也就是1.php和空,结果还是1.php,这样就可以使得拼接后的文件名为1.php。如下:

    1、黑白名单;

    2、对上传的文件重命名,不易被猜测;

    3、对上传的内容进行读取检查;

    4、不要暴露上传文件的位置;

    5、禁用上传文件的执行权限;