简单的万能密码
在web中存在诸如’ or 1=1–类似的万能密码,其实现原理是sql的闭合,导致执行逻辑永真,于是绕过登录密码的限制。
同理,在c语言的项目中也可能会出现同样的问题。
示例代码:
1 |
|
显而易见,在strcmp后有一个很奇怪的strcpy。它将一个大字符串覆盖到小字符串中会出现数组越界的问题。当攻击者构造一个长度足够长的字符串并将其赋值给szBuffer时,数组越界并覆盖到了nFlag,使得条件永真,条件判断失效。
正常情况下的数组内容
当输入小于数组szBuffer长度的内容的时候,即正常情况下的内存布局如图:
字符串结尾的’\0’正是万能密码的关键。
众所周知,strcmp函数比较两个字符串的内容,返回值如下:
1 | 如果返回值 < 0,则表示 str1 小于 str2。 |
当输入纯数字时,由于数字的ascii码比字母小,所以返回值>0,结果为1。当对nFlag取反时即变为假,此时的逻辑为正常逻辑。
那么,当攻击者构造了一个足够长的数组以至于可以覆盖掉nFlag的内容会发生什么呢?
经过构造后的数组
可以看出,字符串的结尾’\0’覆盖掉了本应属于nFlag的位置,导致nFlag=0,逻辑判断成立,最简单的万能密码完成。
当strcmp的返回值为负数时的情况
如题,当字符串大于PASSWORD的值的时候回出现什么问题呢?
由此可见,没有办法对负数的条件进行修改。由于用户无法直接输入真正的’0’,导致高三位的ff无法被覆盖,取反后仍然是零。没办法对负数进行绕过。