我有一个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来说真的很新...... :(
答案 0 :(得分:4)
这是一个缓冲区溢出漏洞。
您必须溢出s
才能覆盖v3
和v4
。
这让我认为s
是char 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
函数本身,因为它很短 - 在这种情况下,我会建议你通过谷歌查找各个命令,并试着了解它自己做了什么......