2011/07/31

EnigmaGroupのSoftwareCrackingレベル12

EnigmaGroupのcrackingも今回でレベル12まで来ました。いまのところ14までしか公開されてないのであと2つ、どんどん終わらせたいと思います。
条件付きジャンプを書き換えるだけで認証成功してパスワードが「14097924cfa505382b0b94c91b9e5c99」と出るんですが、これを判定フォームに入力しても正しくないと言われます。
そこで、「14097924cfa505382b0b94c91b9e5c99」ってのが見るからにハッシュ値っぽいので、ハッシュ化する前のデータがパスワードかなーとか考えながらコードを見てると、CryptAPIを使った処理が見つかりました。



まずキーコンテナというものを取得して、それを介してCSPというもので計算させるようです。
詳しくはここなどを参照してください。

MOV DWORD PTR SS:[ESP+10],0
MOV DWORD PTR SS:[ESP+C],1
MOV DWORD PTR SS:[ESP+8],App12.00441000 ; ASCII "Microsoft Base Cryptographic Provider v1.0"
MOV DWORD PTR SS:[ESP+4],0
LEA EAX,DWORD PTR SS:[EBP-1C]
MOV DWORD PTR SS:[ESP],EAX
CALL <JMP.&ADVAPI32.CryptAcquireContextA>

次にハッシュ値を計算するインスタンスの生成です。
LEA EAX,DWORD PTR SS:[EBP-20]
MOV DWORD PTR SS:[ESP+10],EAX
MOV DWORD PTR SS:[ESP+C],0
MOV DWORD PTR SS:[ESP+8],0
MOV DWORD PTR SS:[ESP+4],8003
MOV EAX,DWORD PTR SS:[EBP-1C]
MOV DWORD PTR SS:[ESP],EAX
CALL <JMP.&ADVAPI32.CryptCreateHash>

MSDNを参照すると、
BOOL WINAPI CryptCreateHash(
  __in   HCRYPTPROV hProv,
  __in   ALG_ID Algid,
  __in   HCRYPTKEY hKey,
  __in   DWORD dwFlags,
  __out  HCRYPTHASH *phHash
);
 
となっており、第二引数にはアルゴリズムを指定します。
プログラムでは0x8003をpushしており、渡す定数の一覧から、アルゴリズムはMD5ということが分かりました。

MOV DWORD PTR SS:[ESP+C],0
MOV EAX,DWORD PTR SS:[EBP-24]
MOV DWORD PTR SS:[ESP+8],EAX                    ;  len(password)
MOV EAX,DWORD PTR SS:[EBP-34]
MOV DWORD PTR SS:[ESP+4],EAX                    ;  password = "c0ckh3ad"
MOV EAX,DWORD PTR SS:[EBP-20]
MOV DWORD PTR SS:[ESP],EAX
CALL <JMP.&ADVAPI32.CryptHashData>

そしてCryptHashDataでハッシュ値の計算をします。
BOOL WINAPI CryptHashData(
  __in  HCRYPTHASH hHash,
  __in  BYTE *pbData,

  __in  DWORD dwDataLen,
  __in  DWORD dwFlags
);

その後、計算に成功すると
MOV DWORD PTR SS:[EBP-2C],4
MOV DWORD PTR SS:[ESP+10],0
LEA EAX,DWORD PTR SS:[EBP-2C]
MOV DWORD PTR SS:[ESP+C],EAX
LEA EAX,DWORD PTR SS:[EBP-28]
MOV DWORD PTR SS:[ESP+8],EAX
MOV DWORD PTR SS:[ESP+4],4
MOV EAX,DWORD PTR SS:[EBP-20]
MOV DWORD PTR SS:[ESP],EAX
MOV DWORD PTR SS:[EBP-78],-1
CALL <JMP.&ADVAPI32.CryptGetHashParam>

CryptGetHash関数でハッシュ値を取り出して、16進法の文字列に直して、インスタンス等を開放してこのルーチンは終わります。
CryptHashDataの所でコメントに書いてあったように、ハッシュ化前のデータは"c0ckh3ad"で、これを入力したら、今度はちゃんとOK出してくれました。


なんか英数文字の羅列をぱっと見て、16進法だなーこれはあのアルゴリズムのハッシュ値だなー、とかすぐに分かったらかっこいいですね。桁数で分かるんでしたっけ。

0 件のコメント:

コメントを投稿