[LSD] IRIX rpc.xfsmd multiple remote root vulnerabilities

From: Last Stage of Delirium (contact@lsd-pl.net)
Date: Thu Jun 20 2002 - 15:19:51 PDT

  • Next message: securityat_private: "Security Update: [CSSA-2002-028.0] Linux: dhcpd dynamic DNS format string vulnerability"

    We have 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 metacharacter, 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 successfull, 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()
    vulnerablity 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
    
    The proof of concept code illustrating the above mentioned IRIX Xfsmd
    vulnerabilities can be found on our website at the following address:
    
       http://lsd-pl.net/files/get?IRIX/irx_xfsmd
    
    Best regards,
    Members of LSD Research Group
    
    
    --------------------------------------------------------------------------------
    Last Stage of Delirium Research Group
                                                                      *://lsd-pl.net
    --------------------------------------------------------------------------------
    



    This archive was generated by hypermail 2b30 : Thu Jun 20 2002 - 13:08:23 PDT