狠狠撸

狠狠撸Share a Scribd company logo
NoSQL Injection~Redisの場合~
March 25, 2021 kataokaw
アジェンダ
? NoSQLとは
? 検証環境
? デモ
? ソースコード
? セキュアなコード
? 検査文字列の検討
? 参考
狈辞厂蚕尝ってなんぞや
NoSQLとは
RDBMSじゃないDBMS
NoSQLとは
? Not only SQL
->SQLに限定されない言語やインターフェースを用いる。Yes/Noではない
? 膨大な非構造化データを柔軟に扱える
->RDBMSのような厳密なスキーマ定義が不要
NoSQLとは
? キー値:
いわゆるKey-Value型とかいわれるやつ。シンプルでレスが早いらしい。
? ドキュメント:
上記概念の拡張版。PinPでいうパラメータをKey 、値のJSONをValueにしたイメージ。スキーマレス。
? 列指向:
1:nな2列?(Key-Value)のExcel。大量集計、大量更新が得意っぽい。
? グラフ:
Node(Entity)とedge(Relation)、property(左2つの属性情報)を管理する。ER図っぽい。
[Microsoft Azure - NoSQL Database - NoSQL とは] https://azure.microsoft.com/ja-jp/overview/nosql-database/
[Microsoft Docs -非リレーショナル データと NoSQL] https://docs.microsoft.com/ja-jp/azure/architecture/data-guide/big-data/non-relational-data
NoSQLいろいろ
[@IT - KVS系NoSQLのまとめ(Hibari、Dynamo、Voldemort、Riak編)] https://www.atmarkit.co.jp/ait/articles/1211/05/news007.html
何となく搁别诲颈蝉多い印象
Redisとは
? オンメモリ
? Key-Value型のデータ構造ストア
? DB、キャッシュ、メッセージブローカーとして利用可能
? セット、ビットマップ、HyperLogLog、地理空間インデックス、streamなどのデータ構造を提供
? サポート言語/ライブラリ
https://redis.io/clients
[redis - Introduction to Redis] https://redis.io/topics/introduction
RedisのNoSQLi
CTF TIME
https://ctftime.org/writeup/11816
Redis scripting language is LUA. All redis functions are callable by redis.call. Injection is
http://ctf.knastu.ru/webch/admin?n=123') and redis.call('get', 'admin
検証環境
ホスト
? Windows 10 Pro 1909
? Python 3.9.1
? redis 3.5.3
ゲスト(WSL2)
? Kali 2021.1
? Redis 6.0.10 64 bit
[Github -andymccurdy/redis-py] https://github.com/andymccurdy/redis-py#getting-started
デモ
ソースコード
pool = redis.ConnectionPool(host=‘IP', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
~省略~
def do_POST(self):
~省略~
q = parse_qs(param, keep_blank_values=1).get('q')[0]
lua = "return redis.call('SET', 'test', '%s’)” % q
multiply = r.register_script(lua)
try:
with open('./html/nosqli.html' , encoding='utf-8') as f:
html = f.read() % (q, multiply(), r.get('test’))
Redisへ接続
検査文字列
「') and redis.call('info」
↓
Lua Script
「return redis.call('SET', 'test', '') an
d redis.call('info')」
下線部でLua Scriptの実行
セキュアなコード
pool = redis.ConnectionPool(host=‘IP', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
~省略~
def do_POST(self):
~省略~
q = parse_qs(param, keep_blank_values=1).get('q')[0]
ret = r.set('test’, q)
try:
with open('./html/nosqli.html' , encoding='utf-8') as f:
html = f.read() % (q, multiply(), r.get('test’))
検査文字列 「‘) and redis.call(’info」 が
set関数によって、ただの文字列として扱われる
検査文字列の検討
? インジェクションできないコマンド例
Redisサーバのディレクトリ情報を取得するコマンド(lsコマンド相当)
「’) and redis.call(’config’, ’get’, ’dir」
↓
サーバエラーログ
->Redisのソースsentinel.cにおいて、
redisCommand構造体で「admin」や「no-auth」の要素を持つコマンドは実行できない
redis.exceptions.ResponseError: Error running script (call to
f_c1f38d90c20f2f994ed60271597f364280c952b4): @user_script:1:
@user_script: 1: This Redis command is not allowed from scripts
検査文字列の検討
127.0.0.1:6379> keys *
1) "dest"
2) "test1"
3) "test"
4) "key1"
5) "key2"
127.0.0.1:6379> del *
(integer) 0
127.0.0.1:6379> del _
(integer) 0
127.0.0.1:6379> del %
(integer) 0
127.0.0.1:6379> del key*
(integer) 0
127.0.0.1:6379> del dest
(integer) 1
127.0.0.1:6379> keys *
1) "test1"
2) "test"
3) "key1"
4) "key2"
? redis-cliによる全件削除可能性の確認
検査文字列の検討
redis.call()において、「and」は効き、以降のコマンドは無効化される。
つまり、ラジオボタン等で
lua = "return redis.call('%s’, 'test', '%s’)” % (operation, value)
課題
? 実装によって挙動が変わる
? JavaやPHPは、Pythonほどセキュアな関数設計になってないかも、逆もしかり。
? Pythonも利用するライブラリの設計によっては、Lua無しでいけるかも
? でも公式でRedisの推奨ライブラリを示しているし、全体的にセキュアかも
->https://redis.io/clients
参考
? [aredis - LUA Scripting] https://aredis.readthedocs.io/en/latest/scripting.html
? [Redis公式] https://redis.io/commands/
? [HackTricks - Pentesting Redis] https://book.hacktricks.xyz/pentesting/6379-pentesting-redis
? [sqreen – Redis injection] https://www.sqreen.com/plugins/redis-injection

More Related Content

NoSQLi(Redis)

Editor's Notes

  • #8: マスタ型:マスタノードが他のノードも管理、マスタが落ちると全部落ちる P2P型:すべてのノードが互いを補完、単一障害点を回避できる オンメモリ:データの永続性が保証されない オンディスク:複数サーバにDBを分割して保有するといった拡張性が無い