登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

A1Pass的风清月朗居

追随技术的巅峰,突破欲望的枷锁!我,是技术与精神的享乐者!

 
 
 
 
 

日志

 
 

一个利用缓冲区溢出修改程序流程的小例子  

2009-07-21 23:19:31|  分类: 思绪燃星火——技 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

题记:扎实的基础永远都是王道。

 

    最近一直在闭关修炼,填补不足,砸实基础,因此已经有近两个月没有发表技术方面的文章,深感愧疚。

    今天我为大家带来的是一个利用缓冲区溢出原理修改程序流程的密码验证程序,此程序利用数组越界造成溢出,淹没返回地址,跳转到一个我们事先精心准备好的函数当中,在此函数当中判断密码,并返回成功/出错信息。

     即兴练手而写,很简单的代码,废话不多说,直接看代码:

 

/**************************************************************************
名字:密码验证程序
------
特点:
------
1、利用缓冲区溢出隐式修改程序执行流程,使得静态逆向跟踪更加困难。
2、采用靶子函数,伪造验证流程,误导破解者。
3、密码采用二维数组保存,插入了大量的垃圾信息保证安全性。
4、比对前释放假密码,迷惑破解者。
5、验证成功与失败关键字均加密保存,应用时动态解密,为爆破设置障碍。

------
原理:
------
    利用缓冲区溢出更改程序流程,将原有程序所调用的靶子函数
PassCmpFun(void)流程转移到PassCmp(void)里,并由PassCmp(void)判定
真正的密码。

------
信息:
------
正确密码:521technic

      函数名    调用地址    函数地址    返回地址
   PassCmpFun  0x0041386E  0x004111EF  0x00413873
      PassCmp  0x00413879  0x004111F4  0x0041387E

日期:2009-07-20   作者:A1Pass
**************************************************************************/

#include <stdio.h>
#include <stdlib.h>


int iRight[10]={0xf0, 0xef, 0xf1, 0xd8, 0xe6, 0xce, 0xfb, 0x84, 0x90, 0x92};  //加密后的验证成功字串
int iError[12]={0xf0, 0xef, 0xf1, 0xd8, 0x87, 0xde, 0xfd, 0xc0, 0x90, 0x92};  //加密后的验证失败字串

char cRight[12]={0};
char cError[15]={0};

 

//真实判定函数
int PassCmp(void)
{
    int iNum[2]={8,9},iTag=0,i,j;  //忽悠人……
    iNum[1]=7;  //为溢出留位置,在此函数里无用

    char szInPass[12]={0};
    char szPass[10][5]={{"5432"},{"2345"},{"1234"},{"tagy"},{"ef11"},\
    {"cijh"},{"hijk"},{"nopq"},{"ijhu"},{"cdef"}}; //只取每个数组的第一位
   

    for (i=0;i<2;i++)
    {
        int iTag=1;
        printf("请输入密码(6-10位):");
        scanf("%10s",szInPass);
        fflush(stdin);
        for (j=0;j<10;j++)
        {
            if(szInPass[j]==szPass[j][0])
            {
                iTag++;
            }
        }

        char cNoPass[11]="51asm51asm";  //干扰内存定位

        if (iTag>=10)
        {
            //加密字串解密---------------
            for (i=0;i<10;i++)
            {
                cRight[i]=iRight[i]^51;
            }//--------------------------
            printf("%s",cRight);
            return 1;
        }
        else if(i>=1)
        {
            //加密字串解密---------------
            for (i=0;i<10;i++)
            {
                cError[i]=iError[i]^51;
            }//--------------------------
            printf("%s",cError);
        }
    }
    return 0;
}


//靶子函数,数据结构与真正函数PassCmp()一样,增加迷惑性
int PassCmpFun(void)
{
    int iNum[2]={8,9},iTag=0,i,j;
    iNum[5]=0x00413879;  //覆盖PassCmpFun()函数返回地址到PassCmp()开始处,此地址不固定。
    char szInPass[12]={0};
    char szPass[10][5]={{"2345"},{"5432"},{"4321"},{"tagy"},{"ef22"},\
                       {"cijh"},{"hijk"},{"nopq"},{"ijhu"},{"cdef"}};
    char cNoPass[11]="51asm51asm";
    for (i=0;i<1;i++)
    {
        int iTag=1;
        printf("请输入密码(6-10位):");
        scanf("%10s",szInPass);
        fflush(stdin);
        for (j=0;j<10;j++)
        {
            if(szInPass[j]==szPass[j][0])
            {
                iTag++;
            }
        }

        char cNoPass[11]="51asm51asm";  //干扰内存定位

        if (iTag==20)
        {
            printf("密码正确!");
            return 1;
        }
        else if(i>=2)
        {
            printf("密码错误!\r\n");
        }
    }
    return 0;
}


//主函数
int main()
{
    int iTest = 1;  //忽悠人用的……

    iTest--;  //使下面的IF语句始终为假

    PassCmpFun();  //调用靶子函数

    if (iTest)
    {
        int iTag;
        iTag=PassCmp();  //真实判定函数入口
        if (iTag==1)
        {
            printf("精彩!");
        }
    }

    printf("\r\n\r\n");
    system("pause");
    return 0;
}

  评论这张
 
阅读(1791)| 评论(9)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018