Commit 3c58c8c0 authored by Robert David Graham's avatar Robert David Graham
Browse files

udp scan

parent 00e3471c
Loading
Loading
Loading
Loading
+129 −20
Original line number Diff line number Diff line
/*
    reads in the "nmap-payloads" file containing UDP payloads
 */
#include "templ-payloads.h"
#include "ranges.h"
#include <stdio.h>
@@ -12,6 +15,13 @@ struct Payload {
    unsigned xsum;
    unsigned char buf[1];
};
struct Payload2 {
    unsigned port;
    unsigned source_port;
    unsigned length;
    unsigned xsum;
    char *buf;
};

struct NmapPayloads {
    unsigned count;
@@ -19,6 +29,68 @@ struct NmapPayloads {
    struct Payload **list;
};

struct Payload2 hard_coded_payloads[] = {
    {161, 65536, 56, 0, 
        "\x30" "\x37"
        "\x02\x01\x00"                    /* version */
        "\x04\x06" "public"               /* community = public */
        "\xa0" "\x2a"                     /* type = GET */
        "\x02\x04\x00\x00\x00\x00"      /* transaction id = ???? */
        "\x02\x01\x00"                  /* error = 0 */
        "\x02\x01\x00"                  /* error index = 0 */
        "\x30\x1c"
        "\x30\x0c"
        "\x06\x08\x2b\x06\x01\x02\x01\x01\x01\x00" /*sysName*/
        "\x05\x00"
        "\x30\x0c"
        "\x06\x08\x2b\x06\x01\x02\x01\x01\x05\x00" /*sysDesc*/
        "\x05\x00"},
    {53, 65536, 31, 0,         "\x00\x00" /* transaction ID */
        "\x01\x00" /* standard query */
        "\x00\x01\x00\x00\x00\x00\x00\x00" /* 1 query */
        "\x03" "www" "\x05" "yahoo" "\x03" "com" "\x00"
        "\x00\x01\x00\x01" /* A IN */
    },
    {5060, 65536, -1, 0,
        "OPTIONS sip:carol@chicago.com SIP/2.0\r\n"
        "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877\r\n"
        "Max-Forwards: 70\r\n"
        "To: <sip:carol@chicago.com>\r\n"
        "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
        "Call-ID: a84b4c76e66710\r\n"
        "CSeq: 63104 OPTIONS\r\n"
        "Contact: <sip:alice@pc33.atlanta.com>\r\n"
        "Accept: application/sdp\r\n"
        "Content-Length: 0\r\n"
    },

    {0,0,0,0,0}
};


/***************************************************************************
 * Calculate the partial checkum of the payload. This allows us to simply
 * add this to the checksum when transmitting instead of recacluating
 * everything.
 ***************************************************************************/
static unsigned
partial_checksum(const unsigned char *px, size_t icmp_length)
{
    uint64_t xsum = 0;
    unsigned i;
    
    for (i=0; i<icmp_length; i += 2) {
        xsum += px[i]<<8 | px[i + 1];
    }
    
    xsum -= (icmp_length & 1) * px[i - 1]; /* yea I know going off end of packet is bad so sue me */
    xsum = (xsum & 0xFFFF) + (xsum >> 16);
    xsum = (xsum & 0xFFFF) + (xsum >> 16);
    xsum = (xsum & 0xFFFF) + (xsum >> 16);
    
    return (unsigned)xsum;
}

/***************************************************************************
 * If we have the port, return the payload
 ***************************************************************************/
@@ -29,7 +101,7 @@ payloads_lookup(
        const unsigned char **px, 
        unsigned *length, 
        unsigned *source_port, 
        unsigned *xsum)
        uint64_t *xsum)
{
    unsigned i;
    if (payloads == 0)
@@ -49,16 +121,6 @@ payloads_lookup(
    return 0;
}

/***************************************************************************
 ***************************************************************************/
struct NmapPayloads *
payloads_create()
{
    struct NmapPayloads *payloads;
    payloads = (struct NmapPayloads *)malloc(sizeof(*payloads));
    memset(payloads, 0, sizeof(*payloads));
    return payloads;
}

/***************************************************************************
 ***************************************************************************/
@@ -94,7 +156,9 @@ payloads_trim(struct NmapPayloads *payloads, const struct RangeList *ports)

        if (!rangelist_is_contains(ports, p->port + 65536)) {
            free(p);
            memmove(payloads->list + i - 1, payloads->list + i, (payloads->count - i) * sizeof(payloads->list[0]));
            memmove(payloads->list + i - 1,
                    payloads->list + i, 
                    (payloads->count - i) * sizeof(payloads->list[0]));
            payloads->count--;
        }
    }
@@ -161,7 +225,8 @@ hexval(int c)
/***************************************************************************
 ***************************************************************************/
