文件上传漏洞练习 upload-labs(1~5)【入门】
写在前面&知识补充
文件上传是个常见的漏洞,也是CTF的考察点之一。环境的搭建较为简单,放出链接: https://github.com/c0ny1/upload-labs 因为隐私和网络安全特殊性,演示至木马上传成功为止,不过我自己会链接验证,保证更高的可用性 我直接使用Windows集成包,放在php下面跑就行。
这里补充一点一句话木马的知识,众所周知,一句话木马有很多种形式 【基本原理】利用文件上传漏洞,往目标网站中上传一句话木马,然后你就可以在本地通过中国菜刀chopper.exe即可获取和控制整个网站目录。@表示后面即使执行错误,也不报错。eval()函数表示括号内的语句字符串什么的全都当做代码执行。POST[‘attack’]表示从页面中获得attack这个参数值。 就表示你用post传参,可以使用attack=…来使用php函数,对服务器文件进行修改或查看。 可以使用eval表示将字符串变成可执行的语句,system表示使用系统函数,那么你就可以使用你的权限直接使用linux命令,还有java版本等等,这里就不细说了。 使用菜刀连接,推荐使用$POST,eval,php形式。 图片木马:如果你没有相关工具,可以直接使用copy加命令行方式。当然你需要在目录下存放图片和木马,并且要切换至cmd (powershell的copy不支持+号) (如果你之前使用过dvwa,而现在你在win下搭建php环境并开始练习,这里有很大不同,简单说几点,win下的平台搭建会有一般的安全选项,你无法之间通过 url传指定参数查看相应的值;无法直接解析php3等向下兼容拓展名,需要更改配置文件;你无法让目标直接在网页上回显,一般发现有解析不了的文件都会有错误处理。如果你想完成整体渗透流程,需要多查查资料)
来吧,现在就开始。
Pass-01
这是一个最为常见的js过滤,即只能使用图片格式的后缀,否则不予上传。 方法一:先将脚本的后缀改为.jpg再上传,随后抓包改回来。 更改前: 更改后: 仅仅是修改了后缀(倒数第二排) 这个靶场会对上传图片进行回显,说明上传成功。 连接效果: 方法二: js是前端的限制,前端限制相当于没有限制,我们给它改一改 打开检查,非常明显可以看到这里有一个check函数: 禁用js 现在你可以直接上传脚本了。
Pass-02
使用上个Pass的方法一就行,但这里的原理不同,这里的检查是MIME检查,需要更改的是包中的Content-Type值,修改为:image/jpeg,相关知识请搜索MIME,这也是非常常规的检测方法。
Pass-03
这里,我们来分析一次源码(后面不会再分析):
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext);
$file_ext = str_ireplace('::$DATA', '', $file_ext);
$file_ext = trim($file_ext);
if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
trim 函数能够对上传文件的空格,换行符等多余字符进行删除,返回修改后的字符,deldot删除文件名末尾的点,都是对文件名进行优化。 strrchr() 函数能够查找子字符串在字符串最后一次出现的位置(r即最右的值),返回该字符串到整体字符串结尾的所有字符。这里是返回上传文件的最后一个后缀名。 strtolower() 函数能够将这最后一个后缀名全部转换为小写。 str_ireplace() 函数能够实现字符串的部分替换,它的三个参数分别为‘查找值’;‘替换值’;‘待查找字符串’ in_array() 就是在数组中搜索值,第一个参数为搜索值,第二个参数为搜索范围 除去第一个条件判断是否有上传路径,通过提示和查看源码可以发现,服务器设置了一个黑名单 [‘tmp_name’] 是服务器端储存的临时文件名 date() 能够格式化本地日期和时间,并返回已格式化的日期字符串,具体返回值与给定format值有关。 move_uploaded_file() 即将文件移至相应位置。 这里的上传路径由时间,随机数,最后一个后缀组成。 大概理解就是: 当浏览器将文件提交到服务器端的时候,服务器端会根据设定的黑白名单对浏览器提交上来的文件扩展名进行检测,如果上传的文件扩展名不符合黑名单的限制,则不予上传,否则上传成功。 那么, 绕过方法: 1. 可以通过上传不受欢迎的php扩展来绕过黑名单。例如:pht,phpt,phtml,php3,php4,php5,php6,这些扩展名也是可以解析的。不过apache是不会默认能够解析上述内容,你还需要在配置环境中调一调httpd.conf 注意一个细节是它这里会加一个随机数,但是它会回显,这样你可以直接看到它的名称,你在连接管理工具时注意修正一下。你也可以使用复制图片链接,然后在新网页窗口打开即可。 通过源码,你可以明白: 2. 或许你会想是否能够大小写混写绕过,这里通过源码可以看到它会全部转换为小写,无法绕过。 3. 能否使用 Apache解析漏洞(一定环境):将一句话木马的文件名【evil.php】,改成【evil.php.abc】(奇怪的不被解析的后缀名都行)。首先,服务器验证文件扩展名的时候,验证的是【.abc】,首先只要该扩展名符合服务器端黑白名单规则,即可上传。另外,当在浏览器端访问该文件时,Apache如果解析不【.abc】扩展名,会向前寻找可解析的扩展名,即【.php】,确实这个方法能够正常在浏览器访问并解析,但真正上传时,是使用源码的文件储存方式,由于筛选的最后一个后缀,上传到服务器后就只剩下【.abc】后缀了,无法连接,所以无法绕过。 4. .重写规则覆盖,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。一般.htaccess可以用来留后门和针对黑名单绕过。上传覆盖.htaccess文件,重写解析规则,将上传的带有脚本马的图片以脚本方式解析。.htaccess文件内容如下:
<FilesMatch "*.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
此时再上传一个.jpg就可以被当作php处理。 如同前面的问题,你需要抓包将名字改为.htaccess,否则被重命名为带时间的奇奇怪怪的名字.
(这里有一个小问题,在第四关和第三关的源码中,它们只有黑名单不同,我没有看到什么异常,但是在第三题是无法上传.htaccess文件的,会强制变为含日期的文件名,但第四题就可以上传这种文件,我暂时没弄明白,希望有人帮我解答下。)
说了非常多,第三题的考点就是在于使用php3等格式进行绕过。 由于需要修改配置,实战情况较少,这里便不做演示。
Pass-04
就是上文提到的htaccess文件,明显可以无压力上传 再次备注:如果你想连接后台,你需要更改apache的选项,一般为了安全,apache是不会暴露这个漏洞的。
Pass-05
这里是较新的版本,不再是大小写绕过。 提示为: 这一关和04传.htaccess文件相似,过滤了.htaccess没有过滤.user.ini。 这里有几点需要注意一下: .htaccess文件只能用于apahce,不能用于iis和nginx等中间件 .user.ini只能用于Server API为FastCGI模式下,而正常情况下apache不是运行在此模块下的。 .htaccess和.user.ini都只能用于访问本目录下的文件时进行覆盖。
.user.ini不能修改以下属性
PHP_INI_USER 可在用户脚本(例如 ini_set())或 Windows 注册表(自 PHP 5.3 起)以及 .user.ini 中设定
PHP_INI_PERDIR 可在 php.ini,.htaccess 或 httpd.conf 中设定
PHP_INI_SYSTEM 可在 php.ini 或 httpd.conf 中设定
PHP_INI_ALL 可在任何地方设定
这里我们要更改的设置就是是否文件包含 参数分别为:
auto_append_file
auto_prepend_file
这两个都可以使用,属于php中的自动包含文件功能,append是文件执行后包含,prepend是文件执行前包含。
那么就可以利用这两个设置来实现上传.user.ini来加载文件进行包含
写入:
auto_prepend_file=1.gif
上传该.user.ini文件 随后上传你提到的这个1.gif,一句话木马改后缀就行。 现在你上传情况至少是这样的: 你可以在网页端访问看看是否上传成功。 在连接前且慢 你可能需要等五分钟 因为在本身的php.ini文件中有这样一个参数 最后连接上去即可,连接时连到readme.php。
|