Commit b7c87415 authored by thesw4rm's avatar thesw4rm 💬

Initial commit (boilerplate)

parents
cmake_minimum_required(VERSION 3.00)
project(control C)
#INCLUDE_DIRECTORIES(/usr/include/libnetfilter_queue)
set(CMAKE_C_STANDARD 11)
add_executable(main main.c tcp_pkt_struct.h)
target_link_libraries(main netfilter_queue)
iptables -t mangle -F PREROUTING
iptables -t mangle -F POSTROUTING
iptables -t nat -F PREROUTING
iptables -t nat -F INPUT
iptables -t nat -F POSTROUTING
# SYN Packet DEST NAT
iptables -t mangle -I POSTROUTING -p tcp --dport 8000 --tcp-flags SYN,ACK SYN -j NFQUEUE --queue-num 0 --queue-bypass
#iptables -A PREROUTING -t nat -p tcp --dport 8000 -j DNAT --to-destination 10.10.70.136:8000
#iptables -t nat -A POSTROUTING -j MASQUERADE
#iptables -t mangle -I PREROUTING -p tcp --sport 8000 --tcp-flags SYN,RST,ACK,FIN SYN,ACK -j NFQUEUE --queue-num 0 --queue-bypass # Get SYNACK handshake packet
#iptables -t mangle -A FORWARD -p tcp --dport 8000 --tcp-flags SYN,RST,ACK,FIN SYN -j MARK --set-mark 145
#iptables -t mangle -I FORWARD -p tcp --dport 8000 --tcp-flags SYN,RST,ACK,FIN SYN -j LOG --log-prefix "SYN_PACKET_DETECTED: FORWARD" --log-level 4
#iptables -t mangle -I POSTROUTING -p tcp --dport 8000 --tcp-flags SYN,RST,ACK,FIN SYN -j LOG --log-prefix "SYN_PACKET_DETECTED: POSTROUTING" --log-level 4
#include <arpa/inet.h>
#include <errno.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <linux/types.h>
#include <linux/netfilter.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "tcp_pkt_struct.h"
// TEST COMMENT
/**
* USE FOR DEBUGGING TO PRINT BINARY NUMBERS
*/
static void print_bin(uint8_t n) {
for (int i = 0; i < 8; i++) {
printf("%d", n % 2);
n /= 2;
}
}
uint16_t ipv4_checksum(struct iphdr *ipv4Header)
{
const uint16_t *data = (const uint16_t *)ipv4Header;
size_t len = sizeof(*ipv4Header);
uint32_t checksum = 0;
while (len > 1)
{
checksum += *data++;
len -= 2;
}
if (len > 0)
checksum += *(const uint8_t *)data;
while (checksum >> 16)
checksum = (checksum & 0xffff) + (checksum >> 16);
return ~checksum;
}
static void send_socket(full_tcp_pkt_t *ipv4_packet) {
int raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
// sendto(raw_socket, ipv4_packet, ipv4_packet->ipv4_header.total_length, MSG_DONTROUTE, )
}
long ipcsum(unsigned char *buf, int length) {
int i = 0;
long sum = 0;
long data;
// Handle all pairs
while (length > 1) {
// Corrected to include @Andy's edits and various comments on Stack Overflow
data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF));
sum += data;
// 1's complement carry bit correction in 16-bits (detecting sign extension)
if ((sum & 0xFFFF0000) > 0) {
sum = sum & 0xFFFF;
sum += 1;
}
i += 2;
length -= 2;
}
// Handle remaining byte in odd length buffers
if (length > 0) {
// Corrected to include @Andy's edits and various comments on Stack Overflow
sum += (buf[i] << 8 & 0xFF00);
// 1's complement carry bit correction in 16-bits (detecting sign extension)
if ((sum & 0xFFFF0000) > 0) {
sum = sum & 0xFFFF;
sum += 1;
}
}
// Final 1's complement value correction to 16-bits
sum = ~sum;
sum = sum & 0xFFFF;
return sum;
}
void rev( void *start, int size )
{
unsigned char *lo = start;
unsigned char *hi = start + size - 1;
unsigned char swap;
while (lo < hi) {
swap = *lo;
*lo++ = *hi;
*hi-- = swap;
}
}
void tcpcsum(struct iphdr *pIph, unsigned short *ipPayload) {
register unsigned long sum = 0;
unsigned short tcpLen = ntohs(pIph->tot_len) - (pIph->ihl<<2);
struct tcphdr *tcphdrp = (struct tcphdr*)(ipPayload);
//add the pseudo header
//the source ip
sum += (pIph->saddr>>16)&0xFFFF;
sum += (pIph->saddr)&0xFFFF;
//the dest ip
sum += (pIph->daddr>>16)&0xFFFF;
sum += (pIph->daddr)&0xFFFF;
//protocol and reserved: 6
sum += htons(IPPROTO_TCP);
//the length
sum += htons(tcpLen);
//add the IP payload
//initialize checksum to 0
tcphdrp->check = 0;
while (tcpLen > 1) {
sum += * ipPayload++;
tcpLen -= 2;
}
//if any bytes left, pad the bytes and add
if(tcpLen > 0) {
//printf("+++++++++++padding, %dn", tcpLen);
sum += ((*ipPayload)&htons(0xFF00));
}
//Fold 32-bit sum to 16 bits: add carrier to result
while (sum>>16) {
sum = (sum & 0xffff) + (sum >> 16);
}
sum = ~sum;
//set computation result
tcphdrp->check = (unsigned short)sum;
}
/* *
* Modifies handshake packets in attack mode.
* TODO: Replace hardcoded IP addresses with live encryption and dynamically chosen helping servers
* TODO: Handle ACK handshake packets
* */
static void modify_handshk_pkt(full_tcp_pkt_t *pkt, int pkt_len) {
/* Should match only SYN packets */
printf("\nPacket intercepted: \n");
if (pkt->tcp_header.syn == 1 && pkt->tcp_header.ack == 0) {
printf("\tPacket type: SYN\n");
}
}
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) {
u_int32_t id;
struct nfqnl_msg_packet_hdr *ph;
ph = nfq_get_msg_packet_hdr(nfa);
id = ntohl(ph->packet_id);
printf("entering callback\n");
full_tcp_pkt_t *ipv4_payload = NULL;
int pkt_len = nfq_get_payload(nfa, (unsigned char **) &ipv4_payload);
modify_handshk_pkt(ipv4_payload, pkt_len);
ipv4_payload->ipv4_header.check = 0;
ipv4_payload->ipv4_header.check =
ipcsum((unsigned char *)&ipv4_payload->ipv4_header,
20);
rev(&ipv4_payload->ipv4_header.check, 2); // Convert between endians
tcpcsum(&ipv4_payload->ipv4_header,
(unsigned short *)&ipv4_payload->tcp_header);
int ret = nfq_set_verdict(qh, id, NF_ACCEPT, (u_int32_t) pkt_len,
(void *) ipv4_payload);
printf("\n Set verdict status: %s\n", strerror(errno));
return ret;
}
uint16_t running_csum(addr_t old_src, addr_t new_src, uint16_t old_checksum) {
return ~(~old_checksum + ~old_src + (new_src));
}
int main(int argc, char **argv) {
struct nfq_handle *h;
struct nfq_q_handle *qh;
int fd;
int rv;
char buf[4096] __attribute__ ((aligned));
printf("opening library handle\n");
h = nfq_open();
if (!h) {
fprintf(stderr, "error during nfq_open()\n");
exit(1);
}
printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
if (nfq_unbind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_unbind_pf()\n");
exit(1);
}
printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
if (nfq_bind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_bind_pf()\n");
exit(1);
}
printf("binding this socket to queue '0'\n");
qh = nfq_create_queue(h, 0, &cb, NULL);
if (!qh) {
fprintf(stderr, "error during nfq_create_queue()\n");
exit(1);
}
printf("setting copy_packet mode\n");
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
fprintf(stderr, "can't set packet_copy mode\n");
exit(1);
}
fd = nfq_fd(h);
// para el tema del loss: while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0)
while ((rv = recv(fd, buf, sizeof(buf), 0))) {
printf("pkt received\n");
nfq_handle_packet(h, buf, rv);
}
printf("unbinding from queue 0\n");
nfq_destroy_queue(qh);
#ifdef INSANE
/* normally, applications SHOULD NOT issue this command, since
* it detaches other programs/sockets from AF_INET, too ! */
printf("unbinding from AF_INET\n");
nfq_unbind_pf(h, AF_INET);
#endif
printf("closing library handle\n");
nfq_close(h);
exit(0);
}
//
// Created by ytpillai on 4/13/19.
//
#ifndef USERLAND_NFQUEUE_C_CLIENT_TCP_PACKET_STRUCT_H
#define USERLAND_NFQUEUE_C_CLIENT_TCP_PACKET_STRUCT_H
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <stdint.h>
// Structs to read a manipulate a raw TCP packet
typedef uint32_t addr_t;
typedef uint16_t port_t;
/* #define HOST_IP "10.0.8.4"
#define CLIENT_IP "10.10.70.135"
#define SERVER_IP "10.10.70.136"*/
#pragma pack(push, 1)
typedef struct {
struct iphdr ipv4_header;
struct tcphdr tcp_header;
} full_tcp_pkt_t;
#pragma pack(pop)
#endif //USERLAND_NFQUEUE_C_CLIENT_TCP_PACKET_STRUCT_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment