Код: Выделить всё
two_factor_pass.exe: PE32 executable (console) Intel 80386, for MS Windows, 15 sections
Я воспользовался декомпилятором и дизассемблером Ghidra для анализа кода, а позже начал отладку с помощью x32dbg в Windows.
Итак, вот декомпиляция Ghidra:
Код: Выделить всё
int __cdecl _main(int _Argc,char **_Argv,char **_Env)
{
undefined4 local_36;
undefined local_32;
undefined4 local_31;
undefined4 local_2d;
undefined4 local_29;
undefined4 local_25;
undefined2 local_21;
char local_1f [5];
char local_1a;
char local_19;
char *local_18;
int local_14;
__main();
local_25 = 0x35706635;
local_21 = 0x73;
local_31 = 0x6866234a;
local_2d = 0x7667236f;
local_29 = 0x776c21;
local_36 = 0x37333331;
local_32 = 0;
local_18 = _getenv("GREENIE");
if ((1 < _Argc) && (local_18 != (char *)0x0)) {
_strncpy(local_1f,_Argv[1],5);
for (local_14 = 0; local_14 < 5; local_14 = local_14 + 1) {
local_1a = (char)local_14 + local_1f[local_14] + '\x01';
if (local_1a != *(char *)((int)&local_25 + local_14)) {
_puts("wrong");
/* WARNING: Subroutine does not return */
_exit(0);
}
}
local_14 = 0;
while( true ) {
if (10 < local_14) {
_putchar(*local_18 + 0x1d);
_putchar(local_18[1] + 0x4c);
_putchar(local_18[2] + -2);
_putchar(local_18[3] + 6);
_putchar(local_18[4] + 0xd);
_putchar(local_18[5] + 0x23);
_putchar(local_18[6] + 0x15);
_putchar(local_18[7] + -0xd);
_putchar(local_18[8] + 0x13);
_putchar(local_18[9] + 9);
_printf("%c\n",local_18[10] + 9);
return 0;
}
local_19 = *(char *)((int)&local_36 + local_14 % 4);
if (local_19 + -0x30 + (int)local_18[local_14] != (int)*(char *)((int)&local_31 + local_14))
break;
local_14 = local_14 + 1;
}
_puts("wrong");
/* WARNING: Subroutine does not return */
_exit(0);
}
_puts("An error occurred");
/* WARNING: Subroutine does not return */
_exit(0);
}
Код: Выделить всё
int main(int _Argc,char **_Argv,char **_Env)
{
undefined4 mem1;
undefined4 mem2;
undefined2 mem3;
char arg1 [5];
char fact1;
char fact2;
char *env;
int i;
__main();
mem1 = 0x35706635; //5fp5s
mem2 = 0x6866234a; //J#fho#gv!lw
mem3 = 0x37333331; //1337
env = getenv("GREENIE");
if ((1 < _Argc) && (env != (char *)0x0))
{
_strncpy(arg1,_Argv[1],5);
for (i = 0; i < 5; i = i + 1) {
fact1 = (char)i + arg1[i] + '\x01';
if (fact1 != *(char *)((int)&mem1 + i)) {
_puts("wrong");
/* WARNING: Subroutine does not return */
_exit(0);
}
}
i = 0;
while( true )
{
if (10 < i)
{
_putchar(*env + 0x1d);
_putchar(env[1] + 0x4c);
_putchar(env[2] + -2);
_putchar(env[3] + 6);
_putchar(env[4] + 0xd);
_putchar(env[5] + 0x23);
_putchar(env[6] + 0x15);
_putchar(env[7] + -0xd);
_putchar(env[8] + 0x13);
_putchar(env[9] + 9);
_printf("%c\n",env[10] + 9);
return 0;
}
fact2 = *(char *)((int)&mem3 + i % 4);
if (fact2 -48 + (int)env[i] != (int)*(char *)((int)&mem2 + i))
break;
i = i + 1;
}
_puts("wrong");
/* WARNING: Subroutine does not return */
_exit(0);
}
_puts("An error occurred");
/* WARNING: Subroutine does not return */
_exit(0);
}
Я вставлю сюда наиболее подходящий фрагмент кода: (мне нужно выяснить строку env)
Код: Выделить всё
undefined4 mem2;
undefined2 mem3;
...
mem2 = 0x6866234a; //J#fho#gv!lw
mem3 = 0x37333331; //1337
...
i = 0;
while( true )
{
if (10 < i)
{
_putchar(*env + 0x1d);
_putchar(env[1] + 0x4c);
_putchar(env[2] + -2);
_putchar(env[3] + 6);
_putchar(env[4] + 0xd);
_putchar(env[5] + 0x23);
_putchar(env[6] + 0x15);
_putchar(env[7] + -0xd);
_putchar(env[8] + 0x13);
_putchar(env[9] + 9);
_printf("%c\n",env[10] + 9);
return 0;
}
fact2 = *(char *)((int)&mem3 + i % 4);
if (fact2 -48 + (int)env[i] != (int)*(char *)((int)&mem2 + i))
break;
i = i + 1;
}
Затем я перешел ко второму фактору, но здесь все усложняется. Я не уверен, что я что-то напутал из-за указателей памяти и их разыменования, или мои обратные вычисления неверны, или что-то в этом роде... но я не понимаю, что мне нужно поместить в переменную env GREENIE.
Кроме того, в моем собственном анализе вы можете видеть, что я прокомментировал значения в этой памяти. Это я получил частично через x32dbg и частично с помощью онлайн-декомпилятора Dogbolt.org, но я предполагаю, что значение, которое они возвращают, должно быть одинаковым в любой 32-битной системе (я понятия не имею, что такое память), но онлайн-компиляторы C возвращают что-то другое.
Вот как я пытался получить строку env:
Код: Выделить всё
#include
int main()
{
// int i;
// char wrong;
// char tar[] = "5fp5f";
// char given[] = "00000";
// char greetings[] = "U1234";
// char write;
// char arg1[] = "4dm10";
// for (i = 0; i < 5; i = i + 1) {
// // w = i + arg + '\x01'
// wrong = (char)i + '0' + '\x01';
// write = (char)(tar[i]-i-'\x01');
// }
// // for (i = 0; i < 5; i = i + 1) {
// // wrong = (char)i + arg1[i] + '\x01';
// // }
// // return 0;
// int i = 0;
// int tar[] = "J#fho#gv!lw";
// int * mem1 = 0x35706635; //4dm1n
char mem2[] = "J#fho#gv!lw";
char mem3[] = "1337";
int i = 0;
int temp;
char fact2[10];
while(i
Подробнее здесь: [url]https://stackoverflow.com/questions/78479529/ctf-reverse-engineering-dereference-a-pointer-in-compiled-32-bit-exe[/url]