| die letzten Änderungen * Seitenstruktur * Stichwortsuche :


logo_puschin.jpg

Startseite

Knowledge base



Kontakt

Impressum

Knowledge base - Firewall

Knowledge base

5 Benutzer online Druckversion




zurück



Firewall
Tamper data on wire mit NFQUEUE-Skript

Dieses Skript kann Daten, die durch ein System laufen on-the-fly verändern und weitersenden.

Beispiel:

# ./tamper gzip ezip



(HTTP-Verbindungen werden nicht mehr komprimiert, da Schlüsselwort gzip fehlt).

Einbinden mit:

#!/bin/sh
iptables -t mangle --flush
iptables -t mangle -A FORWARD -p tcp --dport 80  -j NFQUEUE --queue-num 0



Kompilieren mit:

gcc -Wall -o tamper checksum.c tamper.c -lnfnetlink -lnetfilter_queue -lmnl



tamper.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <time.h>

#include "checksum.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char one[1024];
char two[1024];

static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data)
{
    struct nfqnl_msg_packet_hdr *ph;
    int payload_len;

    unsigned char *payloadData;

    struct iphdr *ipHeader;
    struct tcphdr *tcpHeader;
    struct udphdr *udpHeader;
    unsigned short ipCheck, udpCheck, tcpCheck;

    ph = nfq_get_msg_packet_hdr(nfa);
    u_int32_t id = ntohl(ph->packet_id);

    // Payload einladen
    //
    payload_len = nfq_get_payload(nfa, &payloadData);
    ipHeader = (struct iphdr *)payloadData;
    ipCheck = ipHeader->check;

    int i = 0;
    int j = 0;
    int found = 1;
    int one_found = 0;

    // Zeitstempel
    //
    time_t t;
    char buffer[1024];
    struct tm ltime;

    t = time (0);
    localtime_r (& t, & ltime);

    // Zeitstempel ausgeben
    //
    strftime (buffer, 1024, "%d.%m.%Y %H:%M:%S", & ltime);
    printf ("[%s] ", buffer);

    // Vorher ausgeben
    //
    for (i = 0; i < payload_len; i++)
    {
        if (isprint(payloadData[i])) { printf("%c", payloadData[i]); }
    }
    printf("\n");

    for (i = 0; i < payload_len - strlen(one); i++)
    {
        found = 1;

        for (j = 0; j < strlen(one); j++)
        {
            if (payloadData[i+j]!=one[j])
            {
                found = 0;
                break;
            }
        }

        if (found == 1)
        {
            one_found = 1;

            for (j = 0; j < strlen(one); j++)
            {
                payloadData[i+j]=two[j];
            }
        }
    }

    if (one_found == 1)
    {
        // Zeitstempel ausgeben
        //
        strftime (buffer, 1024, "%d.%m.%Y %H:%M:%S", & ltime);
        printf ("--> [%s] ", buffer);

        // Nachher ausgeben
        //
        for (i = 0; i < payload_len; i++)
        {
            if (isprint(payloadData[i])) { printf("%c", payloadData[i]); }
        }
        printf("\n--\n");
    }

    // Checksumme berechnen
    //
    compute_ip_checksum(ipHeader);

    if (ipHeader->protocol == IPPROTO_TCP)
    {
        tcpHeader = (struct tcphdr *)(payloadData + (ipHeader->ihl<<2));
        tcpCheck = tcpHeader->check;
        compute_tcp_checksum(ipHeader, (unsigned short*)tcpHeader);
    } else if (ipHeader->protocol == IPPROTO_UDP)
    {
        udpHeader = (struct udphdr *)(payloadData + (ipHeader->ihl<<2));
        udpCheck = udpHeader->check;
        compute_udp_checksum(ipHeader, (unsigned short*)udpHeader);
        if (udpHeader->check != udpCheck)
        {
            //
        }
    }

    return nfq_set_verdict(qh, id, NF_ACCEPT, payload_len, payloadData);
}

int main(int argc, char **argv) {
    struct nfq_handle *h;
    struct nfq_q_handle *qh;
    //struct nfnl_handle *nh;
    int fd;
    int rv;
    char buf[4096] __attribute__((aligned));

    printf("tamper v0.0.0.1 - tamper data on the fly\n");

    if (argc == 3)
    {
            if (strlen(argv[1]) != strlen(argv[2]))
            {
                printf("Die Länge der Strings muss identisch sein!\n");
                exit(0);
            }
            else
            {
                strcpy(one, argv[1]);
                strcpy(two, argv[2]);
            }
    }
    else
    {
        printf("tamper [string] [replace]\n");
        exit(0);
    }


    /*netfilter_queue library set up step 1: call nfq_open to open a NFQUEUE handler*/
    printf("opening library handle\n");
    h = nfq_open();
    if (!h) {
        fprintf(stderr, "error during nfq_open()\n");
        exit(1);
    }
    /*set up step 2: tell the kernel that userspace queuing is handled by NFQUEUE for the selected protocol. This is
    made by calling nfq_unbind_pf and nfq_bind_pf with protocol info. The idea behind this is to enable simulataneously                                                                                         loaded modules to be used for queuing*/
    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);
    }
    /*after the above two steps, we can set up and use a queue*/
    /*bind the program to a specific queue, cb is callback function to call for each queued packet
    *h: netfilter queue handle, 0: the number of the queue to bind to, cb: callback function for each queued packet, data:                                                                                      custom data to pass to callback function*/
    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);
    }
    /*set mode: NFQNL_COPY_PACKET: copy entire packet, it defines the part of data that nfqueue copies to userspace
    0xffff: size of the packet that we want to get*/
    printf("setting copy_packet mode\n");
    if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
        fprintf(stderr, "cannot set packet_copy mode\n");
        exit(1);
    }
    /*handle the incoming packets*/
    fd = nfq_fd(h);
    while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
