Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CCCamp_CTF__ALLES_CTF__2019.pdf

Xcyba17her
August 27, 2019

 CCCamp_CTF__ALLES_CTF__2019.pdf

1. Flag Converter Part1
2. Flag Converter Part2

Xcyba17her

August 27, 2019
Tweet

More Decks by Xcyba17her

Other Decks in Technology

Transcript

  1. 目次  FlagConverter (Forensics)  Part 1 (234 Solved, 43

    pts.)  Part 2 (18 solved, 215 pts.) 2
  2. どんな問題?  Part2のフラグは,メモリダンプに暗号化されている状態のフラ グがあり,それをさがす問題  フラグの暗号化を行ったプロセスが存在することが問題文から読 み取れるため,メモリダンプの分析を行う  Volatilityを使う 

    今回使用するのはvolatility_2.6_win64_standalone  実際に分析する際にコマンドプロンプト経由で使用したのは volatility_2.6_win64_standalone.exeであるが,省略して volatilityと表記することにする 7
  3. dllファイルを捜索する  volatility -f flagconverter.dmp --profile=Win7SP1x64 filescan | grep ¥¥Device¥¥HarddiskVolume2¥¥Users¥¥ALLES¥¥Desktop

     Crypto.dllが見つかる  一番上に表示されているCrypto.dllを抽出することを試みる 16
  4. dllファイルを抽出する  volatility -f flagconverter.dmp --profile=Win7SP1x64 dumpfiles --dump-dir [output_dir] -Q

    0x000000003e6495f0  抽出したものをTrIDNETで調べると,dllファイルの可能性が高い  Crypto.dllと名前を変えておく 17
  5. WindowsIdentity.GetCurrent ().User.GetBinaryForm関数  2316を実行できないので, WindowsIdentity.GetCurrent().User.GetBinaryForm関数によりSID のバイナリ表現がどうなのかをC#プログラムを書いてみて調べた  もちろんSIDのバイナリ表現には決まりがあり,それを読んでやってみてもよ かったが,初めてC#を書いてみたかった 

    C#のコンパイラは,僕の環境では次の場所にあった: C:¥Windows¥Microsoft.NET¥Framework¥v4.0.30319¥csc.exe  参考は,各C#入門サイトおよびと,WindowsIdentityクラスについて書 いてあるhttps://docs.microsoft.com/ja- jp/dotnet/api/system.security.principal.windowsidentity?vie w=netframework-4.8など 21
  6. SIDのバイナリ表現  書いたC#ソースコード 22 using System.Security.Principal; using System; public static

    class SidBinTest{ public static void Main(){ byte[] array = new byte[28]; SecurityIdentifier user = new SecurityIdentifier("S-1-5-21-2947568794-2193893069- 2968809547-1000"); user.GetBinaryForm(array, 0); for(int i = 0; i < 28; i++){ Console.Write(String.Format("{0:x2}", array[i])); } } }
  7. SIDのバイナリ表現  実行結果  求めるバイナリ表現は, 0105000000000005150000009a54b0afcd26c4824b70f4b0e8030 000  実はこれで28bytesの長さなので,function03で定義した28bytes の配列arrayにぴったり収まる

     SIDを単にASCII変換すると優に28bytesを超えているし,その28と いう数字がどこから来たものなのか競技中はずっと不思議に思って いた.もう少し掘り下げていれば解けていたのかもしれない…  これを用いてthis.byte_1とthis.byte_0は初期化されるがそこ はソルバに処理を書くことにする 23
  8. Crypto.function01関数の機能  Rijndael暗号のivとkeyとブロック長を指定している  Rijndael暗号はAESのもととなった暗号化方式で,Rijndaelの 鍵長およびブロック長を制限してAESとして規格化された?  https://www.atmarkit.co.jp/ait/articles/1506/18/news019. html 

    今回のPython3によるソルバでは,AESのライブラリを用いて復 号した.IVとKeyは既知であるため,復号できる  Rijndaelのライブラリもあるが,今回はうまく使えなかった  https://github.com/meyt/py3rijndael 25
  9. base64デコード可能な文字列の 抽出  strings flagconverter.dmp | grep -E "^([A-Za-z0- 9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-

    z0-9+/]{2}==)$" > base64_all.txt  これだけでは26万行ほど抽出されるので,重複の削除と,短すぎ る結果と長すぎる結果の削除を行う 27 f = open('base64_all.txt’, ‘r’) g = open(‘base64_all_filtered.txt', 'w') base64_list = [] while True: line = f.readline() if line == ‘’: break if base64_list.count(line) == 0 and 16 <= len(line) <= 160: base64_list.append(line) for line in base64_list: g.write(line) f.close() g.close()
  10. 全候補について復号を試行 28 import base64 from Crypto.Cipher import AES def decrypt(SID,

    ciphertext): IV = SID[:16] KEY = SID[len(SID)-16:]*2 return AES.new(KEY, AES.MODE_CBC, IV).decrypt(ciphertext) if __name__=='__main__': sid = 0x0105000000000005150000009a54b0afcd26c4824b70f4b0e8030000 sid = sid.to_bytes(28, 'big') iv = sid[:16] key = sid[28 - 16 :28] * 2 aes = AES.new(key, AES.MODE_CBC, iv) f = open('base64_all_filtered.txt', 'r') g = open(‘decrypt.txt’, 'wb') while True: cipher_base64 = f.readline()[:-1] # remove '¥n' if cipher_base64 == ‘’: break try: cipher = base64.b64decode(cipher_base64) plaintext = aes.decrypt(cipher) g.write(plaintext) except: continue f.close() g.close() input('[end]')
  11. 怪しい暗号文を復号する 30 import base64 from Crypto.Cipher import AES sid =

    0x0105000000000005150000009a54b0afcd26c4824b70f4b0e8030000 sid = sid.to_bytes(28, 'big') iv = sid[:16] key = sid[28 - 16 :28] * 2 aes = AES.new(key, AES.MODE_CBC, iv) cipher_base64 = 'ZuwJUgfmKzIMbo4F8agPy1MPLq+r7cAlDLowY+RT2wgp1uifc2TXeNH4bvbb2VqfK6r77SPHF rrMYR+GMGv8JGS87Tiybyi4LNNHQWnTR8LlGlSeHWWA9pydAXuJjSk8FzUFbqHOKqHc+bCtJ/4 K2Q==‘ cipher = base64.b64decode(cipher_base64) plaintext = aes.decrypt(cipher) print(plaintext) with open('flag.txt', 'wb') as f: f.write(plaintext)