Schlagwort-Archive: TCP

BitBasics – Crashkurs Netzwerkprotokolle

BitBasics - Crashkurs Netzwerkprotokolle

(69 MB) 00:25:04

2016-09-25 10:00 🛈

PC-Netzwerke sind heutzutage überall. Alleine beim lesen dieses Artikels oder schauen des Videos sind vermutlich dutzende Netzwerke aktiv.

In diesem extrakompakten Crashkurs schauen wir uns an, welche Protokolle in einem einfachen Heimnetzwerk ineinandergreifen und welche Aufgaben sie Übernehmen.

Korrekturen / Ergänzungen

  • 15:32 DNS ist ein eigenständiges Protokoll, dessen Anfrage fängt also selbst wieder bei der Anwendungsschicht an
  • 16:20 LinkLocal, MAC, NDP und ARP werden zwar vom verwendeten Protokoll der Vermittlungsschicht ausgewählt, zählen selbst aber schon zur Übertragung
  • 21:42 Bei Switchen oder Hubs bezeichnet ein Port einen Anschluss – diese haben nichts mit den Ports auf der Transportschicht zu tun.

Grafiken

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2016/09/tcp-layer-300×169.png

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2016/09/isoosi-tcp-layer-300×169.png

Weiterführende Erlkärungen

Ressourcen:

Q’n’D Windows-Shutdown-Daemon in PHP

Alles in Deckung, ich mache wieder unschönes Zeugs. Ich hatte ja bereits erklärt wie man über RPC/Samba einen Windows-PC von Linux herunterfahren kann. Leider ist die Installation von Samba aus Embedded-Systemen eine eher ungünstige Sache und ist in meinem Fall wegen Speichermangel nicht drin. Allerdings ist sowohl auf dem Embedded-System als auch dem betroffenen Rechner PHP verfügbar. I aim to misbehave.

Auf dem herunterzufahrenden Windows-Rechner wird per PHP ein TCP-Socket geöffnet. Dieser Code basiert auf einem Beispiel von Michael Kliewe. Um Scriptkiddies nicht direkt Zugang zu geben ist etwas (sehr schlechte) Challenge-Response-Authentifizierung drin – nunja, ist kein kritisches System. Wird der Client bestätigt folgt ein simples Shutdown per exec. Nicht viel, aber schnell Fertig und funktioniert:

<?php
class SocketChatServer {
    private $address = '0.0.0.0';   // 0.0.0.0 means all available interfaces
    private $port = 12345;          // the TCP port that should be used
    private $maxClients = 10;
 
    private $clients;
    private $socket;
    
    private $salt = 'YourSalt';
    private $pass = 'YourSecret';
 
    public function __construct() {
        // Set time limit to indefinite execution
        set_time_limit(0);
        error_reporting(E_ALL ^ E_NOTICE);
    }
 
    public function start() {
        // Create a TCP Stream socket
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        // Bind the socket to an address/port
        socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1);
        socket_bind($this->socket, $this->address, $this->port);
        // Start listening for connections
        socket_listen($this->socket, $this->maxClients);
 
 
        $this->clients = array('0' => array('socket' => $this->socket));
 
