ログイン
編集不可のページディスカッション情報添付ファイル
CTF/Writeup/tkbctf4/Simple Serial Code

MMA

Simple Serial Code (binary 200)

SimpleSericalCode.exeに対してfileコマンドを用いた所、x86 Mono Assemblyだと特定できたため、ILSpyを用いて逆コンパイルした。(MonoDevelopだと逆コンパイル時にフリーズした)

逆コンパイルしたコードを読むと、引数である32文字のシリアルを4文字毎に区切り、各4文字の文字列のMD5ダイジェスト(16進数)の先頭4文字を取り出し結合して32文字にしたものとMD5("this_is_not_flag!!")が等しいかを判定している。

したがって、md5(<4文字の文字列>)[0,4]のテーブルを作ることでシリアルは用意に復元出来る。

4文字の文字列からどのようなmd5が生成されるかのリストを次のプログラムを用いて生成した。

   1 import std.digest.md;
   2 import std.uni;
   3 import std.conv;
   4 import std.stdio;
   5 
   6 string s = "abcdefABCDEFghijkmnopqrstuvwxyz";
   7 
   8 void main() {
   9   foreach(char c1; s) {
  10     foreach(char c2; s) {
  11       foreach(char c3; s) {
  12         foreach(char c4; s) {
  13           string cur = "" ~ c1 ~ c2 ~ c3 ~ c4;
  14           writeln(cur, " ", (md5Of(cur).toHexString[0..4]).to!string.toLower);
  15         }
  16       }
  17     }
  18   }
  19 }

$ rdmd list.d > md5s

次のプログラムを用いてシリアルを復元した。

   1 require 'digest/md5'
   2 @tbl = {}
   3 File.read('./md5s').split.each_slice(2) do |t, md5|
   4   @tbl[md5] = t
   5 end
   6 #
   7 digest = Digest::MD5.hexdigest('this_is_not_flag!!')
   8 digest.chars.each_slice(4).map(&:join).each do |t|
   9   print @tbl[t]
  10 end

$ ruby solve.rb
yvaDyxakxCffzzfuyqfrxxbixfvrzzCd

$ mono SimpleSerialCode.exe yvaDyxakxCffzzfuyqfrxxbixfvrzzCd
Congratulations!!
FLAG{06e57cb21b042c4d52a1e516b14cceae}

CTF/Writeup/tkbctf4/Simple Serial Code (最終更新日時 2014-11-04 02:01:08 更新者 nomeaning)