zoukankan      html  css  js  c++  java
  • 栈溢出实践

     1 #include <stdio.h>
     2 #define PASSWORD "1234567"
     3 int verify_password (char *password)
     4 {
     5     int authenticated;
     6     char buffer[8];
     7     authenticated=strcmp(password,PASSWORD);
     8     strcpy(buffer,password);//over flowed here!    
     9     return authenticated;
    10 }
    11 void main(void)
    12 {
    13     int valid_flag=0;
    14     char password[1024];
    15     FILE * fp;
    16     if(!(fp=fopen("password.txt","rw+")))
    17     {
    18         exit(0);
    19     }
    20     fscanf(fp,"%s",password);
    21     valid_flag = verify_password(password);
    22     if(valid_flag)
    23     {
    24         printf("incorrect password!
    ");
    25     }
    26     else
    27     {
    28         printf("You have passed the verification!
    ");
    29     }
    30     fclose(fp);
    31 }

    编译成debug版本后,用ollydbg打开,

    由图可知通过验证的程序分支的指令地址是0x00401122  如果把返回地址覆盖成这个地址。则程序将直接跳转到验证通过分支。

    buffer[0~3]

    buffer[4~7]

    authenticated

    前栈帧EBP

    返回地址

    在password.txt中,将4321作为一个输入单元,buffer[8]需要2个单元,第三个单元将authenticated覆盖,第四个将EBP覆盖,第五个单元将返回地址覆盖。

    用十六进制编辑器UltraEdit将第五个修改为0x00401122即可实现跳转。

    代码植入:

    将以上程序稍加修改:

     1 #include <stdio.h>
     2 #include <windows.h>
     3 #define PASSWORD "1234567"
     4 int verify_password(char *password)
     5 {
     6     int authenticated;
     7     char buffer[44];
     8     authenticated = strcmp(password, PASSWORD);  // = ,return 0
     9     strcpy(buffer, password);
    10     return authenticated;
    11 }
    12 void main(void)
    13 {
    14     int valid_flag = 0;
    15     char password[1024];
    16     FILE *fp;
    17     LoadLibrary("user32.dll");    //for messagebox
    18     if(!(fp = fopen("password.txt","rw+")))
    19     {
    20         exit(0);
    21     }
    22     fscanf(fp,"%s",password);
    23     valid_flag = verify_password(password);
    24     if(valid_flag)
    25         printf("incorrect password !
    ");
    26     else
    27         printf("You have passed the verification !
    ");
    28     fclose(fp);
    29     getchar();
    30 
    31 }

    将在password.txt植入用来调用Win API函数MessageBoxA的二进制机器码。

    buffer[44]需要11个4321单元....第14个将返回地址覆盖。

    先在password.txt写入44个字符,则第45个隐藏的截断符null将冲掉authenticated低字节中的1,从而通过验证,此时运行程序可通过。

  • 相关阅读:
    POJ1185:炮兵阵地(状压dp)
    POJ3254:Corn Fields(状压dp第一发)
    二进制x&(x-1);
    子集和问题(应用--换零钱)POJ2229:Sumsets
    JAVA math包
    UVA+POJ中大数实现的题目,持续更新(JAVA实现)
    HDU中大数实现的题目,持续更新(JAVA实现)
    SDUT中大数实现的题目,持续更新(JAVA实现)
    JAVA与ACM
    HDU3123:GCC(同余模简单题)
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4334930.html
Copyright © 2011-2022 走看看