Временная атака на программу bash с использованием функции usleep()

У меня есть небольшой взлом, где я должен получить пароль с грубой силой. В программе есть функция usleep(); когда у меня правильная длина, и она меняется, когда одна буква правильная. Это не было бы проблемой, но время сна составляет около одной минуты, и это довольно долго. Есть ли способ сделать таймер сна быстрее?

64-битный исполняемый файл ELF для ELF, x86-64, версия 1 (SYSV), динамически связанный (использует разделяемые библиотеки)

1 ответ

Способ 1

Вы можете переопределить библиотечные функции с помощью LD_PRELOAD директивы.

Здесь и здесь есть хорошее руководство, с которого можно начать.

Предположим, у вас есть следующий программный код, который затем компилируется в двоичный файл elf.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for usleep() */

int main(int argc, char* argv[]) {
   printf("Entry point. We'll now wait 10 seconds.\n");
   system("date  +\"%H:%M:%S\""); //Output time

   usleep(10*1000*1000);

   printf("Woke up again.\n");
   system("date  +\"%H:%M:%S\""); //Output time

   return 0;
}

Запуск его нормально даст вам

root@kali:~/so# gcc -o prog prog.c
root@kali:~/so# ./prog 
Entry point. We'll now wait 10 seconds.
20:31:10
Woke up again.
20:31:20

Теперь напишите свою собственную версию usleep(),

#include <unistd.h>
#include <stdio.h>

int usleep(useconds_t usec){
   printf("Nope, you're not sleeping today :)\n");

   return 0;
}

Скомпилируйте его как общую библиотеку.

root@kali:~/so# gcc -Wall -fPIC -shared -o usleep_override.so usleep_override.c 

Теперь предварительно загрузите эту библиотечную функцию перед выполнением исходной программы.

root@kali:~/so# LD_PRELOAD=./usleep_override.so ./prog
Entry point. We'll now wait 10 seconds.
20:35:28
Nope, you're not sleeping today :)
Woke up again.
20:35:28

Как вы можете видеть, глядя на date выводя, он выполнил перехваченную функцию вместо оригинала и сразу же вернулся.

Способ 2

Изменить бинарный файл. В частности, измените инструкции, чтобы usleep() функция не выполнена.

Когда мы сбрасываем инструкции main() функция prog с objdump, мы получаем:

root@kali:~/so# objdump -d -Mintel prog | grep  -A20 "<main>"
0000000000400596 <main>:
  400596:   55                      push   rbp
  400597:   48 89 e5                mov    rbp,rsp
  40059a:   48 83 ec 10             sub    rsp,0x10
  40059e:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  4005a1:   48 89 75 f0             mov    QWORD PTR [rbp-0x10],rsi
  4005a5:   bf 68 06 40 00          mov    edi,0x400668
  4005aa:   e8 a1 fe ff ff          call   400450 <puts@plt>
  4005af:   bf 90 06 40 00          mov    edi,0x400690
  4005b4:   e8 a7 fe ff ff          call   400460 <system@plt>
  4005b9:   bf 80 96 98 00          mov    edi,0x989680
  4005be:   e8 cd fe ff ff          call   400490 <usleep@plt>
  4005c3:   bf a2 06 40 00          mov    edi,0x4006a2
  4005c8:   e8 83 fe ff ff          call   400450 <puts@plt>
  4005cd:   bf 90 06 40 00          mov    edi,0x400690
  4005d2:   e8 89 fe ff ff          call   400460 <system@plt>
  4005d7:   b8 00 00 00 00          mov    eax,0x0
  4005dc:   c9                      leave  
  4005dd:   c3                      ret    
  4005de:   66 90                   xchg   ax,ax

Мы можем видеть оскорбительные строки, которые несут ответственность за usleep(10*1000*1000) вызов:

  4005b9:   bf 80 96 98 00          mov    edi,0x989680
  4005be:   e8 cd fe ff ff          call   400490 <usleep@plt>

поскольку 0x989680 равно 10000000 в десятичном виде, мы можем сделать вывод, что это аргумент для usleep() функция. Таким образом, мы можем просто изменить двоичный файл (поиск последовательности байтов bf 80 96 98 00 e8 cd fe ff ff) и вместо этого просто положить 0x90 там для NOP инструкция, которая ничего не делает.

До и после: hex_comparison

Когда мы сейчас сбрасываем инструкции:

root@kali:~/so# objdump -d -Mintel prog_cracked | grep  -A28 "<main>"
0000000000400596 <main>:
  400596:   55                      push   rbp
  400597:   48 89 e5                mov    rbp,rsp
  40059a:   48 83 ec 10             sub    rsp,0x10
  40059e:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  4005a1:   48 89 75 f0             mov    QWORD PTR [rbp-0x10],rsi
  4005a5:   bf 68 06 40 00          mov    edi,0x400668
  4005aa:   e8 a1 fe ff ff          call   400450 <puts@plt>
  4005af:   bf 90 06 40 00          mov    edi,0x400690
  4005b4:   e8 a7 fe ff ff          call   400460 <system@plt>
  4005b9:   90                      nop
  4005ba:   90                      nop
  4005bb:   90                      nop
  4005bc:   90                      nop
  4005bd:   90                      nop
  4005be:   90                      nop
  4005bf:   90                      nop
  4005c0:   90                      nop
  4005c1:   90                      nop
  4005c2:   90                      nop
  4005c3:   bf a2 06 40 00          mov    edi,0x4006a2
  4005c8:   e8 83 fe ff ff          call   400450 <puts@plt>
  4005cd:   bf 90 06 40 00          mov    edi,0x400690
  4005d2:   e8 89 fe ff ff          call   400460 <system@plt>
  4005d7:   b8 00 00 00 00          mov    eax,0x0
  4005dc:   c9                      leave  
  4005dd:   c3                      ret    
  4005de:   66 90                   xchg   ax,ax

Хорошо, звонок пропал. Беги и получим:

root@kali:~/so# chmod +x prog_cracked 
root@kali:~/so# ./prog_cracked 
Entry point. We'll now wait 10 seconds.
21:11:18
Woke up again.
21:11:18

И, таким образом, программа снова "взломана".

Другие вопросы по тегам