|
Georgi Guninski发现Linux上的qmail-smtpd 1.03存在漏洞可导致出发段错误。问题存在于如下代码中:
void blast(hops)
int *hops;
...
int pos; /* number of bytes since most recent \n, if fih */
...
if (pos < 9) {
if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;
...
++pos;
...
当pos增加到足够长时,就会变成负值并当pos到0x80000000后就能绕过(pos<9)检查,然后 "delivered"[pos]会引起段错误。存在以qmaild进程权限执行任意指令的可能。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- main()
- {int pos;
- pos=0x80000000;
- if (pos<9)
- {printf("the pos is less than 9\n");
- exit(0);
- }
- printf("the pos is %d \n" ,pos);
- exit(0);
- }
复制代码
说明,上面的说明很清除了我就不多说了.主要和个位研究的是宰割漏洞
我这己天有空模拟了漏洞的情况,如果定义的pos不是太大,返回的结果非常正确
胆识用了 上面的数字后就绕过了if判断但是却执行了条件中的打印
结果核对信息发现,0x80000000在 ansi 的c中是-2147483648
大家很明显的看出问题了把,这个数字小于9,所以不是逻辑判断没判断
是条件成立!
具体肯能gcc的定义和ansi有区别,但是我想肯可能差不多就是这原因了
我对上面的代码金星了 修改,把变量改做unsigned long得到的结果就符合原来的要求打印出了pos直=-2147483648
问题的原因似乎找到了但是也许不是个很好的办法
目前qmail补丁我还没看到,也许之能大家手动修改代码了 .....
这也是开源软件的优点,哈哈 |
|