        while (true) {
            // Setup clients listen socket for reading
            $read[0] = $this->socket;
            for($i=1; $i<count ($this->clients)+1; ++$i) {
                if($this->clients[$i] != NULL) {
                    $read[$i+1] = $this->clients[$i]['socket'];
                }
            }
 
            // Set up a blocking call to socket_select()
            $ready = socket_select($read, $write = NULL, $except = NULL, $tv_sec = NULL);
 
            /* if a new connection is being made add it to the client array */
            if(in_array($this->socket, $read)) {
                for($i=1; $i < $this->maxClients+1; ++$i) {
                    if(!isset($this->clients[$i])) {
                        $this->clients[$i]['socket'] = socket_accept($this->socket);
                        socket_getpeername($this->clients[$i]['socket'], $ip);
                        $this->clients[$i]['ipaddy'] = $ip;
 
                        socket_write($this->clients[$i]['socket'], 'Welcome to the Shutdown Control System'."\r\n");
                        socket_write($this->clients[$i]['socket'], 'Your personal code is '.md5($this->salt.strftime('%Y-%m-%d').$ip)."\r\n");
 
                        $this->log("New client #$i connected: " . $this->clients[$i]['ipaddy']);
                        break;
                    } elseif($i == $this->maxClients - 1) {
                        $this->log('Too many Clients connected!');
                    }
 
                    if($ready < 1) {
                        continue;
                    }
                }
            }
 
            // If a client is trying to write - handle it now
            for($i=1; $i<$this->maxClients+1; ++$i) {
                if(in_array($this->clients[$i]['socket'], $read)) {
                    $data = @socket_read($this->clients[$i]['socket'], 1024, PHP_NORMAL_READ);
 
                    if($data === FALSE) {
                        unset($this->clients[$i]);
                        $this->log('Client disconnected!');
                        continue;
                    }
 
                    $data = trim($data);
 
                    if(!empty($data)) {
                        switch ($data) {
                            case 'exit':
                            case 'quit':
                                socket_write($this->clients[$i]['socket'], "Disconnecting without any action, Goodbye.\r\n");
                                $this->log("Client #$i is exiting");
                                unset($this->clients[$i]);
                                continue;
                            case 'shutdown-'.md5($this->pass.md5($this->salt.strftime('%Y-%m-%d').$ip)):
                                // first write a message to all connected clients
                                for($j=1; $j < $this->maxClients+1; ++$j) {
                                    if(isset($this->clients[$j]['socket'])) {
                                        if($this->clients[$j]['socket'] != $this->socket) {
                                            socket_write($this->clients[$j]['socket'], "System will be shut down now...\r\n");
                                        }
                                    }
                                }
                                // Close the master sockets, server termination requested
                                exec('shutdown /s /t 15 /c "System wurde per Fernbedienung ausgeschaltet"');
                                $this->log("Terminated server (requested by client #$i)");
                                exit;
                            case 'whoami':
                                // first write a message to all connected clients
                                socket_write($this->clients[$i]['socket'], "You are registred with the source IP ".$this->clients[$i]['ipaddy']." - your Code was ".md5($this->salt.strftime('%Y-%m-%d').$ip)." \r\n");
                                
                                break(2);
                            default:
                                for($j=1; $j < $this->maxClients+1; ++$j) {
                                    if(isset($this->clients[$j]['socket'])) {
                                        if(($this->clients[$j]['socket'] != $this->socket)) {
                                            $this->log($this->clients[$i]['ipaddy'] . ' is sending a message to ' . $this->clients[$j]['ipaddy'] . '!');
                                            socket_write($this->clients[$j]['socket'], '[' . $this->clients[$i]['ipaddy'] . '] says: ' . $data . "\r\n");
                                        }
                                    }
                                }
                                break(2);
                        }
                    }
                }
            }
        } // end while
    }
 
    private function log($msg) {
        // instead of echoing to console we could write this to a database or a textfile
        echo "[".date('Y-m-d H:i:s')."] " . $msg . "\r\n";
    }
}

$srv = new SocketChatServer;
$srv->start();
?>

Der Client bastelt sich eine passende Authentifizierung und spielt Zündknopf:

function pc_shutdown() {                                                                                                                                                                                                              
                $pass = 'YoutSecret';                                                                                                                                                                                                         
                                                                                                                                                                                                                                              
                $fp = fsockopen('pc.name', 12345, $errno, $errstr, 2);                                                                                                                                                                              
                if(!$fp) return false;                                                                                                                                                                                                        
                                                                                                                                                                                                                                              
                $line = fgets($fp); //Greeting                                                                                                                                                                                                
                $line = fgets($fp); //Hash                                                                                                                                                                                                    
                                                                                                                                                                                                                                              
                preg_match('/code is ([\w\d]{32})/', $line, $match);                                                                                                                                                                          
                $seed = $match[1];                                                                                                                                                                                                            
                                                                                                                                                                                                                                              
                $cmd = 'shutdown-'.md5($pass.$seed)."\n";                                                                                                                                                                                     
                                                                                                                                                                                                                                              
                fwrite($fp, $cmd);                                                                                                                                                                                                            
                                                                                                                                                                                                                                              
                var_dump(fgets($fp));                                                                                                                                                                                                         
                                                                                                                                                                                                                                              
                fclose($fp);                                                                                                                                                                                                                  
        }

Hoffen wir, dass es läuft und ich nie wieder drauf schauen muss, denn irgendwo tut sowas selbst mir weh 😉