Друзья, сегодня я представляю вашему вниманию решение одного из челленджей, который был представлен на 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/
Добавить комментарий