破解linux可执行文件

时间:2014-04-11 23:26:39

标签: linux assembly reverse-engineering exploit

我有一个linux可执行文件及其反汇编程序(特别是,程序会检查我是否超级用户,如果是这样,通过执行函数&#34输出一些消息; start_reactor"并退出;如果我&# 39; m不是超级用户程序调用另一个函数" check_password"),我需要的是通过输入一些特定的字符串来找到破解它的方法(执行函数" start_reactor")功能输入" check_password"。

下面是可执行文件的解集..

08048504 <check_password>:
8048504:    55                   push   ebp
8048505:    89 e5                mov    ebp,esp
8048507:    b8 00 00 00 00       mov    eax,0x0
804850c:    5d                   pop    ebp
804850d:    c3                   ret    

0804850e <start_reactor>:
804850e:    55                   push   ebp
804850f:    89 e5                mov    ebp,esp
8048511:    83 ec 04             sub    esp,0x4
8048514:    c7 04 24 90 86 04 08 mov    DWORD PTR [esp],0x8048690
804851b:    e8 0c ff ff ff       call   804842c <printf@plt>
8048520:    c7 04 24 2e 00 00 00 mov    DWORD PTR [esp],0x2e
8048527:    e8 d0 fe ff ff       call   80483fc <putchar@plt>
804852c:    a1 60 98 04 08       mov    eax,ds:0x8049860
8048531:    89 04 24             mov    DWORD PTR [esp],eax
8048534:    e8 e3 fe ff ff       call   804841c <fflush@plt>
8048539:    c7 04 24 01 00 00 00 mov    DWORD PTR [esp],0x1
8048540:    e8 07 ff ff ff       call   804844c <sleep@plt>
8048545:    eb d9                jmp    8048520 <start_reactor+0x12>

08048547 <main>:
8048547:    55                   push   ebp
8048548:    89 e5                mov    ebp,esp
804854a:    83 ec 1c             sub    esp,0x1c
804854d:    c7 45 f8 be ba fe ca mov    DWORD PTR [ebp-0x8],0xcafebabe
8048554:    e8 e3 fe ff ff       call   804843c <getuid@plt>
8048559:    85 c0                test   eax,eax
804855b:    0f 94 c0             sete   al
804855e:    0f b6 c0             movzx  eax,al
8048561:    89 45 fc             mov    DWORD PTR [ebp-0x4],eax
8048564:    83 7d fc 00          cmp    DWORD PTR [ebp-0x4],0x0
8048568:    75 24                jne    804858e <main+0x47>
804856a:    c7 04 24 b0 86 04 08 mov    DWORD PTR [esp],0x80486b0
8048571:    e8 b6 fe ff ff       call   804842c <printf@plt>
8048576:    a1 60 98 04 08       mov    eax,ds:0x8049860
804857b:    89 04 24             mov    DWORD PTR [esp],eax
804857e:    e8 99 fe ff ff       call   804841c <fflush@plt>
8048583:    8d 45 e8             lea    eax,[ebp-0x18]
8048586:    89 04 24             mov    DWORD PTR [esp],eax
8048589:    e8 5e fe ff ff       call   80483ec <gets@plt>
804858e:    81 7d f8 be ba fe ca cmp    DWORD PTR [ebp-0x8],0xcafebabe
8048595:    74 18                je     80485af <main+0x68>
8048597:    c7 04 24 d8 86 04 08 mov    DWORD PTR [esp],0x80486d8
804859e:    e8 b9 fe ff ff       call   804845c <puts@plt>
80485a3:    c7 04 24 ff ff ff ff mov    DWORD PTR [esp],0xffffffff
80485aa:    e8 bd fe ff ff       call   804846c <exit@plt>
80485af:    83 7d fc 00          cmp    DWORD PTR [ebp-0x4],0x0
80485b3:    75 0f                jne    80485c4 <main+0x7d>
80485b5:    8d 45 e8             lea    eax,[ebp-0x18]
80485b8:    89 04 24             mov    DWORD PTR [esp],eax
80485bb:    e8 44 ff ff ff       call   8048504 <check_password>
80485c0:    85 c0                test   eax,eax
80485c2:    74 05                je     80485c9 <main+0x82>
80485c4:    e8 45 ff ff ff       call   804850e <start_reactor>
80485c9:    c9                   leave  
80485ca:    c3                   ret    
80485cb:    90                   nop    
80485cc:    90                   nop    
80485cd:    90                   nop    
80485ce:    90                   nop    
80485cf:    90                   nop    

..和使用IDA进行反向生成的结果。

int __cdecl main()
{
  __uid_t v0; // eax@1
  int result; // eax@7
  char s; // [sp+4h] [bp-18h]@2
  int v3; // [sp+14h] [bp-8h]@1
  bool v4; // [sp+18h] [bp-4h]@1

  v3 = -889275714;
  v0 = getuid();
  v4 = v0 == 0;
  if ( v0 != 0 )
  {
    printf("Please enter the password to continue: ");
    fflush(stdout);
    gets(&s);
  }
  if ( v3 != -889275714 )
  {
    puts(" ");
    exit(-1);
  }
  if ( v4 || (result = check_password()) != 0 )
    start_reactor();
  return result;
}

我对Assembler来说真的很新...... :(

2 个答案:

答案 0 :(得分:4)

这是一个缓冲区溢出漏洞。

您必须溢出s才能覆盖v3v4

这让我认为schar s[16]

  char s; // [sp+4h] [bp-18h]@2  // 18h - 8h = 10h
  int v3; // [sp+14h] [bp-8h]@1

但是在v3中你必须输入-889275714,所以在十六进制0xcafebabe(&lt; 3 it btw:D)

然后用0x01

覆盖布尔值

所以基本上,你想用:

启动你的二进制文件

perl -e 'print "junk_for_sssssss\xbe\xba\xfe\xca\x01"' | ./binary

需要注意的是,由于您的潜在小端架构,您需要输入\ xbe \ xba \ xfe \ xca而不是\ xca \ xfe \ xba \ xbe

答案 1 :(得分:1)

在我看来,你已经对这个程序有了足够的了解。使用fakeroot运行它(也许是一个VM - 取决于你从哪里得到它)。 不是说check_output只做0但是没有做任何事情,所以没有办法说服它执行start_reactor而不重写程序集或以root用户或fakeroot方式启动它。

08048504 <check_password>:
8048504:    55                   push   ebp      // function header
8048505:    89 e5                mov    ebp,esp  // function header
8048507:    b8 00 00 00 00       mov    eax,0x0  // result = 0
804850c:    5d                   pop    ebp      // function footer
804850d:    c3                   ret             // return to callee

当然如果你想修改文件(在磁盘上或在内存中),那么有一百万种方法可以解决这个问题(例如,改变一些跳转使它指向start_reactor函数是一种标准方法)。并且你总是可以反转start_reactor函数本身,因为它很短 - 在这种情况下,我会建议你通过谷歌查找各个命令,并试着了解它自己做了什么......