Хакаем банк на 1337UP LIVE CTF 2024

от автора

Друзья, сегодня я представляю вашему вниманию решение одного из челленджей, который был представлен на 1337UP. Решение далось довольно легко, но я все же считаю, что это достойно хабровской публикации. Что же, давайте не тянуть яйца за кота и посмотрим, с чем мы имеем дело. Идем на страничку с челленджем и качаем его.

Кроме ссылки на скачивание, мы видим строку, которая позволит нам приконнектиться к челленджу на удаленном сервере и прокоммуницировать с программой. Это сделано для защиты от патчинга. Если бы ребята просто давали бинарник с ключом внутри, простой патчинг смог бы запросто решить любую задачку подобного рода.

❯  Первый запуск

tkchk@laptop:~/Downloads$ ./secure_bank  **************************************** *         Welcome to SecureBank        * *    Your trusted partner in security  * ****************************************  ======================================== =   SecureBank Superadmin Login System = ========================================  Enter superadmin PIN: 123 Access Denied! Incorrect PIN. tkchk@laptop:~/Downloads$ 

Сразу видим, что программа запрашивает у нас пин-код. Нам ничего не остаётся, как открыть бинарник в дизассемблере и разобрать, что же за пин-код от нас требуется. Я использовал фришную версию Binary Ninja. Поскольку за этот челлендж даётся всего 100 поинтов, мы получаем non-stripped binary. Это значит, что мы абсолютно спокойно видим все функции.

Нас, конечно же, интересует main. Это точка входа в любое скомпилированное приложение. Сразу видим 2 функции banner и login_message. Здесь ничего интересного. Просто несколько puts, которые выдают нам приглашение. Ровно так же как и последующий printf.

00001159  int64_t banner()  00001159  { 00001167      puts("********************************…"); 00001176      puts("*         Welcome to SecureBank …"); 00001185      puts("*    Your trusted partner in sec…"); 0000119b      return puts("********************************…"); 00001159  }
0000119c  int64_t login_message()  0000119c  { 000011aa      puts("================================…"); 000011b9      puts("=   SecureBank Superadmin Login …"); 000011cf      return puts("================================…"); 0000119c  } 

Функция __isoc99_scanf на строке с адресом 00001357 как раз таки считывает наш ввод из консоли в переменную var_10. Ее первый аргумент &data_21ea указывает ей, в каком формате считывать наш ввод. Перейдя по этому референсу, мы видим %u. Без этого %u мы бы считали наш ввод как hex символы, и это бы очень сильно затруднило процесс нашего взлома.

На самом деле на этом этапе нас интересует строка с адресом 00001370. Как раз в ней мы печатаем ‭«Access Denied! Incorrect PIN‭» на консоль и завершаем программу. Условие if на строке 00001364 заруливает программу в это русло. Нам очень нужно избежать подобного поведения программы. Сравнение происходит с числом 0x539. Открыв в калькуляторе, я перевел его в десятичный вид и получил 1337. Классика.

Ну что? Давайте пробовать.

tkchk@laptop:~/Downloads$ ./secure_bank  **************************************** *         Welcome to SecureBank        * *    Your trusted partner in security  * ****************************************  ======================================== =   SecureBank Superadmin Login System = ========================================  Enter superadmin PIN: 1337 Enter your 2FA code: 123 Access Denied! Incorrect 2FA code. tkchk@laptop:~/Downloads$ 

Хм, число подошло, но нас еще ждет 2FA авторизация. Программа требует какой-то токен. На строке с адресом 00001381 мы вызываем функцию generate_2fa_code. Глянув на нее, я пришел в полнейшее замешательство и ужас. Куча сравнений чисел, тайп кастов, еще какая-то функция obscure_key на строке 0000129d. Честно признаться, на этом этапе уже хотелось сдаться.

❯  Решаем

Функция generate_2fa_code в дизассемблированном виде выглядит еще хуже, чем в Pseudo-C, но на самом деле нам в ней надо отыскать всего одно место — нам нужно то, что она возвращает. Я запустил программу в дебагере gdb и сделал disass generate_2fa_code чтобы получить тело функции в виде процессорных инструкций. Здесь обращаем внимание на последние из них. На строке 61 мы видим mov eax,DWORD PTR [rbp-0x8].Это значит, что в регистр eax со стека снимается определенное значение. Может быть это оно?

