Beispiel #1
0
static short tamperProcess(PacketNode *head, PacketNode *tail) {
    short tampered = FALSE;
    PacketNode *pac = head->next;
    while (pac != tail) {
        if (checkDirection(pac->addr.Direction, tamperInbound, tamperOutbound)
            && calcChance(chance)) {
            char *data = NULL;
            UINT dataLen = 0;
            if (DivertHelperParsePacket(pac->packet, pac->packetLen, NULL, NULL, NULL,
                NULL, NULL, NULL, (PVOID*)&data, &dataLen) 
                && data != NULL && dataLen != 0) {
                // trying to tamper the more center part of the packet,
                // since common packets put their checksum at head or tail
                if (dataLen <= 4) {
                    // for short packet just tamper it all
                    tamper_buf(data, dataLen);
                    LOG("tampered w/ chance %.1f, dochecksum: %d, short packet changed all", chance/10.0, doChecksum);
                } else {
                    // for longer ones process 1/4 of the lens start somewhere in the middle
                    UINT len = dataLen;
                    UINT len_d4 = len / 4;
                    tamper_buf(data + len/2 - len_d4/2 + 1, len_d4);
                    LOG("tampered w/ chance %.1f, dochecksum: %d, changing %d bytes out of %u", chance/10.0, doChecksum, len_d4, len);
                }
                // FIXME checksum seems to have some problem
                if (doChecksum) {
                    DivertHelperCalcChecksums(pac->packet, pac->packetLen, 0);
                }
                tampered = TRUE;
            }

        }
        pac = pac->next;
    }
    return tampered;
}
Beispiel #2
0
/*
 * Entry.
 */
