ping CTF 2023
Ziggarettes [50 pts]
Don’t smoke zigarettes, kids!
e0d8bf8fdefc32df23a1c96f047c50fc.zip
We’re given an ELF binary. I decompiled with Dogbolt and examined the Ghidra code. Here’s the relevant part:
do {
if (uVar8 == 0x23) goto LAB_00202664;
if (uVar8 < 0x23) {
cVar1 = *(char *)((long)&local_58 + uVar8);
switch(uVar8) {
case 0:
case 0x20:
if (cVar1 != 'p') goto LAB_00202677;
break;
case 1:
if (cVar1 != 'i') {
LAB_00202677:
uVar12 = 7;
pcVar16 = "Wrong!\n";
do {
local_78[0] = 1;
sVar4 = FUN_00202714(local_78,pcVar16,uVar12);
if (sVar4 != 0) {
LAB_002025e0:
uVar12 = *(undefined8 *)(&DAT_002006c8 + (long)sVar4 * 0x10);
uVar3 = *(undefined8 *)(&DAT_002006d0 + (long)sVar4 * 0x10);
local_70[0] = 2;
FUN_0020284a(&DAT_00207104);
local_78[0] = 2;
sVar4 = FUN_00202714(local_78,"error: {s}\n",7);
if ((sVar4 == 0) &&
(sVar4 = FUN_0020291a(uVar12,uVar3,&DAT_002006a0,local_70), sVar4 == 0)) {
local_58 = CONCAT44(local_58._4_4_,2);
FUN_00202714(&local_58,"\n",1);
}
FUN_00202888(&DAT_00207104);
}
syscall();
LAB_00202664:
uVar12 = 9;
pcVar16 = "Correct!\n";
} while( true );
}
break;
case 2:
if (cVar1 != 'n') goto LAB_00202677;
break;
case 3:
if (cVar1 != 'g') goto LAB_00202677;
break;
case 4:
if (cVar1 != '{') goto LAB_00202677;
break;
case 5:
if (cVar1 != 'z') goto LAB_00202677;
break;
case 6:
case 9:
if (cVar1 != '1') goto LAB_00202677;
break;
case 7:
if (cVar1 != 'G') goto LAB_00202677;
break;
default:
if (cVar1 != '_') goto LAB_00202677;
break;
case 10:
if (cVar1 != 'S') goto LAB_00202677;
break;
case 0xc:
if (cVar1 != 'v') goto LAB_00202677;
break;
case 0xd:
case 0x17:
if (cVar1 != '3') goto LAB_00202677;
break;
case 0xe:
if (cVar1 != 'R') goto LAB_00202677;
break;
case 0xf:
if (cVar1 != 'Y') goto LAB_00202677;
break;
case 0x11:
if (cVar1 != 'C') goto LAB_00202677;
break;
case 0x12:
if (cVar1 != '0') goto LAB_00202677;
break;
case 0x13:
case 0x1e:
if (cVar1 != 'O') goto LAB_00202677;
break;
case 0x14:
case 0x21:
if (cVar1 != 'l') goto LAB_00202677;
break;
case 0x16:
case 0x1f:
if (cVar1 != '2') goto LAB_00202677;
break;
case 0x18:
if (cVar1 != '4') goto LAB_00202677;
break;
case 0x19:
if (cVar1 != 'm') goto LAB_00202677;
break;
case 0x1a:
case 0x1c:
if (cVar1 != 'K') goto LAB_00202677;
break;
case 0x1b:
case 0x1d:
if (cVar1 != 'I') goto LAB_00202677;
break;
case 0x22:
if (cVar1 != '}') goto LAB_00202677;
}
}
uVar8 = uVar8 + 1;
} while( true );
Seems like it’s just a switch statement checking the characters! Only thing to note is that cases that come consecutively, where one case doesn’t have a break statement before the next one, run the same code. Knowing that, brute-forcing becomes trivial:
0123456789abcdef0123456789abcdef0123456789abcdef
ping{z1G_1S_v3RY_C0Ol_234mKIKIO2pl}