ヒントにGhidraでって書いてたので,喜んでチャレンジしたが,誤った道に進んだGhidraちゃんを正しい道に導くことができなかった。この悔しさは忘れない。いつかリベンジする。
picoCTF
picoGym Practice Challenges
gogo
Category: Reverse Engineering
Description:
Hmmm this is a weird file... enter_password. There is a instance of the service running at mercury.picoctf.net:48728.
Hints:
use go tool objdump or ghidra
Solution:
ncしてみる。
$ nc mercury.picoctf.net 48728
Enter Password:
Ghidra で文字列 Enter Password: を検索する。
あった。でも末尾が0x00じゃないのでstringに変換できない。
XREF
Printf の引数だ。
Scanf の後,main.checkPassword 関数を呼んでる
main.checkPasswordは
void main.checkPassword(int param_1,uint param_2,undefined param_3)
{
uint *puVar1;
uint uVar2;
int iVar3;
int *in_GS_OFFSET;
undefined4 local_40;
undefined4 local_3c;
undefined4 local_38;
undefined4 local_34;
undefined4 local_30;
undefined4 local_2c;
undefined4 local_28;
undefined4 local_24;
byte local_20 [28];
undefined4 uStack4;
puVar1 = (uint *)(*(int *)(*in_GS_OFFSET + -4) + 8);
if (register0x00000010 < (undefined *)*puVar1 ||
(undefined *)register0x00000010 == (undefined *)*puVar1) {
uStack4 = 0x80d4b72;
runtime.morestack_noctxt();
main.checkPassword();
return;
}
if ((int)param_2 < 0x20) {
os.Exit(0);
}
FUN_08090b18();
local_40 = 0x38313638;
local_3c = 0x31663633;
local_38 = 0x64336533;
local_34 = 0x64373236;
local_30 = 0x37336166;
local_2c = 0x62646235;
local_28 = 0x39383338;
local_24 = 0x65343132;
FUN_08090fe0();
uVar2 = 0;
iVar3 = 0;
while( true ) {
if (0x1f < (int)uVar2) {
if (iVar3 == 0x20) {
return;
}
return;
}
if ((param_2 <= uVar2) || (0x1f < uVar2)) break;
if ((*(byte *)(param_1 + uVar2) ^ *(byte *)((int)&local_40 + uVar2)) == local_20[uVar2]) {
iVar3 = iVar3 + 1;
}
uVar2 = uVar2 + 1;
}
runtime.panicindex();
do {
invalidInstructionException();
} while( true );
}
結構,ぐちゃぐちゃ
型
local_40 の型を byte[32] に
local_20 の型を byte[32] に
変数名
local_40 を key に
local_20 を enc に
uVar2 を i に
iVar2 を j に
void main.checkPassword(int param_1,uint param_2,undefined param_3)
{
uint *puVar1;
uint i;
int j;
int *in_GS_OFFSET;
byte key [32];
byte enc [32];
puVar1 = (uint *)(*(int *)(*in_GS_OFFSET + -4) + 8);
if (register0x00000010 < (undefined *)*puVar1 ||
(undefined *)register0x00000010 == (undefined *)*puVar1) {
enc._28_4_ = 0x80d4b72;
runtime.morestack_noctxt();
main.checkPassword();
return;
}
if ((int)param_2 < 0x20) {
os.Exit(0);
}
FUN_08090b18();
key._0_4_ = 0x38313638;
key._4_4_ = 0x31663633;
key._8_4_ = 0x64336533;
key._12_4_ = 0x64373236;
key._16_4_ = 0x37336166;
key._20_4_ = 0x62646235;
key._24_4_ = 0x39383338;
key._28_4_ = 0x65343132;
FUN_08090fe0();
i = 0;
j = 0;
while( true ) {
if (0x1f < (int)i) {
if (j == 0x20) {
return;
}
return;
}
if ((param_2 <= i) || (0x1f < i)) break;
if ((*(byte *)(param_1 + i) ^ key[i]) == enc[i]) {
j = j + 1;
}
i = i + 1;
}
runtime.panicindex();
do {
invalidInstructionException();
} while( true );
}
param_1 が入力 文字長32
key も32バイト(stack strings)
param_1[i] ^ key[i] == enc[i]だが,大問題発生
enc[]への代入が,どこにも無い。
今の私の力では Ghidra を正しい方向に導けない
デコンパイルはあきらめ,逆アセ結果を見る
stack strings の key を構築したあと,main.statictmp_4 のアドレスを取得してる
32バイトのデータ
とりあえず,xor してみる
def dword_parse(value):
return([(value & 0x000000ff) / 0x1,(value & 0x0000ff00) / 0x100,(value & 0x00ff0000) / 0x10000,(value & 0xff000000) / 0x1000000])
key=[]
addr = toAddr(0x080d4ab1)
inst = getInstructionAt(addr)
i = 0
while i < 8:
key.extend(dword_parse(inst.getOpObjects(1)[0].getValue()))
inst = inst.getNext()
i = i + 1
print(key)
print("key="+''.join(map(chr,key)))
enc = getBytes(toAddr(0x0810fe00),32)
print(enc)
print("enc="+''.join(map(chr,enc)))
ans=[]
i = 0
while i < 32:
ans.append(enc[i] ^ key[i])
i = i + 1
print(ans)
print("ans="+''.join(map(chr,ans)))
key=861836f13e3d627dfa375bdb8389214e
ans=reverseengineericanbarelyforward
ncに戻ってみる
$ nc mercury.picoctf.net 48728
Enter Password: reverseengineericanbarelyforward
=========================================
This challenge is interrupted by psociety
What is the unhashed key?
進展した。
今度はkeyをunhashしろって。
これをかな?
861836f13e3d627dfa375bdb8389214e
$ nc mercury.picoctf.net 48728
Enter Password: reverseengineericanbarelyforward
=========================================
This challenge is interrupted by psociety
What is the unhashed key?
goldfish
Flag is: picoCTF{
ビンゴ
でもうれしくない。