#ifndef TCPOPTIONCUSTOMCHANNEL_H #define TCPOPTIONCUSTOMCHANNEL_H #include "../BidirectionalChannels.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 class TCPOptionCustomChannel : public BidirectionalChannels { 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 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 &targetIP, const std::string &targetPort) : BidirectionalChannels(innerInterface, outerInterface, targetIP, targetPort) {} /** * Destroys the CovertChannel. */ virtual ~TCPOptionCustomChannel() {} 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(); 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 BidirectionalChannels::protocol.receive((uint8_t *)(options[i].data_ptr())); tcp.remove_option((Tins::TCP::OptionTypes)target_options_id); } BidirectionalChannels::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(); uint8_t data[N]; BidirectionalChannels::protocol.send(data); Tins::TCP::option op(target_options_id, N, data); tcp.add_option(op); BidirectionalChannels::outerSender.send(pdu); return true; } }; #endif