题记:扎实的基础永远都是王道。
最近一直在闭关修炼,填补不足,砸实基础,因此已经有近两个月没有发表技术方面的文章,深感愧疚。
今天我为大家带来的是一个利用缓冲区溢出原理修改程序流程的密码验证程序,此程序利用数组越界造成溢出,淹没返回地址,跳转到一个我们事先精心准备好的函数当中,在此函数当中判断密码,并返回成功/出错信息。
即兴练手而写,很简单的代码,废话不多说,直接看代码:
/**************************************************************************
名字:密码验证程序
------
特点:
------
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;
}
评论