软件安全性测试(连载12)
- 2020 年 2 月 10 日
- 筆記
2.6其他代码注入
除了XSS注入外,还存在XML注入、JSON注入和XPath注入三种代码注入情形。
1. XML注入
XML注入是指将恶意代码注入到XML文件中,比如存在一个user.xml表。
… <admin id="1"> <username>admin</username> <password>a384b6463fc216a5f8ecb6670f86456a</password> </admin> <admin id="5"> <username>root</username> <password>eb89f40da6a539dd1b1776e522459763</password> </admin> …
其中记录的信息是登录到某个系统的用户名和密码账号信息。假设有这么一段信息被注入进来,这个黑客就很容易进入系统,从而带来威胁。
<adminid="6"> <username>hack</username> <password>c331 … 2059 </password> </admin> 这样这段HTML文本变为。 … <admin id="1"> <username>admin</username> <password>a384b6463fc216a5f8ecb6670f86456a</password> </admin> <admin id="5"> <username>root</username> <password>eb89f40da6a539dd1b1776e522459763</password> </admin> <admin id="6"> <username>hack</username> <password>c331 … 2059</password> </admin> …
黑客可以利用嵌入的用户名和密码登录(注:正如1.5-1所示,基于MD5加密的密文可以通过“彩虹表”软件来破译)。
对于XML的防御措施主要通过对特殊字符的转义。再来看一下OWASP 的ESAPI函数是如何来实现XML转义的。
1)编码内容:XML内容
l 转义清单
Ø &->&
Ø <-><
Ø >->>
l 转移函数
Ø Encode.forXmlContent(userData)。
l 例子与说明
<name>Encode.forXmlContent(userData)</name>
2)编码内容:XML属性
l 转义清单
Ø &->&
Ø <->%lt;
Ø "->"
Ø '->'
l 转移函数
Ø Encode.forXmlContent(userData)。
l 例子与说明
<nameid=Encode.forXmlContent(userData)>XXX</name>
3)编码内容:XML内容和属性
l 转义清单
Ø &->&
Ø <-><
Ø >->>
Ø "->"
Ø '->'
l 转移函数
Ø Encode.forXml (userData)。
l 例子与说明
<name>Encode.forXml(userData)</name>
4)编码内容:XML注释
l 转义清单
Ø 无效字符->空格
Ø —>-
l 转移函数
Ø Encode.forXmlComment(comment)。
l 例子与说明
<!–"+Encode.forXmlComment(comment)+"–>
5)编码内容:XML的DTD
l 转义清单
Ø 非法字符->空格
Ø 终止符:]]>->]]]]><!CDAT[>
l 转移函数
Ø Encode.forCDATA(…)。
l 例子与说明
<xml-data><![CDATA[<%=Encode.forCDATA(…)%>]]></xma-data>
经过转码,上面的XML注入就成为。
…
<adminid=Ś">
<>name > hack</name>
< password > c331… 2059</password>
</admin >
…
这样就不可以用创建的用户登录了。
案例4-1 XML注入
注册界面,用户名与密码存储在user.xml文件中。网站采用jsp+javabean格式。Javabean代码如下。
import java.io.File; import java.io.FileWriter; public addUser(Stringusername,String password) throws Exception{ File file= newFile("user.xml"); FileWriter filewriter = newFileWriter(file); String xml_cointent="<?xmlversion="1.0" encode="UTF-8">n" +"<root>n"+ "<user>n"+ "<username>"+ username+"</username>n"+ "<password>"+password+"</password>n"+ "</user>n"+ "</root>n"; filewriter.write(xml_cointent); filewriter.flush(); filewriter.close(); }
当用户输入用户名Jerry,密码123456,user.xml如下。
<?xml version="1.0"encode="UTF-8"> <root> <user> <username>Jerry</username> <password>123456</password> </user> </root> 如果用户输入用户名Jerry,密码123456</password>n<role>admin</role>n<password>,密码123456,user.xml就变成。 <?xml version="1.0"encode="UTF-8"> <root> <user> <username>Jerry</username> <password>123456</password> <role>admin</role> <password></password> </user> </root>
从而达到了XML注入的目的。(当然,专业的注册方法没有那么简单,这里仅仅作为XML注入进行介绍)。
2. XPath注入
XPath是定位DOM树的一门技术(关于DOM树在2.1-1 XSS分类,DOM型 XSS中介绍过)。利用XPath可以查询XML中的元素。
案例4-2 XPath注入
系统用户名密码存在如案例4-1所在的user.xml中。通过页面的登录程序实现登录功能。JAVA代码如下。
importjava.io.File; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; public boolean login(String username,String password) throws Exception{ SAXReadersax=new SAXReader(); Documentdocument=sax.read(new File(".\user.xml")); Stringxpath ="//user[username/text()='+username+'andpassword/text()='+password+']"; List<Node>nodes= document.selectNodes(xpath); inti=0 for(Node node:nodes){ if(node instanceof Element){ Elementelement=(Element) node; System.out.println("Id:"+element.attributeValue("id")); System.out.println("UserName:"+element.elementText("username")); System.out.println("Password:"+element.elementText("password")); i++ } if(i==0){returnfalse;} else{return true;} } } 当输入用户名Jerry,密码123456,登录正确。但是当用户输入用户名Hack,密码myadmin' or '1'='1,如SQL注入一样仍旧可以登录。输出所有的记录。 Id:1 UserName:admin Password:myadmin6548 Id:2 UserName:root Password:qwert Id:3 UserName:jerry Password:123456 运行上面的代码需要以下四个jar文件。 l dom4j-1.6.1.jar。 l jaxen-1.1-beta-6.jar。 l log4j-1.2.16.jar。 l slf4j-nop-1.5.8.jar。
对于XPath可以通过以下方式进行。
l 对用户的输入进行合理验证,对特殊字符(如<、>、'、"等)等进行转义。过滤可以在客户端和服务端两边实现,如果可能的话,建议两者同时进行过滤OWASP的ESAPI提供了encodeForXPATH()方法。
对上面的。
String xpath="//user[username/text()='jerry'and password/text()=' or'1'='1']";
加入encodeForXPATH()方法,成为。
String encode_xpath = ESAPI.encode().encodeForXPATH("username/text()='jerry'andpassword/text()=' or '1'='1'");
String xpath ="//user/name[text()='"+ encode_xpath+'"]";
l 创建一份安全字符白名单,确保 XPath 查询中由用户控制的数值完全来自于预定的字符集合,不包含任何 XPath元字符。
l 使用源代码静态分析工具,进行自动化的检测,可以有效的发现源代码中的XPath 注入问题。
可以看见XML注入存在于写XML文件,而XPath注入在于查询XML文件,后面介绍的XXE漏洞是对XML实体变量的读取。
3. JSON注入
JSON代码如下。
{"users":[ {"username":"admin","password":"123456","email":"[email protected]"} {"username":"root","password":"root","email":"[email protected]"} {"username":"hack","password":"aabbccd","email":"[email protected]"} {"username":"jerry","password":"hzynk","email":"[email protected]"} ]}
假设仍旧为用户注册,用户名和密码存在JSON文件中,按照案例4-1的思路,就会产生JSON注入,在这里不做更多地介绍。
防止JOSN注入的方法很简单,只需要对以下两个字符进行转义。
l "(双引号)——>"。
l (转义号)——> \。