generate_2fa_code
   0x00005555555551fa <+0>:push   rbp    0x00005555555551fb <+1>:mov    rbp,rsp    0x00005555555551fe <+4>:sub    rsp,0x18    0x0000555555555202 <+8>:mov    DWORD PTR [rbp-0x14],edi    0x0000555555555205 <+11>:mov    eax,DWORD PTR [rbp-0x14]    0x0000555555555208 <+14>:imul   eax,eax,0xbeef    0x000055555555520e <+20>:mov    DWORD PTR [rbp-0x4],eax    0x0000555555555211 <+23>:mov    eax,DWORD PTR [rbp-0x4]    0x0000555555555214 <+26>:mov    DWORD PTR [rbp-0x8],eax    0x0000555555555217 <+29>:mov    DWORD PTR [rbp-0xc],0x0    0x000055555555521e <+36>:jmp    0x5555555552a4 <generate_2fa_code+170>    0x0000555555555223 <+41>:mov    eax,DWORD PTR [rbp-0x4]    0x0000555555555226 <+44>:mov    edi,eax    0x0000555555555228 <+46>:call   0x5555555551d0 <obscure_key>    0x000055555555522d <+51>:mov    DWORD PTR [rbp-0x4],eax    0x0000555555555230 <+54>:mov    eax,DWORD PTR [rbp-0x4]    0x0000555555555233 <+57>:xor    DWORD PTR [rbp-0x8],eax    0x0000555555555236 <+60>:rol    DWORD PTR [rbp-0x8],0x5    0x000055555555523a <+64>:mov    ecx,DWORD PTR [rbp-0xc]    0x000055555555523d <+67>:movsxd rax,ecx    0x0000555555555240 <+70>:imul   rax,rax,0x66666667    0x0000555555555247 <+77>:shr    rax,0x20    0x000055555555524b <+81>:mov    edx,eax    0x000055555555524d <+83>:sar    edx,1    0x000055555555524f <+85>:mov    eax,ecx    0x0000555555555251 <+87>:sar    eax,0x1f    0x0000555555555254 <+90>:sub    edx,eax    0x0000555555555256 <+92>:mov    eax,edx    0x0000555555555258 <+94>:shl    eax,0x2    0x000055555555525b <+97>:add    eax,edx    0x000055555555525d <+99>:mov    edx,ecx    0x000055555555525f <+101>:sub    edx,eax    0x0000555555555261 <+103>:mov    eax,DWORD PTR [rbp-0x4]    0x0000555555555264 <+106>:mov    ecx,edx    0x0000555555555266 <+108>:shr    eax,cl    0x0000555555555268 <+110>:mov    esi,eax    0x000055555555526a <+112>:mov    edx,DWORD PTR [rbp-0xc]    0x000055555555526d <+115>:movsxd rax,edx    0x0000555555555270 <+118>:imul   rax,rax,0xffffffff92492493    0x0000555555555277 <+125>:shr    rax,0x20    0x000055555555527b <+129>:add    eax,edx    0x000055555555527d <+131>:sar    eax,0x2    0x0000555555555280 <+134>:mov    ecx,edx    0x0000555555555282 <+136>:sar    ecx,0x1f    0x0000555555555285 <+139>:sub    eax,ecx    0x0000555555555287 <+141>:mov    ecx,eax    0x0000555555555289 <+143>:shl    ecx,0x3    0x000055555555528c <+146>:sub    ecx,eax    0x000055555555528e <+148>:mov    eax,edx    0x0000555555555290 <+150>:sub    eax,ecx    0x0000555555555292 <+152>:mov    edx,DWORD PTR [rbp-0x4]    0x0000555555555295 <+155>:mov    ecx,eax    0x0000555555555297 <+157>:shl    edx,cl    0x0000555555555299 <+159>:mov    eax,edx    0x000055555555529b <+161>:xor    eax,esi    0x000055555555529d <+163>:add    DWORD PTR [rbp-0x8],eax    0x00005555555552a0 <+166>:add    DWORD PTR [rbp-0xc],0x1    0x00005555555552a4 <+170>:cmp    DWORD PTR [rbp-0xc],0x9    0x00005555555552a8 <+174>:jle    0x555555555223 <generate_2fa_code+41>    0x00005555555552ae <+180>:and    DWORD PTR [rbp-0x8],0xffffff    0x00005555555552b5 <+187>:mov    eax,DWORD PTR [rbp-0x8]    0x00005555555552b8 <+190>:leave    0x00005555555552b9 <+191>:ret 

