= 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が生成されるかのリストを次のプログラムを用いて生成した。 {{{#!highlight d import std.digest.md; import std.uni; import std.conv; import std.stdio; string s = "abcdefABCDEFghijkmnopqrstuvwxyz"; void main() { foreach(char c1; s) { foreach(char c2; s) { foreach(char c3; s) { foreach(char c4; s) { string cur = "" ~ c1 ~ c2 ~ c3 ~ c4; writeln(cur, " ", (md5Of(cur).toHexString[0..4]).to!string.toLower); } } } } } }}} {{{ $ rdmd list.d > md5s }}} 次のプログラムを用いてシリアルを復元した。 {{{#!highlight ruby require 'digest/md5' @tbl = {} File.read('./md5s').split.each_slice(2) do |t, md5| @tbl[md5] = t end # digest = Digest::MD5.hexdigest('this_is_not_flag!!') digest.chars.each_slice(4).map(&:join).each do |t| print @tbl[t] end }}} {{{ $ ruby solve.rb yvaDyxakxCffzzfuyqfrxxbixfvrzzCd $ mono SimpleSerialCode.exe yvaDyxakxCffzzfuyqfrxxbixfvrzzCd Congratulations!! FLAG{06e57cb21b042c4d52a1e516b14cceae} }}}