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,从而通过验证,此时运行程序可通过。

  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/ht-beyond/p/4334930.html
Copyright © 2011-2022 走看看