zoukankan      html  css  js  c++  java
  • 【逆向】《0day安全-软件漏洞分析技术》实验笔记1

    Crack 小实验

    工具

    • Dev C++(书上使用的VS)
    • IDA_Pro_v7.0
    • Ollydbg
    • LordPE
    • 010 editor

    使用IDA打开文件

    • 找到程序分支点
    • 空格跳转到汇编界面
    • 得到VA:0x40156d

    使用OD打开文件

    • Ctrl+G跳转到IDA得到的VA
    • 加断点,运行,此时输入任意密码,回车后程序在此中断。
    • 我们只要把je改成jne就能实现输入错误密码返回正确结果。


    使用LordPE打开文件

    • OD修改只是修改了内存中的值
    • 利用公式计算:
      文件偏移地址 = 虚拟内存地址(VA) - 装载基址 - 节偏移
      = 0x0040156D - 0x00400000 - (0x1000 - 0x400)
      = 0x96D

    使用十六进制编辑器修改文件

    • 010Editor打开文件
    • Ctrl + G 跳转到0x96D
    • 修改740e为750e
    • 保存运行
    • 输入正确密码显示密码错误,错误密码会返回正确的提示

    实验 2.2.2 突破密码验证程序

    知识点

    实验环境与工具

    • Win10 64bit
    • Dev-C++
    • IDA-Pro
    • OD

    实验记录

    • 代码:
       1 #include <stdio.h>
       2 #include <string.h>
       3 
       4 #define PASSWORD "1234567"
       5 
       6 int verify_password(char *password)
       7 {
       8     int authenticated;
       9     char buffer[8];
      10     authenticated=strcmp(password,PASSWORD);
      11     strcpy(buffer,password);
      12     return authenticated;
      13 }
      14 
      15 int main()
      16 {
      17     int valid_flag = 0;
      18     char password[1024];
      19     while(1)
      20     {
      21         printf("Please input password:     ");
      22         scanf("%s", password);
      23         valid_flag = verify_password(password);
      24         if(valid_flag)
      25         {
      26             printf("incorrect password!
      
      ");
      27         }
      28         else
      29         {
      30             printf("Congratulation! You have passed the verification!
      ");
      31             break;
      32         }
      33     }
      34     return 0;
      35 }

    实验步骤

    • 运行测试:
    • 静态反汇编:
      • strcpy后一句地址为0x401532
    • 动态调试
      • 输入"qqqqqq",authenticated的值为1
      • 输入"qqqqqqqq"尝试使用字符串末尾的''把authenticated的低字节覆盖从而变成0

      • 成功绕过了验证

    实验 2.3.2 更改返回地址

    实验工具

    • 010 Editor
    • Dev C++
    • IDA-Pro
    • OD

    实验知识点

    • 缓冲区溢出覆盖栈内函数的返回地址

    实验源码

     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);
     9     return authenticated;
    10 }
    11 
    12 main()
    13 {
    14     int valid_flag=0;
    15     char password[1024];
    16     FILE *fp;
    17     if(!(fp=fopen("password.txt","rw+")))
    18     {
    19         exit(0);
    20     }
    21     fscanf(fp,"%s",password);
    22     valid_flag = verify_password(password);
    23     if(valid_flag)
    24     {
    25         printf("incorrect password!
    ");
    26     }
    27     else
    28     {
    29         printf("Congratulation!You Have passed the verification!
    ");
    30     }
    31     fclose(fp);
    32 }

    实验步骤

    • 运行测试
    • 静态反编译,strcpy下一句为0x40152e,密码正确的分支是0x4015ca

    • 动态调试
      • 当前栈帧的EBP是0x61fa78
      • 查看栈的内容
      • 尝试直接修改返回地址,成功跳转到正确密码的分支

      • 使用二进制编辑器构造payload
      • 运行,虽然会闪退,但是通过捕捉,可以发现确实跳转到了正确的分支

    实验 2.4 代码植入

    实验工具

    • Windows XP SP3
    • Visual C++ 6.0
    • Depends
    • OD

    源码

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

    实验步骤

    1. 编译程序并且拖入Depends,发现并没有user32.dll
    2. 从编辑器里面打开dll文件,发现也可以看到库的基地址,user32.dll的库基地址为0x77D10000,MessageBoxA的偏移地址为0x407EA,地址为0x77D5 07EA‬

    3. 先用123422343234423452346234来找到栈中buffer的位置,buffer的起始地址是0x12FAF0

    4. 构造password.txt
    5. 代码植入成功
    6. 运行测试

    遇到的问题

    • Depends的结果与实验指导上的不一样,没有显示出user32.dll的库基地址
      • 从编辑器打开user32.dll:
  • 相关阅读:
    CTS、CLS、CLR分别作何解释?
    C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
    net中读写数据库需要用到那些类?他们的作用?
    什么叫应用程序域?
    一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。
    override与重载的区别
    请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
    求以下表达式的值,写出您想到的一种或几种实现方法: 12+34+……+m
    什么是强类型系统?
    在下面的例子里
  • 原文地址:https://www.cnblogs.com/tiumo/p/11280543.html
Copyright © 2011-2022 走看看