人为漏洞的构造和程序密码验证机制的突破

 1 // stack_overflow.cpp : Defines the entry point for the console application.
 2  //
 3  
 4  #include "stdafx.h"
 5  #include <string.h>   //strcmp、strcpy
 6  #include <STDIO.H>    //printf
 7  #include <conio.h>    //getch
 8  //全局变量保存真码
 9  #define  PASSWORD "1234567"
10  //密码验证函数
11  int verify_password(char *password)
12  {
13      int authenticated;   //保存验证结果
14      char buffer[8];   
15      authenticated = strcmp(password,PASSWORD);   //真码与假码的比较
16      strcpy(buffer,password);                     //将输入的假码放入缓冲区
17      return authenticated;                        //返回结果
18  }
19  
20  int main(int argc, char* argv[])
21  {
22      int valid_flag= 0;
23      char password[1024];
24      while(1)
25      {
26          printf("please input password:    ");
27          scanf("%s",password);
28          valid_flag = verify_password(password);
29          if (valid_flag)
30          {
31              printf("incorrect password!\n\n");
32          } 
33          else
34          {
35              printf("Congratulation!You have passed the verification!\n");
36              break;
37          }
38      }
39      getch();
40      return 0;
41  }
42  

对应的反汇编程序:

 1 00401070 >/$  81EC 00040000 sub     esp, 400                                      ;  _main
 2  00401076  |>  68 88804000   /push    offset <InputInfo>                           ;  ASCII "please input password:    "
 3  0040107B  |.  E8 67000000   |call    <_printf>
 4  00401080  |.  8D4424 04     |lea     eax, dword ptr [esp+4]
 5  00401084  |.  50            |push    eax
 6  00401085  |.  68 84804000   |push    offset <InputFormat>                         ;  ASCII "%s"
 7  0040108A  |.  E8 41000000   |call    <_scanf>
 8  0040108F  |.  8D4C24 0C     |lea     ecx, dword ptr [esp+C]
 9  00401093  |.  51            |push    ecx
10  00401094  |.  E8 67FFFFFF   |call    <func_verify_password>
11  00401099  |.  83C4 10       |add     esp, 10
12  0040109C  |.  85C0          |test    eax, eax
13  0040109E  |.  74 0F         |je      short 004010AF
14  004010A0  |.  68 6C804000   |push    offset <BadInfo>            ;  ASCII "incorrect password!",LF,LF
15  004010A5  |.  E8 3D000000   |call    <_printf>
16  004010AA  |.  83C4 04       |add     esp, 4
17  004010AD  |.^ EB C7         \jmp     short 00401076
18  004010AF  |>  68 38804000   push    offset <GoodInfo>                             
; ASCII "Congratulation!You have passed the verification!",LF 19 004010B4 |. E8 2E000000 call <_printf> 20 004010B9 |. E8 68580000 call <__getch> 21 004010BE |. 33C0 xor eax, eax 22 004010C0 |. 81C4 04040000 add esp, 404 23 004010C6 \. C3 retn 24 25

当输入异常时,就会出现:

然而,仅仅覆盖所需的结果不只是我们需要的,有时候我们更希望能覆盖返回地址。

这样,我们就可以跳转到程序的其它地方去执行我们希望的代码。

 

在这之前,我们先看看返回地址的位置和其中的数据是什么。

verify_password函数的下一行代码,就是这个。

我们的目标是淹没这个地址,使其指向我们希望的地址。

由于我们输入的字符,始终有一些缺憾,不能直接输入对应的数值使其指向我们希望的地方,所以下次我们构造一个使用文件类型的漏洞来进行

利用演示。

posted @ 2012-10-06 13:25  r3call  阅读(601)  评论(0编辑  收藏  举报