/// <summary> /// The handler for HTTP GET requests. /// </summary> /// <param name="processor">The HTTP processor.</param> public void HttpGetHandler(HttpProcessor processor) { processor.WriteSuccess(); Cryptkeeper myCrypt = new Cryptkeeper(this.passphrase); DerivedValue derived = new DerivedValue(this.passphrase); string result = derived.GetString(3, 10); // No result? No handshake. Done. if (processor.RequestURL.IndexOf(result) == -1) return; // Parse out the host name and fetch the next page. string hostname = string.Empty; string absolutePath = processor.RequestURL; string[] values = absolutePath.Split(new string[] { result }, StringSplitOptions.RemoveEmptyEntries); absolutePath = values[0].Trim(); string hostBase64 = values[1].Trim(); byte[] hostBytes = System.Convert.FromBase64String(hostBase64); hostname = Encoding.ASCII.GetString(hostBytes); Uri link = new Uri(string.Concat("http://", hostname, absolutePath)); try { WebClient web = new WebClient(); byte[] page = web.DownloadData(link); web.Dispose(); WebPageSteganography stegopage = new WebPageSteganography(page, this.passphrase); string message = string.Empty; if (this.MessageQueue.Count > 0) { message = (string)this.MessageQueue.Dequeue(); } stegopage.WriteValue(message); page = stegopage.GetBytes(); processor.StreamOutput.Write(page); processor.StreamOutput.Flush(); processor.WriteSuccess(); } catch (Exception ex) { processor.StreamOutput.Write("<html><p>Ping! Something odd happened while retrieving ... " + link.ToString() + "</p><p>" + ex.ToString() + "</p></html>"); } }
/// <summary> /// Provides a one-time, preprocessing functionality for the cmdlet. /// </summary> protected override void BeginProcessing() { // Initialize parameters and base Incog cmdlet components this.InitializeComponent(); // Verify the browser history file path this.BrowserHistoryFile = ConsoleTools.ExpandAndVerifyPath(this, this.BrowserHistoryFile); StreamReader history = new StreamReader(this.BrowserHistoryFile.FullName); string text = history.ReadToEnd(); string[] lines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); this.links = new Uri[lines.Length]; for (int i = 0; i < this.links.Length; i++) { this.links[i] = new Uri(lines[i]); this.WriteVerbose(string.Format("Loading ... {0}", this.links[i].ToString())); } // Invoke Interative Mode if selected if (this.Interactive) this.InteractiveMode(); // Set the default TCP port if (this.TCP == 0) this.TCP = 80; // Get a derived value to indicate where the path and host split DerivedValue derived = new DerivedValue(this.Passphrase); string split = derived.GetString(3, 10); int linkIndex = 0; do { // Get the host and path of the next URL string host = this.links[linkIndex].Host; string absolutePath = this.links[linkIndex].AbsolutePath; // Get the host as a base64 encoded string byte[] hostBytes = System.Text.Encoding.ASCII.GetBytes(host); string hostBase64 = System.Convert.ToBase64String(hostBytes); // Get the resulting link -- absolute path and host in base 64 Uri resultingLink = new Uri(string.Concat( "http://", this.RemoteAddress.ToString(), ":", this.TCP.ToString(), absolutePath, split, hostBase64)); try { // Create a request for the URL and set the timeout WebRequest request = WebRequest.Create(resultingLink); request.Timeout = request.Timeout * 2; // Get the response WebResponse response = request.GetResponse(); // Display the status this.WriteVerbose(resultingLink.ToString()); this.WriteVerbose(((HttpWebResponse)response).StatusDescription); // Get the stream containing content returned by the server Stream dataStream = response.GetResponseStream(); // Read in the stream into a buffer int growBufferBy = 1024; byte[] buffer = new byte[10240]; byte[] page; int index = 0; do { int i = dataStream.ReadByte(); if (i == -1) { page = new byte[index]; Array.Copy(buffer, page, index); break; } buffer[index] = Convert.ToByte(i); index++; if (index == buffer.Length) { byte[] temp = new byte[buffer.Length + growBufferBy]; Array.Copy(buffer, temp, buffer.Length); buffer = new byte[temp.Length]; Array.Copy(temp, buffer, temp.Length); } } while (true); response.Close(); // Feed the bytes into a stego page and test WebPageSteganography stegoPage = new WebPageSteganography(page, this.Passphrase); string message = stegoPage.ReadValue(); // Break on exit if (message.Trim().ToLower() == "exit") break; if (message != string.Empty) { if (this.Interactive) { Console.WriteLine("{0} > {1}", this.RemoteAddress.ToString(), message); } else { this.WriteObject(message); } } } catch (System.Net.Sockets.SocketException ex) { this.WriteVerbose(ex.InnerException.ToString()); break; } catch (Exception ex) { if (ex.InnerException != null) { if (ex.InnerException.GetType() == typeof(System.Net.Sockets.SocketException)) { this.WriteWarning(ex.InnerException.Message); break; } } this.WriteWarning(ex.ToString()); } linkIndex++; if (linkIndex == this.links.Length) linkIndex = 0; System.Threading.Thread.Sleep(500); } while (true); }
/// <summary> /// Interactive Mode allows the user to key in message after message, and have the message sent over the covert channel. /// </summary> private void InteractiveMode() { // Update the screen with the parameters of the chat session this.PrintInteractiveMode(ChannelTools.CommunicationMode.Alice); // Wait for the client connection this.WriteVerbose("Waiting for client connect . . ."); NamedPipeServerStream pipeServer = new NamedPipeServerStream( this.CmdletGuid, PipeDirection.InOut); DerivedValue derived = new DerivedValue(this.Passphrase); string handshake = derived.GetString(3, 12); this.WriteVerbose(string.Format("Handshaking with {0}.", handshake)); pipeServer.WaitForConnection(); this.WriteVerbose("Connected. Ready to send chat messages."); try { // Read the request from the client IncogStream stream = new IncogStream(pipeServer, this.Passphrase, this.TargetEntropy); // Verify our identity to the connected client using a handshake string stream.WriteString(handshake); do { Console.Write("{0}> ", this.CmdletName); string line = Console.ReadLine(); if (line == string.Empty) continue; stream.WriteString(line); if (line.ToLower() == "exit") break; } while (true); } catch (System.IO.IOException e) { // Catch the IOException that is raised if the pipe is broken or disconnected. this.WriteWarning(e.Message); } pipeServer.Close(); }
/// <summary> /// Provides a one-time, preprocessing functionality for the cmdlet. /// </summary> protected override void BeginProcessing() { // Initialize parameters and base Incog cmdlet components this.InitializeComponent(); // Invoke Interative Mode if selected if (this.Interactive) this.InteractiveMode(); // Start the connection this.WriteVerbose("Connecting to server . . ."); NamedPipeClientStream pipeClient = new NamedPipeClientStream( this.RemoteAddress.ToString(), this.CmdletGuid, PipeDirection.InOut, PipeOptions.None, System.Security.Principal.TokenImpersonationLevel.Impersonation); DerivedValue derived = new DerivedValue(this.Passphrase); string handshake = derived.GetString(3, 12); this.WriteVerbose(string.Format("Handshaking with {0}.", handshake)); pipeClient.Connect(); IncogStream stream = new IncogStream(pipeClient, this.Passphrase); // Validate the server's signature string if (stream.ReadString() == handshake) { // The client security token is sent with the first write. // Print the file to the screen. this.WriteVerbose("Connected. Incoming chat messages."); do { string message = stream.ReadString(); if (message == string.Empty) { Thread.Sleep(250); continue; } if (message.Trim().ToLower() == "exit") { break; } if (this.Interactive) { Console.WriteLine("{0} > {1}", this.RemoteAddress.ToString(), message); } else { this.WriteObject(message); } } while (true); } else { this.WriteVerbose("The connected failed because of an invalid server handshake."); } pipeClient.Close(); // Give the client process some time to display results before exiting. Thread.Sleep(2000); }