//      printf("pkt received\n");
        nfq_handle_packet(h, buf, rv);
    }
    printf("unbinding from queue 0\n");
    nfq_destroy_queue(qh);
    /*the program has finished with libnetfilter_queue, it can call nfq_close to free all associated resources*/
    printf("closing library handle\n");
    nfq_close(h);
    exit(0);
}



checksum.c:

#include <stdio.h>
#include <linux/types.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>

/* Compute checksum for count bytes starting at addr, using one's complement of one's complement sum*/
static unsigned short compute_checksum(unsigned short *addr, unsigned int count) {
  register unsigned long sum = 0;
  while (count > 1) {
    sum += * addr++;
    count -= 2;
  }
  //if any bytes left, pad the bytes and add
  if(count > 0) {
    sum += ((*addr)&htons(0xFF00));
  }
  //Fold sum to 16 bits: add carrier to result
  while (sum>>16) {
        sum = (sum & 0xffff) + (sum >> 16);
  }
  //one's complement
  sum = ~sum;
  return ((unsigned short)sum);
}

/* set ip checksum of a given ip header*/
void compute_ip_checksum(struct iphdr* iphdrp){
  iphdrp->check = 0;
  iphdrp->check = compute_checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);
}

/*validate ip checksum, result should be 0 if IP header is correct*/
u_int16_t validate_ip_checksum(struct iphdr* iphdrp){
  return compute_checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);
}

/* set tcp checksum: given IP header and tcp segment */
void compute_tcp_checksum(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, %d\n", 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;
}

/* set tcp checksum: given IP header and UDP datagram */
void compute_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload) {
        register unsigned long sum = 0;
        struct udphdr *udphdrp = (struct udphdr*)(ipPayload);
        unsigned short udpLen = htons(udphdrp->len);
        //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~udp len=%d\n", udpLen);
        //add the pseudo header
        //printf("add pseudo header\n");
        //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: 17
        sum += htons(IPPROTO_UDP);
        //the length
        sum += udphdrp->len;

        //add the IP payload
        //printf("add ip payload\n");
        //initialize checksum to 0
        udphdrp->check = 0;
        while (udpLen > 1) {
                sum += * ipPayload++;
                udpLen -= 2;
        }
    //if any bytes left, pad the bytes and add
    if(udpLen > 0) {
                //printf("+++++++++++++++padding: %d\n", udpLen);
        sum += ((*ipPayload)&htons(0xFF00));
    }
        //Fold sum to 16 bits: add carrier to result
        //printf("add carrier\n");
        while (sum>>16) {
                sum = (sum & 0xffff) + (sum >> 16);
        }
        //printf("one's complement\n");
        sum = ~sum;
        //set computation result
        udphdrp->check = ((unsigned short)sum == 0x0000)?0xFFFF:(unsigned short)sum;
}



checksum.h:

#include <stdio.h>

/* set ip checksum of a given ip header*/
void compute_ip_checksum(struct iphdr* iphdrp);
/*validate ip checksum, result should be 0 if IP header is correct*/
unsigned short validate_ip_checksum(struct iphdr* iphdrp);
/* set tcp checksum: given IP header and TCP header, and TCP data */
void compute_tcp_checksum(struct iphdr *pIph, unsigned short *ipPayload);
/* set tcp checksum: given IP header and TCP header, and TCP data */
void compute_udp_checksum(struct iphdr *pIph, unsigned short *ipPayload);


zurück



Knowledge base wurde zuletzt bearbeitet am 12.07.13 durch Frank

www.puschin.de
login

<body bgcolor='#FFFFFF' link='#000000' vlink='#000000' alink='#000000' text='#000000'><font face='Verdana' size='2'><strong>www.puschin.de</strong><br>Die Webseite http://www.puschin.de bietet eine interessante Webseite zu vielen Themen aus dem Bereich Linux und Windows. Man findet hier Tipps und Tricks zu cms php apache postfix openxchange tomcat windows linux firewall <br><br><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=191'>Startseite</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=63'>Knowledge base</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=57'>Kontakt</a><font face='Verdana' size='2'><li><a href='cms.php?print=&aktion=thema_anzeigen&menue_id=9'>Impressum</a></body>