WIDE
5 minutos de lectura
Se nos proporciona un binario de 64 bits llamado wide
y otro archivo llamado db.ex
con algunas cadenas de texto:
$ file wide
wide: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=13869bb7ce2c22f474b95ba21c9d7e9ff74ecc3f, not stripped
$ strings db.ex
Primus
people breathe variety practice
Our home dimension
Cheagaz
scene control river importance
The Ice Dimension
Byenoovia
fighting cast it parallel
The Berserk Dimension
Cloteprea
facing motor unusual heavy
The Hungry Dimension
Maraqa
stomach motion sale valuable
The Water Dimension
Aidor
feathers stream sides gate
The Bone Dimension
Flaggle Alpha
admin secret power hidden
HOt*
0ANe
Si ejeutamos el binario tenemos lo siguiente:
$ ./wide
Usage: ./wide db.ex
$ ./wide db.ex
[*] Welcome user: kr4eq4L2$12xb, to the Widely Inflated Dimension Editor [*]
[*] Serving your pocket dimension storage needs since 14,012.5 B [*]
[*] Displaying Dimensions.... [*]
[*] Name | Code | Encrypted [*]
[X] Primus | people breathe variety practice | [*]
[X] Cheagaz | scene control river importance | [*]
[X] Byenoovia | fighting cast it parallel | [*]
[X] Cloteprea | facing motor unusual heavy | [*]
[X] Maraqa | stomach motion sale valuable | [*]
[X] Aidor | feathers stream sides gate | [*]
[X] Flaggle Alpha | admin secret power hidden | * [*]
Which dimension would you like to examine? 6
[X] That entry is encrypted - please enter your WIDE decryption key:
La sexta opcion parece que es la que retornará la flag, pero necesitamos una clave de descifrado:
Si usamos Ghidra para analizar el binario, veremos la función main
:
undefined8 main(int param_1, undefined8 *param_2) {
int iVar1;
FILE *__stream;
ulong uVar2;
void *__ptr;
uint uVar3;
int i;
if (param_1 < 2) {
printf("Usage: %s db.ex\n", *param_2);
/* WARNING: Subroutine does not return */
exit(-1);
}
puts("[*] Welcome user: kr4eq4L2$12xb, to the Widely Inflated Dimension Editor [*]");
puts("[*] Serving your pocket dimension storage needs since 14,012.5 B [*]");
__stream = fopen((char *) param_2[1], "r");
if (__stream == (FILE *) 0x0) {
puts("[x] There was a problem accessing your database [x]");
/* WARNING: Subroutine does not return */
exit(-1);
}
fseek(__stream, 0, 2);
uVar2 = ftell(__stream);
fseek(__stream, 0, 0);
uVar2 = (uVar2 - uVar2 % 0xb4) / 0xb4;
iVar1 = (int) uVar2;
__ptr = calloc((long) iVar1,0xb4);
fread(__ptr, 0xb4,(long) iVar1, __stream);
fclose(__stream);
puts("[*] Displaying Dimensions.... [*]");
puts("[*] Name | Code | Encrypted [*]");
for (i = 0; i < iVar1; i = i + 1) {
if (*(int *) ((long) __ptr + (long) i * 0xb4) == 0) {
uVar3 = 0x20;
} else {
uVar3 = 0x2a;
}
printf("[X] %-16s | %-32s | %6s%c%7s [*]\n", (long) __ptr + (long) i * 0xb4 + 4,
(long) __ptr + (long) i * 0xb4 + 0x14, &DAT_0010132d, (ulong) uVar3, &DAT_0010132d);
}
menu(__ptr, uVar2 & 0xffffffff);
return 0;
}
Al final, existe una llamada a otra función llamada menu
:
void menu(long param_1, int param_2) {
int iVar1;
long lVar2;
undefined8 *puVar3;
long in_FS_OFFSET;
uint i;
wchar_t local_1c8[16];
undefined8 local_188;
// ...
undefined8 local_10;
local_10 = *(undefined8 *) (in_FS_OFFSET + 0x28);
local_b8 = 0;
local_b0 = 0;
local_a8 = 0;
local_a0 = 0;
do {
while (true) {
while (true) {
printf("Which dimension would you like to examine? ");
fgets((char *) &local_b8, 0x20, stdin);
lVar2 = strtol((char *) &local_b8, (char **) 0x0, 10);
iVar1 = (int) lVar2;
if ((-1 < iVar1) && (iVar1 < param_2)) break;
puts("That option was invalid.");
}
puVar3 = (undefined8 *) (param_1 + (long) iVar1 * 0xb4);
local_188 = *puVar3;
local_180 = puVar3[1];
local_178 = puVar3[2];
local_170 = puVar3[3];
local_168 = puVar3[4];
local_160 = puVar3[5];
local_158 = (undefined4) puVar3[6];
uStack340 = (undefined4) ((ulong) puVar3[6] >> 0x20);
// ...
uStack220 = (undefined4) ((ulong) puVar3[0x15] >> 0x20);
local_d8 = *(undefined4 *) (puVar3 + 0x16);
if ((int) local_188 != 0) break;
puts((char *) &uStack340);
}
local_98 = CONCAT44(local_150, uStack340);
// ...
local_20 = CONCAT44(local_d8, uStack220);
printf("[X] That entry is encrypted - please enter your WIDE decryption key: ");
fgets(local_c8, 0x10, stdin);
mbstowcs(local_1c8, local_c8, 0x10);
iVar1 = wcscmp(local_1c8, L"sup3rs3cr3tw1d3");
if (iVar1 == 0) {
for (i = 0; (i < 0x80 && (*(char *) ((long) &local_98 + (long) (int) i) != '\0')); i = i + 1) {
*(byte *) ((long) &local_98 + (long) (int) i) =
*(byte *)((long) &local_98 + (long) (int) i) ^
(char) (i * 0x1b) + (char) ((int) (i * 0x1b) / 0xff);
}
puts((char *) &local_98);
} else {
puts("[X] Key was incorrect [X]");
}
} while (true);
}
Y ahí tenemos la contraseña: sup3rs3cr3tw1d3
. Si la utilizamos obtenemos la flag:
$ ./wide db.ex
[*] Welcome user: kr4eq4L2$12xb, to the Widely Inflated Dimension Editor [*]
[*] Serving your pocket dimension storage needs since 14,012.5 B [*]
[*] Displaying Dimensions.... [*]
[*] Name | Code | Encrypted [*]
[X] Primus | people breathe variety practice | [*]
[X] Cheagaz | scene control river importance | [*]
[X] Byenoovia | fighting cast it parallel | [*]
[X] Cloteprea | facing motor unusual heavy | [*]
[X] Maraqa | stomach motion sale valuable | [*]
[X] Aidor | feathers stream sides gate | [*]
[X] Flaggle Alpha | admin secret power hidden | * [*]
Which dimension would you like to examine? 6
[X] That entry is encrypted - please enter your WIDE decryption key: sup3rs3cr3tw1d3
HTB{som3_str1ng5_4r3_w1d3}
Podríamos pensar que esta cadena de texto se puede extraer con strings
, pero no. El problema es que está separada por bytes nulos, podemos analizar el contenido hexadecimal del binario para verlo:
$ strings wide | grep sup3rs3cr3tw1d3
$ xxd wide
...
000010d0: 5b58 5d20 5468 6174 2065 6e74 7279 2069 [X] That entry i
000010e0: 7320 656e 6372 7970 7465 6420 2d20 706c s encrypted - pl
000010f0: 6561 7365 2065 6e74 6572 2079 6f75 7220 ease enter your
00001100: 5749 4445 2064 6563 7279 7074 696f 6e20 WIDE decryption
00001110: 6b65 793a 2000 0000 7300 0000 7500 0000 key: ...s...u...
00001120: 7000 0000 3300 0000 7200 0000 7300 0000 p...3...r...s...
00001130: 3300 0000 6300 0000 7200 0000 3300 0000 3...c...r...3...
00001140: 7400 0000 7700 0000 3100 0000 6400 0000 t...w...1...d...
00001150: 3300 0000 0000 0000 5b58 5d20 2020 2020 3.......[X]
00001160: 2020 2020 2020 2020 2020 2020 2020 2020
00001170: 2020 2020 204b 6579 2077 6173 2069 6e63 Key was inc
00001180: 6f72 7265 6374 2020 2020 2020 2020 2020 orrect
...