Engineering Note

プログラミングなどの技術的なメモ

10.4 競合状態に勝つ (サイバーセキュリティプログラミング Pythonで学ぶハッカーの思考)

本記事は、オライリージャパンから発行されている「サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考(原題:Black Hat Python)」の学習メモとして、書籍ではPython2で書かれていますが、自分なりに解釈した上でPython3に書き直しをしています。 

今回は、特定のディレクトリ内でのファイル変更(ファイル操作)の検知方法について学んでいきます。

 

 

Windowsの一時ディレクトリについて

Windowsには"C:\Windows"ディレクトリの中に"Temp"というディレクトリが存在します。

これはソフトウェアのアップデートなどで、一時的に使用するファイルを作成したりするための用途として使われ、不要になると削除されてしまうものが殆どです。

また、Windowsの「ファイル名を指定して実行」やコマンドプロンプトのcdコマンドに"%temp%"を指定すると、ローカルのTempフォルダに移動できます。

今回作成したスクリプトで同ディレクトリを監視していると、短時間で様々なファイルの作成や更新および削除の操作が確認できます。

 

Pythonでファイル変更を検知する

以下が今回作成するスクリプトとなります。

 

# file_monitor.py
import tempfile
import threading
import win32file
import win32con
import os

dirs_to_monitor = ["test"]

FILE_CREATED = 1
FILE_DELETED = 2
FILE_MODIFIED = 3
FILE_RENAMED_FROM = 4
FILE_RENAMED_TO = 5

def start_monitor(path_to_watch):
    FILE_LIST_DIRECTORY = 0x0001
    h_directory = win32file.CreateFile(
        path_to_watch,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None)
    while True:
        try:
            results = win32file.ReadDirectoryChangesW(
                h_directory,
                1024,
                True,
                win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
                win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
                win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
                win32con.FILE_NOTIFY_CHANGE_SIZE |
                win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
                win32con.FILE_NOTIFY_CHANGE_SECURITY,
                None,
                None)
            for action, file_name in results:
                full_filename = os.path.join(path_to_watch, file_name)

                if action == FILE_CREATED:
                    print("[ + ] Created {}".format(full_filename))
                elif action == FILE_DELETED:
                    print("[ - ] Deleted {}".format(full_filename))
                elif action == FILE_MODIFIED:
                    print("[ * ] Modified {}".format(full_filename))

                    print("[vvv] Dumping contents...")
                    try:
                        with open(full_filename, "r") as f:
                            contents = f.read()
                        print(contents)
                        print("[^^^] Dump complete.")
                    except:
                        print("[!!!] Failed.")
                elif action == FILE_RENAMED_FROM:
                    print("[ > ] Renamed from: {}".format(full_filename))
                elif action == FILE_RENAMED_TO:
                    print("[ < ] Renamed to: {}".format(full_filename))
                else:
                    print("[???] Unknown: {}".format(full_filename))
        except:
            pass

for path in dirs_to_monitor:
    monitor_thread = threading.Thread(target=start_monitor, args=[path])
    print("Spawning monitoring thread for path: {}".format(path))
    monitor_thread.start()

 

動作確認

それでは、上記で作成したプロセスを実行してみます。

 

 > python file_monitor.py
 Spawning monitoring thread for path: test

 

今回はtestディレクトリを作成し、その中でファイルの作成、追記および削除を行ってみます。

 

 > echo hello > test.txt
 > echo hello >> test.txt
 > rm test.txt

 

上記で行ったファイル変更が以下のように検知できました。

 

 [ + ] Created test\test.txt
 [ * ] Modified test\test.txt
 [vvv] Dumping contents...
 h e l l o


 [^^^] Dump complete.
 [ * ] Modified test\test.txt
 [vvv] Dumping contents...
 h e l l o

  h e l l o


 [^^^] Dump complete.
 [ - ] Deleted test\test.txt

 

 

最後に

今回は特定のディレクトリ内でのファイル変更を検知する方法について学びました。

これらのファイルを監視し、適切なACLや権限が設定されていないファイルをうまく書き換えれることができれば、その権限で様々なスクリプトを実行することが可能となります。

 

参考書籍

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考