Python セキュリティ

Pythonを使ってハッキング用の情報収集ツールを作成してみよう

ペネトレーションテスターを目指す場合、言うまでもなくWeb側からのサイバー攻撃に対する手口を理解しておくことは重要な要素の一つですが、センシティブな内容のためかそれに言及している記事は非常に数が少ないです。また解説している記事があったとしてもそれは既存のツールの使い方に関するものがほとんどで、その仕組みや実装に関しては触れられることはほぼありません。

確かに多くの場合既存のツールを使えばできることをわざわざ実装する必要はないかもしれませんが、ペネトレーションテスト等の局面ではセキュリティの制約がある場面でツールのダウンロードを行えず、現状用意されている環境で情報収集を行わなくてはいけないこともあるでしょう。勿論Pythonを利用できる環境が用意されている保証もありませんが、昨今では自動化などでPythonをサーバにインストールしていることも多いため、今回の記事を理解することで情報収集方法の選択肢を増やすことに繋がります。またPythonがインストールされていなくとも、別のプログラミング言語が導入されていればここで理解した実装のアルゴリズムをそのまま転用できるかもしれません。

今回はPythonを使い不用意な情報がサーバ上に残されていないかをスキャンして、利用価値のありそうな情報を収集するためのツール作成を行っていきます。

実行環境

・Windows 10

・Python 3.10.2

・Pycharm 2022.1.4 (Community Edition)

今回の記事はペネトレーションテスト等、サイバーセキュリティ業務に従事している人へ向けた内容になっています。本記事の内容を商用環境に実施すると法律に問われる可能性がありますので悪用目的での利用は絶対に控えてください。

事前準備

1.ワードリストを取得

ランダムな文字列を生成して闇雲にスキャンしていては膨大な時間がかかります。そのため脆弱性診断などを目的として作られたワードリストを取得し、これを利用してスキャンを行います。こういった手法は辞書攻撃などと呼ばれています。

今回はinvictiという会社が公開しているワードリストを使いますがHPからダウンロードしようとすると404エラーが返ってきてしまったので、代わりにGitのアーカイブからall.txtをダウンロードしてきました。もし以下のリンクが使えなくなっていたり、ワードリストについて興味が出た人は「Web security Wordlist」などで検索して他にも使えそうなワードリストがないか調べてみてください。

https://www.invicti.com/blog/web-security/svn-digger-better-lists-for-forced-browsing/#
https://github.com/nathanmyee/SVNDigger/blob/master/SVNDigger/all.txt

all.txtが取得できたら適当な場所に保存しておきます。

2.テストスキャンの対象を確認

検証に使用するWebサイトはAcunetix社が公開している「http://testphp.vulnweb.com」という環境があるので、これに対してスキャンを実施します。公開されているWebサイトに対してスキャンを行うのは抵抗があるかもしれませんが、以下の通り「ペネトレーションテストや教育目的で使っても良いですよ。」と記載されているので安心して使用してください。

Warning: This site hosts intentionally vulnerable web applications. You can use these applications to understand how programming and configuration errors lead to security breaches. We created the site to help you test Acunetix but you may also use it for manual penetration testing or for educational purposes. It will help you learn about vulnerabilities such as SQL Injection, Cross-site Scripting (XSS), Cross-site Request Forgery (CSRF), and many more.

http://www.vulnweb.com/

情報収集ツールの概要とPythonソースコード

では準備が整ったところでツール作成の話に入っていきたいところですが、その前に今回の記事で最終的にどんなことができるようになるのか、概要を先に確認しておきます。冒頭でも記載しましたがこれから解説するのはサーバ上に想定外のファイルを残してしまってないかをスキャンするためのプログラムです。サーバや開発担当者のセキュリティ意識が低かったりすると、フォルダのアクセス制御ミスがあったり、開発時に作成したファイルがそのままサーバ上に残してしまったりすることがあります。

実際にスキャナーのコードを載せたうえで攻撃者に参考情報を与えてしまう事例を解説しますが、コードは後で詳しく解説するので安心してくださいね。

※wordlistのパスなどは適宜変更してください。

import queue
import requests
import threading
import sys

WORDLIST = r"C:\Users\owner\Desktop\Others\学習\Python\all.txt"
TARGET = "http://testphp.vulnweb.com"
THREAD_NUM = 30
urlList = queue.Queue()
threads = []

def getWords():
    words = queue.Queue()

    with open(WORDLIST) as f:
        wordList = f.read()

    for word in wordList.split():
        print(f'Loading words... {word}')
        words.put(word)

    return words

def bruteForce(words):
    while not words.empty():
        url = f'{TARGET}/{words.get()}'
        try:
            r = requests.get(url)
        except:
            sys.stderr.write('Oops, an error has occurred.')
            continue

        if r.status_code == 200:
            print(f'\nDetected! -> {url}')
            urlList.put(f'200 SUCCESS -> {url}')
        elif r.status_code == 404:
            print(f'.', end="")
        else:
            print(f'.', end="")
            urlList.put(f'[*] Check the following URL -> {url}, Status code: {r.status_code} ')

        if words.qsize() % 100 == 0:
            print(f"\n{words.qsize()} words remaining.")

if __name__ == '__main__':
    words = getWords()
    for _ in range(THREAD_NUM):
        t = threading.Thread(target=bruteForce, args=(words,))
        t.start()
        threads.append(t)

    for t in threads:
        t.join()

    while not urlList.empty():
        print(urlList.get())
スキャナーの実行結果

スキャナーを実行してしばらくたつと上記の通りサーバ上で閲覧できるファイルの一覧が出力されました。勿論公開を想定しているページであればアクセスできるのは当然なので何も気にする必要はありませんが、Webアプリやプラットフォームの脆弱性診断を行っていると開発時に残したと思われるファイルや、サーバに導入しているプロダクトの設定ファイルなど、攻撃者にヒントを与えてしまうようなファイルが残っていることがあります。上記の出力結果の中に「http://testphp.vulnweb.com/admin」というフォルダがありますが、少し怪しいのでこれを確認してみましょう。

URLをブラウザで直打ちしアクセスしてみたところサーバ上にあるフォルダの中身が表示されているようですね。「create.spl」という非常に興味深そうなファイルがあったので中身を確認してみます。

おぉっと、テーブル作成時のSQLでしょうか。テーブル構造が丸見えですね。もし対象サイトにSQLインジェクション等の脆弱性があった場合、このテーブルの中に必要な情報があればピンポイントで効率よく取得することができそうです。

他にも「http://testphp.vulnweb.com/pictures/」というURLが検出されていたのでこちらも確認してみました。

こちらも「credentials.txt」や「wp-config.bak」といった有益そうな情報が入っているファイルが表示されています。数が多いのでこれ以上の精査は行いませんが、気になる人は是非手元でも試してみてください。

ちなみに「credential.txt」にはファイル名の通りユーザ名とパスワードと思われる内容が記載されていました。「認証情報がもし管理者用アカウントだったらこれでサイトにログインして重要な設定を色々いじれるんじゃないか」「サーバ上の他のサービスでも同じ認証情報を使ってる可能性があるかもしれない」など、こちらも攻撃の参考となる情報を取得できてしまうことがお分かりいただけたかと思います。

ソースコードの詳細解説については別記事に続く。

-Python, セキュリティ