int __cdecl main(int argc, char **argv)
{
    HANDLE handle, console;
    UINT i;
    INT16 priority = 0;
    char packet[MAXBUF];
    UINT packet_len;
    DIVERT_ADDRESS recv_addr, send_addr;
    PDIVERT_IPHDR ip_header;
    PDIVERT_IPV6HDR ipv6_header;
    PDIVERT_ICMPHDR icmp_header;
    PDIVERT_ICMPV6HDR icmpv6_header;
    PDIVERT_TCPHDR tcp_header;
    PDIVERT_UDPHDR udp_header;
    UINT payload_len;
    
    TCPPACKET reset0;
    PTCPPACKET reset = &reset0;
    UINT8 dnr0[sizeof(ICMPPACKET) + 0x0F*sizeof(UINT32) + 8 + 1];
    PICMPPACKET dnr = (PICMPPACKET)dnr0;

    TCPV6PACKET resetv6_0;
    PTCPV6PACKET resetv6 = &resetv6_0;
    UINT8 dnrv6_0[sizeof(ICMPV6PACKET) + sizeof(DIVERT_IPV6HDR) +
        sizeof(DIVERT_TCPHDR)];
    PICMPV6PACKET dnrv6 = (PICMPV6PACKET)dnrv6_0;

    // Check arguments.
    switch (argc)
    {
        case 2:
            break;
        case 3:
            priority = (INT16)atoi(argv[2]);
            break;
        default:
            fprintf(stderr, "usage: %s divert-filter [priority]\n",
                argv[0]);
            fprintf(stderr, "examples:\n");
            fprintf(stderr, "\t%s true\n", argv[0]);
            fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
                argv[0]);
            fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -4000\n", argv[0]);
            exit(EXIT_FAILURE);
    }

    // Initialize all packets.
    PacketIpTcpInit(reset);
    reset->tcp.Rst = 1;
    reset->tcp.Ack = 1;
    PacketIpIcmpInit(dnr);
    dnr->icmp.Type = 3;         // Destination not reachable.
    dnr->icmp.Code = 3;         // Port not reachable.
    PacketIpv6TcpInit(resetv6);
    resetv6->tcp.Rst = 1;
    resetv6->tcp.Ack = 1;
    PacketIpv6Icmpv6Init(dnrv6);
    dnrv6->ipv6.Length = htons(sizeof(DIVERT_ICMPV6HDR) + 4 +
        sizeof(DIVERT_IPV6HDR) + sizeof(DIVERT_TCPHDR));
    dnrv6->icmpv6.Type = 1;     // Destination not reachable.
    dnrv6->icmpv6.Code = 4;     // Port not reachable.

    // Get console for pretty colors.
    console = GetStdHandle(STD_OUTPUT_HANDLE);

    // Divert traffic matching the filter:
    handle = DivertOpen(argv[1], 0, priority, 0);
    if (handle == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_INVALID_PARAMETER)
        {
            fprintf(stderr, "error: filter syntax error\n");
            exit(EXIT_FAILURE);
        }
        fprintf(stderr, "error: failed to open Divert device (%d)\n",
            GetLastError());
        exit(EXIT_FAILURE);
    }

    // Main loop:
    while (TRUE)
    {
        // Read a matching packet.
        if (!DivertRecv(handle, packet, sizeof(packet), &recv_addr,
                &packet_len))
        {
            fprintf(stderr, "warning: failed to read packet\n");
            continue;
        }
       
        // Print info about the matching packet.
        DivertHelperParse(packet, packet_len, &ip_header, &ipv6_header,
            &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL,
            &payload_len);
        if (ip_header == NULL && ipv6_header == NULL)
        {
            continue;
        }

        // Dump packet info: 
        SetConsoleTextAttribute(console, FOREGROUND_RED);
        fputs("BLOCK ", stdout);
        SetConsoleTextAttribute(console,
            FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        if (ip_header != NULL)
        {
            UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
            UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;
            printf("ip.SrcAddr=%u.%u.%u.%u ip.DstAddr=%u.%u.%u.%u ",
                src_addr[0], src_addr[1], src_addr[2], src_addr[3],
                dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
        }
        if (ipv6_header != NULL)
        {
            UINT16 *src_addr = (UINT16 *)&ipv6_header->SrcAddr;
            UINT16 *dst_addr = (UINT16 *)&ipv6_header->DstAddr;
            fputs("ipv6.SrcAddr=", stdout);
            for (i = 0; i < 8; i++)
            {
                printf("%x%c", ntohs(src_addr[i]), (i == 7? ' ': ':'));
            } 
            fputs(" ipv6.DstAddr=", stdout);
            for (i = 0; i < 8; i++)
            {
                printf("%x%c", ntohs(dst_addr[i]), (i == 7? ' ': ':'));
            }
            putchar(' ');
        }
        if (icmp_header != NULL)
        {
            printf("icmp.Type=%u icmp.Code=%u ",
                icmp_header->Type, icmp_header->Code);
            // Simply drop ICMP
        }
        if (icmpv6_header != NULL)
        {
            printf("icmpv6.Type=%u icmpv6.Code=%u ",
                icmpv6_header->Type, icmpv6_header->Code);
            // Simply drop ICMPv6
        }
        if (tcp_header != NULL)
        {
            printf("tcp.SrcPort=%u tcp.DstPort=%u tcp.Flags=",
                ntohs(tcp_header->SrcPort), ntohs(tcp_header->DstPort));
            if (tcp_header->Fin)
            {
                fputs("[FIN]", stdout);
            }
            if (tcp_header->Rst)
            {
                fputs("[RST]", stdout);
            }
            if (tcp_header->Urg)
            {
                fputs("[URG]", stdout);
            }
            if (tcp_header->Syn)
            {
                fputs("[SYN]", stdout);
            }
            if (tcp_header->Psh)
            {
                fputs("[PSH]", stdout);
            }
            if (tcp_header->Ack)
            {
                fputs("[ACK]", stdout);
            }
            putchar(' ');


            if (ip_header != NULL)
            {
                reset->ip.SrcAddr = ip_header->DstAddr;
                reset->ip.DstAddr = ip_header->SrcAddr;
                reset->tcp.SrcPort = tcp_header->DstPort;
                reset->tcp.DstPort = tcp_header->SrcPort;
                reset->tcp.SeqNum = 
                    (tcp_header->Ack? tcp_header->AckNum: 0);
                reset->tcp.AckNum =
                    (tcp_header->Syn?
                        htonl(ntohl(tcp_header->SeqNum) + 1):
                        htonl(ntohl(tcp_header->SeqNum) + payload_len));

                DivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET), 0);
                
                memcpy(&send_addr, &recv_addr, sizeof(send_addr));
                send_addr.Direction = !recv_addr.Direction;
                if (!DivertSend(handle, (PVOID)reset, sizeof(TCPPACKET),
                        &send_addr, NULL))
                {
                    fprintf(stderr, "warning: failed to send TCP reset (%d)\n",
                        GetLastError());
                }
            }

            if (ipv6_header != NULL)
            {
                memcpy(resetv6->ipv6.SrcAddr, ipv6_header->DstAddr,
                    sizeof(resetv6->ipv6.SrcAddr));
                memcpy(resetv6->ipv6.DstAddr, ipv6_header->SrcAddr,
                    sizeof(resetv6->ipv6.DstAddr));
                resetv6->tcp.SrcPort = tcp_header->DstPort;
                resetv6->tcp.DstPort = tcp_header->SrcPort;
                resetv6->tcp.SeqNum =
                    (tcp_header->Ack? tcp_header->AckNum: 0);
                resetv6->tcp.AckNum =
                    (tcp_header->Syn?
                        htonl(ntohl(tcp_header->SeqNum) + 1):
                        htonl(ntohl(tcp_header->SeqNum) + payload_len));

                DivertHelperCalcChecksums((PVOID)resetv6, sizeof(TCPV6PACKET),
                    0);
                
                memcpy(&send_addr, &recv_addr, sizeof(send_addr));
                send_addr.Direction = !recv_addr.Direction;
                if (!DivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET),
                        &send_addr, NULL))
                {
                    fprintf(stderr, "warning: failed to send TCP (IPV6) "
                        "reset (%d)\n", GetLastError());
                }
            }
        }
        if (udp_header != NULL)
        {
            printf("udp.SrcPort=%u udp.DstPort=%u ",
                ntohs(udp_header->SrcPort), ntohs(udp_header->DstPort));
        
            if (ip_header != NULL)
            {
                // NOTE: For some ICMP error messages, WFP does not seem to
                //       support INBOUND injection.  As a work-around, we
                //       always inject OUTBOUND.
                UINT icmp_length = ip_header->HdrLength*sizeof(UINT32) + 8;
                memcpy(dnr->data, ip_header, icmp_length);
                icmp_length += sizeof(ICMPPACKET);
                dnr->ip.Length = htons((UINT16)icmp_length);
                dnr->ip.SrcAddr = ip_header->DstAddr;
                dnr->ip.DstAddr = ip_header->SrcAddr;
                
                DivertHelperCalcChecksums((PVOID)dnr, icmp_length, 0);
                
                memcpy(&send_addr, &recv_addr, sizeof(send_addr));
                send_addr.Direction = DIVERT_DIRECTION_OUTBOUND;
                if (!DivertSend(handle, (PVOID)dnr, icmp_length, &send_addr,
                    NULL))
                {
                    fprintf(stderr, "warning: failed to send ICMP message "
                        "(%d)\n", GetLastError());
                }
            }
        
            if (ipv6_header != NULL)
            {
                UINT icmpv6_length = sizeof(DIVERT_IPV6HDR) +
                    sizeof(DIVERT_TCPHDR);
                memcpy(dnrv6->data, ipv6_header, icmpv6_length);
                icmpv6_length += sizeof(ICMPV6PACKET);
                memcpy(dnrv6->ipv6.SrcAddr, ipv6_header->DstAddr,
                    sizeof(dnrv6->ipv6.SrcAddr));
                memcpy(dnrv6->ipv6.DstAddr, ipv6_header->SrcAddr,
                    sizeof(dnrv6->ipv6.DstAddr));
                
                DivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length, 0);

                memcpy(&send_addr, &recv_addr, sizeof(send_addr));
                send_addr.Direction = DIVERT_DIRECTION_OUTBOUND;
                if (!DivertSend(handle, (PVOID)dnrv6, icmpv6_length,
                        &send_addr, NULL))
                {
                    fprintf(stderr, "warning: failed to send ICMPv6 message "
                        "(%d)\n", GetLastError());
                }
            }
        }
        putchar('\n');
    }
}