Давайте запустим наш банк в дебагере и посмотрим на содержимое регистра rax (от eax он отличается только размером — это один и тот же регистр) после исполнения функции generate_2fa_code. Начинаем с команды break generate_2fa_code чтобы успешно остановить программу на этапе входа в функцию. Далее я ввел finish, чтобы дебагер прогнал программу по этой функции до ее завершения и стопнулся в нужный нам момент.

tkchk@laptop:~/Downloads$ gdb secure_bank  GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git Copyright (C) 2024 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at:     <http://www.gnu.org/software/gdb/documentation/>.  For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from secure_bank...  This GDB supports auto-downloading debuginfo from the following URLs:   <https://debuginfod.ubuntu.com> Enable debuginfod for this session? (y or [n]) y Debuginfod has been enabled. To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit. (No debugging symbols found in secure_bank) (gdb) break generate_2fa_code Breakpoint 1 at 0x11fe (gdb) run Starting program: /home/tkchk/Downloads/secure_bank  Downloading separate debug info for system-supplied DSO at 0x7ffff7fc3000 [Thread debugging using libthread_db enabled]                                    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". **************************************** *         Welcome to SecureBank        * *    Your trusted partner in security  * ****************************************  ======================================== =   SecureBank Superadmin Login System = ========================================  Enter superadmin PIN: 1337  Breakpoint 1, 0x00005555555551fe in generate_2fa_code () (gdb) finish  Run till exit from #0  0x00005555555551fe in generate_2fa_code () 0x0000555555555386 in main () (gdb) info reg rax            0x568720            5670688 rbx            0x7fffffffdee8      140737488346856 rcx            0x2                 2 rdx            0x57c77bc8          1472691144 rsi            0xd5f1def           224337391 rdi            0xa8497d36          2823388470 rbp            0x7fffffffddc0      0x7fffffffddc0 rsp            0x7fffffffddb0      0x7fffffffddb0 r8             0xa                 10 r9             0x0                 0 r10            0x7ffff7db1fc0      140737351720896 r11            0x7ffff7e038e0      140737352055008 r12            0x1                 1 r13            0x0                 0 r14            0x555555557dd8      93824992247256 r15            0x7ffff7ffd000      140737354125312 rip            0x555555555386      0x555555555386 <main+117> eflags         0x202               [ IF ] cs             0x33                51 ss             0x2b                43 ds             0x0                 0 es             0x0                 0 fs             0x0                 0 gs             0x0                 0 fs_base        0x7ffff7fa9740      140737353783104 gs_base        0x0                 0 (gdb)   

Команда info reg отдаст нам содержимое регистров. И поскольку на строке с адресом 000013b3 мы считываем наш 2fa код функцией __isoc99_scanf с теми же параметрами (я имею в виду %u), нам необходимо интерпретировать регистр rax в десятичном формате. Пробуем цифры 5670688 в качестве нашей 2fa.

tkchk@laptop:~/Downloads$ ./secure_bank  **************************************** *         Welcome to SecureBank        * *    Your trusted partner in security  * ****************************************  ======================================== =   SecureBank Superadmin Login System = ========================================  Enter superadmin PIN: 1337 Enter your 2FA code: 5670688 Access Granted! Welcome, Superadmin! Here is your flag: INTIGRITI{fake_flag}

Ха. Все на столько просто! Мы получили fake flag от нашего скачанного бинарника. Нам ничего не остается, как ввести эти данные на удаленный сервер, чтобы получить реальный флаг. Пробуем и радуемся! Мы решили челлендж.

tkchk@laptop:~/Downloads$ nc securebank.ctf.intigriti.io 1335 **************************************** *         Welcome to SecureBank        * *    Your trusted partner in security  * ****************************************  ======================================== =   SecureBank Superadmin Login System = ========================================  Enter superadmin PIN: 1337 Enter your 2FA code: 5670688 Access Granted! Welcome, Superadmin! Here is your flag: INTIGRITI{pfff7_wh47_2f4?!} 

Друзья, на данный момент меня интересует лишь одно, нравится ли вам подобный контент? Также интересует правильно ли я понял этот %u? Ставьте лайки и пишите комментарии. До связи!

Также читайте мой цикл статей о взломе диска от Red Balloon Security. Часть 0x00


Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud  в нашем Telegram-канале 

Перейти ↩

📚 Читайте также:


ссылка на оригинал статьи https://habr.com/ru/articles/860812/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *