LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 935|回复: 3

关于qmail超长smtp漏洞的研究~~~~

[复制链接]
发表于 2004-2-15 15:11:58 | 显示全部楼层 |阅读模式
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进程权限执行任意指令的可能。



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>

  5. main()
  6. {int pos;

  7.   pos=0x80000000;
  8.   if (pos<9)
  9.    {printf("the pos is less than 9\n");
  10.     exit(0);
  11.    }
  12.   printf("the pos is %d \n" ,pos);
  13. exit(0);
  14. }
复制代码


说明,上面的说明很清除了我就不多说了.主要和个位研究的是宰割漏洞
我这己天有空模拟了漏洞的情况,如果定义的pos不是太大,返回的结果非常正确
胆识用了 上面的数字后就绕过了if判断但是却执行了条件中的打印
结果核对信息发现,0x80000000在 ansi 的c中是-2147483648
大家很明显的看出问题了把,这个数字小于9,所以不是逻辑判断没判断
是条件成立!
具体肯能gcc的定义和ansi有区别,但是我想肯可能差不多就是这原因了
我对上面的代码金星了 修改,把变量改做unsigned long得到的结果就符合原来的要求打印出了pos直=-2147483648

问题的原因似乎找到了但是也许不是个很好的办法

目前qmail补丁我还没看到,也许之能大家手动修改代码了 .....
这也是开源软件的优点,哈哈
发表于 2004-2-15 18:44:20 | 显示全部楼层
其实这个就是整数溢出,一个比较让程序员难受的错误

你说他是错误也不是,反正让人感觉不尴不尬的
发表于 2004-2-16 10:04:05 | 显示全部楼层
这个不是gcc和ansi c定义不同吧?
另外,能不能少点错别字?
 楼主| 发表于 2004-2-16 11:35:52 | 显示全部楼层
老哥类似这个意思吧,我想所以研究研究
另外输入法问题。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表