軟體安全性測試(連載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 (轉義號)——> \。