CC++语言的软件安全漏洞
Unsafe String Functions
A few of the string functions declared in the standard <string.h> and <stdio.h> headers are notoriously unsafe.
1.
Strcpy When used carelessly this function can overflow the buffer reserved for its output string. Use strlcpy() instead. strncpy This function can leave its destination buffer without a null string terminator. It also has performance problems. Again, use strlcpy(). strcat Same issue as strcpy(). Use strlcat() instead. strncat The meaning of its buffer size argument is surprising. Again, use strlcat(). strtok Uses global data, so it is unsafe in threaded programs such as kernels. Use strtok_r() instead.
防止Format String问题
防止格式化字符串漏洞一般的规则是在所有需要格式化的字符串的程序中不使用 非常量的格式化字符参数.
原
型
错误用法
正确用法
int printf(char *,…) int fprintf(FILE *,char *,….) int snprintf(char *,size_t, char *,….) Void syslog(int priority,char *format,…)
Example 1: The following code reads from cfgfile and copies the input into inputbuf using strcpy(). The code mistakenly assumes that inputbuf will always contain a null terminator.
Vulnerabilities in C / C++
Fortify China Consultant:WangHong hwang@
Course Objectives
In this chapter, we will Examine some unsafe features of the C language Take an over view of things to think about when writing code
Buffer Overflow(缓冲区溢出)
Buffer Overflow(缓冲区溢出) 对所分配的内存块进行写操作时,没有对输入数据的大小作验证,造成输 入数据的大小超出了目的内存的存储范围,使得临近目的内存块的数据被覆 盖(Overflow)从而使程序崩溃,甚至导致执行恶意代码.
Buffer Overflow
Command Injection---Sample2
Sample2: ... char* home=getenv("APPHOME"); char* cmd=(char*)malloc(strlen(home)+strlen(INITCMD)); if (cmd) { strcpy(cmd,home); strcat(cmd,INITCMD); execl(cmd, NULL); } ... 从系统中取出的变量正确的时候,程序正常运行。 攻击者变化系统变量,变量进入命令,造成命令注入攻击。
2.
3. 4.
5.
Deprecated formatted string output functions
1.
sprintf
You should never use the sprintf function; use asprintf instead This function will behave unpredictably if the string to which it is printing overlaps any of its arguments. It is dangerous because the characters output to the string may overflow it i.e. the size of the output is larger than allocated space ! This problem cannot be solved with the field width modifier to the conversion specifier, because only the minimum field width can be specified with it. To avoid this problem Use asprintf, but there is a lot of C code that still uses sprintf, so it is important to know about it.
Format String
Format String(格式化字符串): 允许用户去控制格式化字符串的函数的参数,将导致黑客读取堆 栈信息或者进行buffer overflow攻击. 阶段 1.不可信的数据通过用户进入程序. 2.进入的数据被作为函数的格式化字符参数 比如,printf(),sprintf(), FormatMessageW(), or syslog().
Memory Leak
#define MAXLEN 1024 ... char *pathbuf[MAXLEN]; ... read(cfgfile,inputbuf,MAXLEN); //does not null terminate strcpy(pathbuf,inputbuf); //requires null terminated input
String Termination Error
依赖于字符串终止符的操作有可能造成缓冲区溢出。 字符串终止错误在以下两种情况下发生 数据通过一个函数的输出进入另一个需要字符终止符输入的函数作操作, 而作为输出函数的字符没有字符终止符. 数据被传输到一个需要字符终止符的操作函数.但数据没有字符终止符结 尾.
printf(user_supplied_string) Printf(“%s”,user_supplied_s tring) fprintf(stderr,user_supplied _string) Snprintf(buffer,sizeof(buffe r),user_supplied_string) syslog(LOG_CRIT,string) fprintf(stderr,”%s,user_sup plied_string); Snprintf(buffer,sizeof(buffer ),”%s”,user_supplied_string) Syslog(LOG_CRIT,”%s”,strin g)
pass = get_password(); ... fprintf(dbms_log, "%d:%s:%s:%s", id, pass, type, tstamp);
Password Management
把口令写在程序代码里,可能危及系统安全,并且也不容易修改. 所有项目的开发人员都知道口令. 一旦系统部署后,很难去修改口令
Buffer Overflow分类: 1.Stack Overflow : 静态内存分配 调用function时,在stack中分配一块内存作为buffer 攻击方式 : 覆盖stack 数据,造成segmentation fault --改变程序流程. --改变返回地址.(return address) 2.Heap Overflow : 动态内存分配 在function中利用动态内存分配方式(ex:malloc(),new()),取得 buffer的空间配置. 攻击方式: pointer overwrite, Vtable overwrite, SEH
Format String---sample
Example 1: The following code copies a command line argument into a buffer using snprintf(). int main(int argc, char **argv){ char buf[128]; ... snprintf(buf,128,argv[1]);
C/C++主要的漏洞
Buffer Overflow (缓冲溢出) Command Injection (命令注入) Format String (格式化字符串) String Termination Error (字符结尾错误) Password Management: Hardcoded Password (口令管理) Privacy Violation (私密信息违规管理) Double Free (两次释放同一块内存) Memory Leak (内存泄露)
Example: The following code uses a hardcoded password to connect to a database: ... rc = SQLConnect(*hdbc, server, SQL_NTS, “scott”, SQL_NTS, “tiger”, SQL_NTS); …