使用usleep()对bash程序进行时间攻击

使用usleep()对bash程序进行时间攻击,bash,dynamic-linking,usleep,Bash,Dynamic Linking,Usleep,我有一个小黑客,我必须用蛮力获取密码。程序中有函数usleep();当我有正确的长度时,当一个字母正确时,它就会改变。 这不会是一个问题,但睡眠时间大约是一分钟,这是一个相当长的时间。 有没有办法让usleep定时器更快 ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接(使用共享库)方法1 您可以使用LD\u PRELOAD指令重写库函数 这里有一个很好的教程,让你开始学习 假设您有以下程序代码,然后将其编译为二进制elf文件 #include <stdio.h&

我有一个小黑客,我必须用蛮力获取密码。程序中有函数usleep();当我有正确的长度时,当一个字母正确时,它就会改变。 这不会是一个问题,但睡眠时间大约是一分钟,这是一个相当长的时间。 有没有办法让usleep定时器更快

ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接(使用共享库)

方法1 您可以使用
LD\u 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;
}
现在编写自己版本的
usleep()

现在,在执行原始程序之前预加载该库函数

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
正如您在查看
日期
输出时所看到的,它执行了hooked函数而不是原始函数,然后立即返回

方法2 修改二进制文件。特别是,修改指令,使
usleep()
函数不执行

当我们使用
objdump
转储
prog
main()
函数的指令时,我们得到:

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
由于
0x989680
在十进制中等于10000000,我们可以推断这是
usleep()
函数的参数。因此,我们只需修改二进制文件(搜索字节序列
bf 80 96 98 00 e8 cd fe ff ff
),而只需将
0x90
放在那里作为
NOP
指令,它什么也不做

前后:

当我们现在转储指令时:

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
因此,程序再次被“破解”。

方法1 您可以使用
LD\u 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;
}
现在编写自己版本的
usleep()

现在,在执行原始程序之前预加载该库函数

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
正如您在查看
日期
输出时所看到的,它执行了hooked函数而不是原始函数,然后立即返回

方法2 修改二进制文件。特别是,修改指令,使
usleep()
函数不执行

当我们使用
objdump
转储
prog
main()
函数的指令时,我们得到:

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
由于
0x989680
在十进制中等于10000000,我们可以推断这是
usleep()
函数的参数。因此,我们只需修改二进制文件(搜索字节序列
bf 80 96 98 00 e8 cd fe ff ff
),而只需将
0x90
放在那里作为
NOP
指令,它什么也不做

前后:

当我们现在转储指令时:

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

因此,该程序再次被“破解”。

发布一些特定于该问题的代码将有助于回答您的问题。如果不太麻烦的话,最高质量的问题会将问题抽象出来,因此它更普遍地适用于寻求类似答案的其他用户。LD_预加载一个覆盖我们的库。反驳一些特定于问题的代码对任何试图回答你的问题的人都会有帮助。如果不太麻烦的话,最高质量的问题会将问题抽象出来,因此更普遍地适用于寻求类似答案的其他用户。LD_预加载覆盖usleep的库
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