Browse Source

US47: Covert Channel Method - Options field

Sander, Paul 4 years ago
parent
commit
3cb5a13214
2 changed files with 152 additions and 0 deletions
  1. 129 0
      daemon/include/CovertChannel/TCPOptionCustomChannel.hpp
  2. 23 0
      daemon/src/main.cpp

+ 129 - 0
daemon/include/CovertChannel/TCPOptionCustomChannel.hpp

@@ -0,0 +1,129 @@
+#ifndef TCPOPTIONCUSTOMCHANNEL_H
+#define TCPOPTIONCUSTOMCHANNEL_H
+
+#include "CovertChannel.h"
+#include "CovertProtocolBidirectional.hpp"
+
+/**
+ * @class TCPOptionCustom
+ *
+ * A CovertChannel which hides data in a custom field in the TCP options data
+ *
+ * In theory, any options field can be used to store data. This implementation specifically uses field 11 (CC).
+ * For (un)usable fields, refer to the IANA listing at
+ * https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml
+ *
+ * @param N number of bytes which can be used to transmit data
+ * @param PASSIVE true - server only reacts to incoming channel | false - server initiates channel
+ */
+template <int N, bool PASSIVE> class TCPOptionCustomChannel : public CovertChannel {
+	static_assert(N <= 255 - 2);
+	public :
+	    /**
+	     * Sets up a CovertChannel.
+	     *
+	     * Creates a CovertChannel, sets the network interfaces for sniffing and sending and sets the filter.
+	     *
+	     * @param innerInterface name of the interface of the inner network
+	     * @param outerInterface name of the interface of the outer network
+	     * @param ownIP IP of this server
+	     * @param targetIP IP of the target server
+	     * @param targetPort Port of the target server
+	     */
+	    TCPOptionCustomChannel(const std::string &innerInterface, const std::string &outerInterface, const std::string &ownIP, const std::string &targetIP,
+	                    const std::string &targetPort)
+	    : CovertChannel(innerInterface, outerInterface,
+	                    "(not (tcp and " + std::string(PASSIVE ? "src" : "dst") + " host " + targetIP + " and " + std::string(PASSIVE ? "src" : "dst") +
+	                        " port " + targetPort + ")) and (not (dst host " + ownIP + "))",
+	                    "(not (tcp and " + std::string(PASSIVE ? "dst" : "src") + " host " + targetIP + " and " + std::string(PASSIVE ? "dst" : "src") +
+	                        " port " + targetPort + ")) and (not (dst host " + ownIP + "))",
+	                    "tcp and " + std::string(PASSIVE ? "src" : "dst") + " host " + targetIP + " and " + std::string(PASSIVE ? "src" : "dst") + " port " +
+	                        targetPort,
+	                    "tcp and " + std::string(PASSIVE ? "dst" : "src") + " host " + targetIP + " and " + std::string(PASSIVE ? "dst" : "src") + " port " +
+	                        targetPort) {}
+
+	/**
+	 * Destroys the CovertChannel.
+	 */
+	virtual ~TCPOptionCustomChannel() {}
+
+	/**
+	 * Send a file over the covert channel.
+	 *
+	 * @param fileName name of the file in the file directory
+	 * @return true - file will be sent | false - file was not accepted
+	 */
+	virtual bool sendFile(const std::string &fileName) {
+		if constexpr (PASSIVE) {
+			return false;
+		} else {
+			return protocol.sendFile(fileName);
+		}
+	}
+
+protected:
+	// this is the id of the option as found in the article found at the top
+	const unsigned int target_options_id = 11;
+	
+	/**
+	 * Handler for sniffed packets filterd to forward from the outer network.
+	 *
+	 * Handles incoming packets and forwards them.
+	 *
+	 * @param pdu sniffed packet
+	 *
+	 * @return false = stop loop | true = continue loop
+	 */
+	virtual bool handleChannelFromOuter(Tins::PDU &pdu) {
+		Tins::TCP &tcp = pdu.rfind_pdu<Tins::TCP>();
+
+		const Tins::TCP::options_type &options = tcp.options();
+		Tins::TCP::option op;
+		size_t i;
+		// find option field
+		for (i = 0; i < options.size(); i++) {
+			if (options[i].option() == target_options_id) {
+				op = options[i];
+				break;
+			}
+		}
+		if (i != options.size() && options[i].data_size()) {
+			// found the option
+			protocol.receive((uint8_t *)(options[i].data_ptr()));
+			tcp.remove_option((Tins::TCP::OptionTypes)target_options_id);
+		}
+		
+		innerSender.send(pdu);
+
+		return true;
+	}
+
+	/**
+	 * Handler for sniffed packets filterd to forward from the inner network.
+	 *
+	 * Handles incoming packets and forwards them.
+	 *
+	 * @param pdu sniffed packet
+	 *
+	 * @return false = stop loop | true = continue loop
+	 */
+	virtual bool handleChannelFromInner(Tins::PDU &pdu) {
+		Tins::TCP &tcp = pdu.rfind_pdu<Tins::TCP>();
+		uint8_t data[N];
+		protocol.send(data);
+		
+		Tins::TCP::option op(target_options_id, N, data);
+		tcp.add_option(op);
+		
+		outerSender.send(pdu);
+
+		return true;
+	}
+
+	/**
+	 * protocol used to transmit data
+	 */
+	CovertProtocolBidirectional<N, PASSIVE> protocol;
+};
+
+#endif

+ 23 - 0
daemon/src/main.cpp

@@ -5,6 +5,7 @@
 #include "../include/CovertChannel/ForwardChannel.h"
 #include "../include/CovertChannel/TCPAppendChannel.hpp"
 #include "../include/CovertChannel/TCPOptionTimestampChannel.hpp"
+#include "../include/CovertChannel/TCPOptionCustomChannel.hpp"
 #include "../include/CovertChannel/TCPUrgencyChannel.hpp"
 #include "../include/Server.h"
 #include "../include/UserManager.h"
@@ -80,6 +81,28 @@ int main(int argc, char *argv[]) {
 			covertchannel = new TCPOptionTimestampChannel<false>(innerInterface, outerInterface, ownIP, targetIP, targetPort);
 		}
 
+		// test sending file
+		if (passiveMode != "true" && sendFile != "")
+			covertchannel->sendFile(sendFile);
+
+		// covertchannel = new ForwardChannel(innerInterface, outerInterface);
+		covertchannel->startSniffing();
+	} else if (covertChannelMode == "tcpoptioncustom") {
+		const string innerInterface = Config::getValue("innerInterface");
+		const string outerInterface = Config::getValue("outerInterface");
+
+		const string ownIP = Config::getValue("ownIP");
+		const string targetIP = Config::getValue("targetIP");
+		const string targetPort = Config::getValue("targetPort");
+		const string passiveMode = Config::getValue("passiveMode");
+		const string sendFile = Config::getValue("sendFile");
+
+		if (passiveMode == "true") {
+			covertchannel = new TCPOptionCustomChannel<8, true>(innerInterface, outerInterface, ownIP, targetIP, targetPort);
+		} else {
+			covertchannel = new TCPOptionCustomChannel<8, false>(innerInterface, outerInterface, ownIP, targetIP, targetPort);
+		}
+
 		// test sending file
 		if (passiveMode != "true" && sendFile != "")
 			covertchannel->sendFile(sendFile);