イベントID 1029に記録されるユーザー名に注意
Microsoft-Windows-TerminalServices-RDPClient/OperationalのイベントID 1029に記録されるユーザー名について、単純には解析できなかったのでメモとして記録しておきます。
なお、本記事の内容は以下の記事とほぼ同じ内容なので、英語が得意な方はこちら👇を読むことをオススメします。
イベントID 1029の概要
イベントID 1029は、RDP接続を試行する際に接続元の端末に記録されます。
記録される内容は下図の通りで、接続しようとしたユーザー名をハッシュ化&エンコードした値が記録されます。
注意点として、存在しないユーザー名を入力した場合や、RDP接続に失敗した場合も記録されます。
イベントID 1029の解析
ログに Base64(SHA256(UserName)) is = …
と記載されているので、ユーザー名のSHA256を計算した後にBase64エンコードすればこの値が生成されると考えられます。
ということで、先ほどの例で使用した「TEST」を計算してみます。
…が、計算結果は
OTRlZTA1OTMzNWU1ODdlNTAxY2M0YmY5MDYxM2UwODE0ZjAwYTdiMDhiYzdjNjQ4ZmQ4NjVhMmFmNmEyMmNjMg==
となっており、イベントログに記録された値
zzV6ChUo2bTS/UpOyeSYs3PXpzH5m4DwLJuB+bpyHbY=
と明らかに異なります。
そこでイベントID 1029について調べてみたところ、どうやら実際は以下の流れで計算されていることが分かりました。
つまり、実際は Base64(SHA256binary(UTF-16LE(UserName))
と書いた方が正しいようです。( Base64(SHA256(UserName))
じゃ分からんやろ…)
ということで、 CyberChef で Base64(SHA256binary(UTF-16LE(UserName))
を計算してみたところ、ログの値と同じ結果になりました🎉
Pythonの場合は以下のようなコードで計算可能です。
import hashlib import base64 # 計算したいユーザー名 username = 'TEST' # UTF-16LEにエンコード utf16_username = username.encode('utf-16le') # SHA256を計算し、バイナリ形式で取得 hash_username = hashlib.sha256(utf16_username).digest() # Base64エンコード base64_username = base64.b64encode(hash_username) # UTF-8にデコード result = base64_username.decode('utf-8') print('ユーザー名: ' + username) print('Base64(SHA256binary(UTF-16LE(UserName)) is = ' + result)
上記のコードを実行すると以下のように出力されます。
まとめ
本記事ではMicrosoft-Windows-TerminalServices-RDPClient/OperationalのイベントID 1029に記録されるユーザー名の解析方法について紹介しました。
それにしても Base64(SHA256(UserName))
という表記はトラップすぎますね…。
ということで、イベントID 1029のユーザー名を解析する際はご注意ください。