C与C++安全编码
有关字符串的一些概念
字符串
c语言中都是以数组存储字符串,以\0作为字符串结尾,低位地址是数组首元素地址,高位地址是数组末元素地址。
sizeof 用来计算数组大小。但是对于数组与指针应用时,sizeof对同一个数组的大小计算不同。果然我们学的是基础的c语言,如果当时学仔细一点,就应该发现这个问题的。
宽字节简单来说就是大一点的字符,需要更多空间。
字符串字面值就是这个字符串的值,宽字符串前缀是L
字符串类型:C语言中字符串常量类型为int
以下结果是4,1.告诉我们C语言中神奇的存储,我以前都没怎么注意说实话…
计算字符串大小
strlen函数是我们经常用来计算字符串元素个数的,但是如果应用于宽字节,就会导致错误。strlen函数一旦遇到空字节就判断字符串结束,但是宽字符包含空字节。所以会产生错误。
字符串的常见错误
最常见的字符串错误:无界字符串复制错误,差一错误,空结尾错误,字符串截断错误。
一、无界字符串复制
例如gets就是一个很麻烦的例子。
当定义数组小于输入字符串时,就会发生错误。
同样的,命令行参数输入,如果复制进定义的数组,但是定义数组空间不够的话,就会发生错误。
二、差一错误
与数组越界类似,预定数组长度不够的情况下会发生。
三、空字符结尾错误
指的是字符串数组没有以正确的空字符结尾。
比如,strncpy复制不超过n个字符,很可能为复制进空字符结尾,这样会导致数组很大很大,超过想象,那么对另一个数组进行操作时,就会发生错误。有时候编译器不会告诉你错误,但是漏洞就会存在。
四、字符串截断
数组长度不足以容纳一个字符串的内容时,会发生字符串截取,程序员为了防止缓冲区溢出,可能会用到字符串截取,有可能会导致丢失数据或者出现漏洞。
五、与函数无关的字符串错误
这个我感觉发生的概率比前几个高。
简略版代码:(略略略)buff[128] buff[i]=a[i] buff[i]=’\0’
字符串漏洞及其利用
一、缓冲区溢出
名字虽然很高深的样子,其实就是数组或者特定分配的内存空间外写进数据,就称为缓冲区溢出。未进行隐式的边界检查。
二、栈管理及栈溢出
基本概念:从C语言来说就是 先进后出 的某个对内存的操作后的内存(= =)
一般来说,弹 出栈 意味着栈指针需要 递增 。栈在压入变量之后一般还会在最后压入返回地址,这意味着一旦这一段结束即可返回。(可能是错的,只是暂时的总结)
栈溢出:由于栈在内存中按顺序存储,一个栈可能存储许多不同类型的数据,包括变量,指针,地址等等。如果用户恶意输入,很可能使得数据泄露或者越过某些数据检验。比如,简单的弧注入攻击。
代码注入:被恶意注入的代码也叫外壳代码,攻击者往往利用某个子例程的返回地址导致栈混乱,从而获取该程序相同的权限,如果是root权限,即是开一个远程shell,获取最高权限。
恶意参数的特征:(感觉很有趣)
|
|
个人觉得第一点是程序写的不好,第二点是你输入的恶意参数必须能干点事,第三点就是你不能输入的参数直接把程序搞崩。
题目
给出了a.out
第一步,反汇编。核心代码如下。
|
|
main函数中跳转到vul函数,重点关注read(0, a, 0x3E8u)这句话,这个是把a的大小放入内存,这样就容易造成栈溢出。
|
|
由char a[100]; // [sp+Ch] [bp-6Ch]@1可知,a的实际内存大小为108再加上ebp的大小一共为112。再跳到xiaoxiannv那个函数。
再就是关于linux命令的知识了。