static const char *
parse_c_string(unsigned char *buf, size_t *buf_length, size_t buf_max, const char *line)
parse_c_string(unsigned char *buf, size_t *buf_length, 
               size_t buf_max, const char *line)
{
    size_t offset;

@@ -274,7 +339,9 @@ get_next_line(FILE *fp, unsigned *line_number, char *line, size_t sizeof_line)
/***************************************************************************
 ***************************************************************************/
static void
payload_add(struct NmapPayloads *payloads, const unsigned char *buf, size_t length, struct RangeList *ports, unsigned source_port)
payload_add(struct NmapPayloads *payloads,
            const unsigned char *buf, size_t length, 
            struct RangeList *ports, unsigned source_port)
{
    struct Payload *p;
    uint64_t port_count = rangelist_count(ports);
@@ -299,19 +366,24 @@ payload_add(struct NmapPayloads *payloads, const unsigned char *buf, size_t leng
        p->source_port = source_port;
        p->length = (unsigned)length;
        memcpy(p->buf, buf, length);
        p->xsum = partial_checksum(buf, length);

        /* insert in sorted order */
        {
            unsigned j;

            for (j=0; j<payloads->count; j++) {
                if (p->port < payloads->list[j]->port)
                if (p->port <= payloads->list[j]->port)
                    break;
            }
            if (j < payloads->count)
            if (j < payloads->count) {
                if (p->port == payloads->list[j]->port)
                    free(payloads->list[j]);
                else
                memmove(    payloads->list + j + 1,
                            payloads->list + j, 
                            (payloads->count-j) * sizeof(payloads->list[0]));
            }
            payloads->list[j] = p;

            payloads->count++;
@@ -323,7 +395,8 @@ payload_add(struct NmapPayloads *payloads, const unsigned char *buf, size_t leng
/***************************************************************************
 ***************************************************************************/
void
payloads_read_file(FILE *fp, const char *filename, struct NmapPayloads *payloads)
payloads_read_file(FILE *fp, const char *filename, 
                   struct NmapPayloads *payloads)
{
    char line[16384];
    unsigned line_number = 0;
@@ -378,7 +451,8 @@ payloads_read_file(FILE *fp, const char *filename, struct NmapPayloads *payloads
            memmove(line, line+6, strlen(line+5));
            trim(line);
            if (!isdigit(line[0])) {
                fprintf(stderr, "%s:%u: expected source port\n", filename, line_number);
                fprintf(stderr, "%s:%u: expected source port\n", 
                        filename, line_number);
                goto end;
            }
            source_port = strtoul(line, 0, 0);
@@ -423,10 +497,45 @@ end:
    fclose(fp);
}



/***************************************************************************
 ***************************************************************************/
struct NmapPayloads *
payloads_create()
{
    unsigned i;
    struct NmapPayloads *payloads;
    payloads = (struct NmapPayloads *)malloc(sizeof(*payloads));
    memset(payloads, 0, sizeof(*payloads));
    
    for (i=0; hard_coded_payloads[i].length; i++) {
        struct Range range;
        struct RangeList list;
        unsigned length;
        
        /* Kludge: create a pseudo-rangelist to hold the one port */
        list.list = &range;
        list.count = 1;
        range.begin = hard_coded_payloads[i].port;
        range.end = range.begin;
        
        length = hard_coded_payloads[i].length;
        if (length == -1)
            length = strlen(hard_coded_payloads[i].buf);
        
        /* Add this to our real payloads. This will get overwritten
         * if the user adds their own with the same port */
        payload_add(payloads,
                    (const unsigned char*)hard_coded_payloads[i].buf,
                    length,
                    &list,
                    hard_coded_payloads[i].source_port);
    }
    return payloads;
}


/****************************************************************************
 ****************************************************************************/
int
payloads_selftest()
{
+8 −1
Original line number Diff line number Diff line
#ifndef TEMPL_PAYLOADS_H
#define TEMPL_PAYLOADS_H
#include <stdio.h>
#include <stdint.h>
struct RangeList;

int payloads_selftest();
@@ -22,7 +23,13 @@ void
payloads_trim(struct NmapPayloads *payloadsd, const struct RangeList *ports);

int
payloads_lookup(const struct NmapPayloads *payloads, unsigned port, const unsigned char **px, unsigned *length, unsigned *source_port, unsigned *xsum);
payloads_lookup(
                const struct NmapPayloads *payloads, 
                unsigned port, 
                const unsigned char **px, 
                unsigned *length, 
                unsigned *source_port, 
                uint64_t *xsum);



+18 −43
Original line number Diff line number Diff line
@@ -162,37 +162,6 @@ static unsigned char default_arp_template[] =
    "\0\0\0\0"      /* length */
;

/***************************************************************************
 ***************************************************************************/
struct UDP_Payloads {
    unsigned port;
    unsigned payload_length;
    unsigned seqno_offset;
    unsigned seqno_length;
    const unsigned char *payload;
} udp_payloads[] = {
    {53, 31, 0, 2, (const unsigned char*)
        "\x00\x00" /* transaction ID */
        "\x01\x00" /* standard query */
        "\x00\x01\x00\x00\x00\x00\x00\x00" /* 1 query */
        "\x03" "www" "\x05" "yahoo" "\x03" "com" "\x00"
        "\x00\x01\x00\x01" /* A IN */
    },
    {5060, 0, 0, 0, (const unsigned char*)
        "OPTIONS sip:carol@chicago.com SIP/2.0\r\n"
        "Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKhjhs8ass877\r\n"
        "Max-Forwards: 70\r\n"
        "To: <sip:carol@chicago.com>\r\n"
        "From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n"
        "Call-ID: a84b4c76e66710\r\n"
        "CSeq: 63104 OPTIONS\r\n"
        "Contact: <sip:alice@pc33.atlanta.com>\r\n"
        "Accept: application/sdp\r\n"
        "Content-Length: 0\r\n"
    },
        
    {0,0,0}    
};

/***************************************************************************
 ***************************************************************************/
@@ -536,31 +505,37 @@ template_set_target(
        break;
    case Proto_UDP:
        {
#if 0
            const unsigned char *px2;
            unsigned length2;
            unsigned length2 = 0;
            unsigned source_port2;
            if (payloads_lookup(tmpl->payloads, port, ) {
                xsum = tmpl->payloads[port]->checksum;
                memcpy(&px[tmpl->offset_app],
                       tmpl->payloads[port]->buf,
                       tmpl->payloads[port]->length);
            
            payloads_lookup(tmpl->payloads,
                                         port,
                                         &px2,
                                         &length2,
                                         &source_port2,
                                         &xsum);
            
            if (length2) {
                memcpy(&px[tmpl->offset_app], px2, length2);
            } else
                xsum = 0;
            tmpl->length = offset_tcp + length2 + 8;
            
            px[offset_tcp+ 2] = (unsigned char)(port >> 8);
            px[offset_tcp+ 3] = (unsigned char)(port & 0xFF);
            px[offset_tcp+ 4] = (unsigned char)((length2+8)>>8);
            px[offset_tcp+ 5] = (unsigned char)((length2+8)&0xFF);
            xsum += (uint64_t)tmpl->checksum_tcp
                    + (uint64_t)ip
                    + (uint64_t)port
                    + (uint64_t)seqno;
                    + (uint64_t)length2;
            xsum = (xsum >> 16) + (xsum & 0xFFFF);
            xsum = (xsum >> 16) + (xsum & 0xFFFF);
            xsum = (xsum >> 16) + (xsum & 0xFFFF);
            xsum = ~xsum;
            px[offset_tcp+4] = (unsigned char)(xsum >>  8);
            px[offset_tcp+5] = (unsigned char)(xsum >>  0);
#endif
            px[offset_tcp+6] = (unsigned char)(xsum >>  8);
            px[offset_tcp+7] = (unsigned char)(xsum >>  0);
        }
        break;
    case Proto_SCTP:
+7 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
		11A921F817DBCC7E00DDFD32 /* syn-cookie.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921CF17DBCC7E00DDFD32 /* syn-cookie.c */; };
		11A921F917DBCC7E00DDFD32 /* templ-pkt.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D117DBCC7E00DDFD32 /* templ-pkt.c */; };
		11A921FA17DBCC7E00DDFD32 /* xring.c in Sources */ = {isa = PBXBuildFile; fileRef = 11A921D317DBCC7E00DDFD32 /* xring.c */; };
		11B2DD9E17DE4DD8007FC363 /* templ-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
@@ -128,6 +129,8 @@
		11A921D317DBCC7E00DDFD32 /* xring.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xring.c; sourceTree = "<group>"; };
		11A921D417DBCC7E00DDFD32 /* xring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xring.h; sourceTree = "<group>"; };
		11A921FB17DBD17600DDFD32 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = "<group>"; };
		11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "templ-payloads.c"; sourceTree = "<group>"; };
		11B2DD9D17DE4DD8007FC363 /* templ-payloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "templ-payloads.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
@@ -161,6 +164,8 @@
		11A9219217DBCC7E00DDFD32 /* src */ = {
			isa = PBXGroup;
			children = (
				11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */,
				11B2DD9D17DE4DD8007FC363 /* templ-payloads.h */,
				11A9219317DBCC7E00DDFD32 /* event-timeout.c */,
				11A9219417DBCC7E00DDFD32 /* event-timeout.h */,
				11A9219517DBCC7E00DDFD32 /* logger.c */,
@@ -320,6 +325,7 @@
				11A921F817DBCC7E00DDFD32 /* syn-cookie.c in Sources */,
				11A921F917DBCC7E00DDFD32 /* templ-pkt.c in Sources */,
				11A921FA17DBCC7E00DDFD32 /* xring.c in Sources */,
				11B2DD9E17DE4DD8007FC363 /* templ-payloads.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
@@ -415,6 +421,7 @@
				11A9219117DBCB3200DDFD32 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};