a

よろしくのキワミ

Reversing進捗2

Reversing進捗2

・Ea/sy_Ke/yg///enM//e

動作確認

keygenの問題らしい。 中にはReadMeとプログラムが入っていた。

(ReadMe)

Find the Name when the Serial is ****************

* 一部文字を崩しています

ReadMeによると名前を見つけることがカギになりそうですね。

とりあえず実行してみます。
f:id:toDo:20190105160327p:plain

NameとSerialを入力するとWrongと出力されプログラムが終了します。

それではデバッガを起動して名前を確認してみましょう。

まずは文字列確認から
f:id:toDo:20190105160813p:plain

"InputName"や"Wrong"などは実行時に見えた文字ですね。
名前が合っていれば"Correct!"が表示されるであろうこともわかります。

しかしここでおかしな文字列が入っていることに気が付く人は少ないでしょう。

%s
%s%02X

"%s"は書式指定時の文字列であるがでは"%s%02X"とはなんだろうか。

分けて考えてみよう。

"%s" => 文字列  
"%02X" => 16進数。0詰め。2桁。

わざわざこんな書き方をしているのだ。
何か重要な手掛かりになることは疑いようがない...!

よくわからないので見送ります😊

"Correct"を参照している場所へ移動
f:id:toDo:20190105163052p:plain

直前のjne命令で分岐しているので潰してから実行してみる。
f:id:toDo:20190105163649p:plain

通った!!
だが通るだけでは意味がないので結局正しいInput Nameを探さなければいけない。 はっきり言って条件分岐を外しただけで成し遂げた気になっていいのは小学生までなのだ←

解いていく

main関数のあたりから見ていく
f:id:toDo:20190105180033p:plain

"Input Name"と表示した後に

mov byte ptr ss:[esp+10],10
mov byte ptr ss:[esp+11],20
mov byte ptr ss:[esp+12],30

と値を入れており
さらにその後に

add esp,4
lea eax,dword ptr ss:[esp+10]
push eax 
push easy keygen.40805C                 40805C:"%s"
call easy keygen.4011A2

とある。

callで呼び出している関数は入力に関するものと予想できる
("%s"があるため、おそらくそうだ)
さらに関数呼び出しの前にeaxをpushしていることから入力された値はeaxに入るはずだ。

おそらく

scanf("%s", eax);

という感じになっていると思う。

さらに先を見てみると繰り返しのような文章が見える。

f:id:toDo:20190105185929p:plain

プログラムに直すとこんな感じだろうか...

esi = 0;
esp_1x[10,20,30];
input_str[];
tmp_string[];

for( i = 0 ; i < len(input_str) ; i++ ){
  // esiが3以上なら
  if( esi >= 3 ){
    esi = 0;
  }

  /* esiが0ならss:[esp+10]、1ならss:[esp+11]、2ならss:[esp+12]と文字列のi番目をxor演算する */
  tmp[i] = input_str[i] ^ esp_1x[esi];

  esi++;
}

ぐちゃぐちゃだが大体あっている気がする。

つまりこのプログラムでは入力されたNameのn文字目10,20,30の値を繰り返しをxor演算していることになる。

そしてSerialを入力しSerialと変換されたNameが一致するかを判定しているというわけだ。

f:id:toDo:20190106221550p:plain

つまり入力する名前はSerialから求めることができるというわけだ。

ここまでわかればあとは復号するだけなのでちゃちゃっとコードを書く

serial = "5B134977135E7D13"
esi = 0
num = [10, 20, 30]
answer = ""

for i in range(0, len(serial), 2):
  if esi >= 3:
    esi = 0

  tmp = serial[i] + serial[i+1]
  answer += chr(int(tmp, 16) ^ num[esi])
  esi += 1

print(answer)
$ python a.py
QW}@w

f:id:toDo:20190106224644p:plain

が、ダメ...
原因はserialの文字は10進数に戻したのにnumの中の文字が16進数のままだからだ。

# numの中身を16進数に変更
# 10 => 0001 0000 => 16
# 20 => 0010 0000 => 32
# 30 => 0100 0000 => 48
# num = [10, 20, 30]
num = [16, 32, 48]

f:id:toDo:20190106230546p:plain

無事にフラグがゲットできた。
ついつい数字を10進数に見てしまうのは僕の悪い癖(水谷豊)

感想

関数呼び出しがあるとその中身を追ってしまい時間が削られる。
ある程度主要な関数はわかるようにしたい。

プライバシーポリシー お問い合わせ