软件安全性测试(连载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 转义清单

Ø &->&amp;

Ø <->&lt;

Ø >->&gt;

l 转移函数

Ø Encode.forXmlContent(userData)。

l 例子与说明

<name>Encode.forXmlContent(userData)</name>

2)编码内容:XML属性

l 转义清单

Ø &->&amp;

Ø <->%lt;

Ø "->&#34

Ø '->&#39

l 转移函数

Ø Encode.forXmlContent(userData)。

l 例子与说明

<nameid=Encode.forXmlContent(userData)>XXX</name>

3)编码内容:XML内容和属性

l 转义清单

Ø &->&amp

Ø <->&lt;

Ø >->&gt;

Ø "->&#34

Ø '->&#39

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注入就成为。

&lt;adminid=&#346&#34&gt;

&lt;>name &gt; hack</name&gt;

&lt; password &gt; c331… 2059&lt;/password&gt;

&lt;/admin &gt;

这样就不可以用创建的用户登录了。

案例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 (转义号)——> \。