|
@@ -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
|