
2.3.1 被污染的数据
例2.3是一个简单的程序,它检查用户密码(应考虑被污染的数据),并授权或拒绝访问。
例2.3 IsPasswordOK()程序
01 bool IsPasswordOK(void) { 02 char Password[12]; 03 04 gets(Password); 05 r eturn 0 == strcmp(Password, "goodpass"); 06 } 07 08 int main(void) { 09 bool PwStatus; 10 11 puts("Enter password:"); 12 PwStatus = IsPasswordOK(); 13 if (PwStatus == false) { 14 puts("Access denied"); 15 exit(-1); 16 } 17 }
该程序仅仅是用来演示字符串是如何被误用的,并非密码检查之范本程序。这个IsPasswordOK()程序从main()函数开始执行。执行的第一行代码是调用puts()打印出一段字符串字面值。在C标准中,puts()函数被定义为字符输出函数,它在<stdio.h>中声明,其功能是在由stdout所指向的输出流中写入一个字符串并且以换行符('\n')结尾。IsPasswordOK()函数紧接着被调用,从用户那里获取一个密码。该函数返回一个布尔值,如果密码有效将返回true,如果无效则返回false。后面的程序检测PwStatus的值,以决定是否给用户授权或者拒绝用户访问。
IsPasswordOK()函数使用gets()函数从(stdin所指向的)输入流中读取字符,存储到由Password所指向的数组中,直到遇见文件结束(end-of-file,EOF)标志或者换行符。任何换行符都将被丢弃,并且当最后一个字符被读入数组后,立即会加上一个用作结尾的空字符。<string.h>头文件中定义的strcmp()函数将由Password所指向的字符串和字符串字面量“goodpass”作比较,如果两者相同,它将返回一个值为0的整数,如果两者不同,则返回值不为0。IsPasswordOK()函数在用户输入的密码等于“goodpass”时返回true,main()函数以此为依据决定是否授权用户访问。
在程序第一次运行中(参见图2.2),用户输入正确的密码,因此被授权访问。
第二次运行中(参见图2.3),用户输入的密码不正确,因此系统拒绝用户的访问。
遗憾的是,该程序包含一个安全缺陷,该缺陷允许攻击者绕过密码保护逻辑,直接获得对程序的访问权限。你能识别出这个缺陷吗?
图2.2 用户输入正确的密码,因此被授权访问
图2.3 用户输入的密码不正确,因此被拒绝访问