本記事は、オライリージャパンから発行されている「サイバーセキュリティプログラミング ―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や権限が設定されていないファイルをうまく書き換えれることができれば、その権限で様々なスクリプトを実行することが可能となります。