User Controls

Writing custom modules for Zmap in C.

  1. #1
    Sophie Pedophile Tech Support
    I want to find all DNS servers that respond to requests for zones for which they are none-authoritative, which i am pretty sure i can do with Zmap. Generally this is a an indicator they can be used in DNS Amplification. However i would really like to have a module that is capable of performing more tests, or sending packets in such a way that it gives me a more definitive answer on whether the DNS server in question would be suitable for Amplification or not.

    To do so however i will have to write a module that contains a payload that we can send to the DNS servers we are querying. Luckily Zmap allows us to do just that. Anyway...

    Each type of scan is implemented by developing and registering the necessary callbacks in a send_module_t struct:


    typedef struct probe_module {
    const char *name; // how scan is invoked on command-line
    size_t packet_length; // how long is probe packet (must be static size)

    const char *pcap_enhancement; // PCAP enhancement for collecting responses
    size_t pcap_snaplen; // maximum number of bytes for libpcap to capture

    uint8_t port_args; // set to 1 if ZMap requires a --target-port be
    // specified by the user

    probe_global_init_cb global_initialize; // called once at scanner initialization
    probe_thread_init_cb thread_initialize; // called once for each thread packet buffer
    probe_make_packet_cb make_packet; // called once per host to update packet
    probe_validate_packet_cb validate_packet; // called once per received packet,
    // return 0 if packet is invalid,
    // non-zero otherwise.

    probe_print_packet_cb print_packet; // called per packet if in dry-run mode
    probe_classify_packet_cb process_packet; // called by receiver to classify response
    probe_close_cb close; // called at scanner termination

    fielddef_t *fields // Definitions of the fields specific to this module
    int numfields // Number of fields

    } probe_module_t;



    int make_packet(
    void *packetbuf, // packet buffer
    ipaddr_n_t src_ip, // source IP in network-order
    ipaddr_n_t dst_ip, // destination IP in network-order
    uint32_t *validation, // validation string to place in probe
    int probe_num // if sending multiple probes per host,
    // this will be which probe number for this
    // host we are currently sending
    );


    I read that;

    The make_packet callback is called for each host that is scanned to allow the probe module to update host specific values and is provided with IP address values, an opaque validation string, and probe number. The probe module is responsible for placing as much of the verification string into the probe, in such a way that when a valid response is returned by a server, the probe module can verify that it is present. Apparently, for a TCP SYN scan, the tcp_synscan probe module can use the TCP source port and sequence number to store the validation string. Response packets (SYN+ACKs) will contain the expected values in the destination port and acknowledgement number.

    The documentation also told me that;

    Scan modules must also define pcap_enhancement, validate_packet, and process_packet. Only packets that match the PCAP enhancement will be considered by the scanner.

    Since i've done a little homework, i have also brought a captured a DNS request to see what it's supposed to look like.

    Raw request

    0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 ........ ......E.
    0010 00 3c 51 e3 40 00 40 11 ea cb 7f 00 00 01 7f 00 .<Q.@.@. ........
    0020 00 01 ec ed 00 35 00 28 fe 3b 24 1a 01 00 00 01 .....5.( .;$.....
    0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c .......w ww.googl
    0040 65 03 63 6f 6d 00 00 01 00 01


    Here is the 'expert info' as Wireshark would call it.


    Domain Name System (query)
    [Response In: 1852]
    Transaction ID: 0x241a
    Flags: 0x0100 (Standard query)
    0... .... .... .... = Response: Message is a query
    .000 0... .... .... = Opcode: Standard query (0)
    .... ..0. .... .... = Truncated: Message is not truncated
    .... ...1 .... .... = Recursion desired: Do query recursively
    .... .... .0.. .... = Z: reserved (0)
    .... .... ...0 .... = Non-authenticated data OK: Non-authenticated data is unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
    www.google.com: type A, class IN
    Name: www.google.com
    Type: A (Host address)
    Class: IN (0x0001)


    Response raw:

    0000 00 00 00 00 00 00 00 00 00 00 00 00 08 00 45 00 ........ ......E.
    0010 00 7a 00 00 40 00 40 11 3c 71 7f 00 00 01 7f 00 .z..@.@. <q......
    0020 00 01 00 35 ec ed 00 66 fe 79 24 1a 81 80 00 01 ...5...f .y$.....
    0030 00 03 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c .......w ww.googl
    0040 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 05 00 01 e.com... ........
    0050 00 05 28 39 00 12 03 77 77 77 01 6c 06 67 6f 6f ..(9...w ww.l.goo
    0060 67 6c 65 03 63 6f 6d 00 c0 2c 00 01 00 01 00 00 gle.com. .,......
    0070 00 e3 00 04 42 f9 59 63 c0 2c 00 01 00 01 00 00 ....B.Yc .,......
    0080 00 e3 00 04 42 f9 59 68


    And again the breakdown.

    Domain Name System (response)
    [Request In: 1851]
    [Time: 0.000125000 seconds]
    Transaction ID: 0x241a
    Flags: 0x8180 (Standard query response, No error)
    1... .... .... .... = Response: Message is a response
    .000 0... .... .... = Opcode: Standard query (0)
    .... .0.. .... .... = Authoritative: Server is not an authority for domain
    .... ..0. .... .... = Truncated: Message is not truncated
    .... ...1 .... .... = Recursion desired: Do query recursively
    .... .... 1... .... = Recursion available: Server can do recursive queries
    .... .... .0.. .... = Z: reserved (0)
    .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
    .... .... .... 0000 = Reply code: No error (0)
    Questions: 1
    Answer RRs: 3
    Authority RRs: 0
    Additional RRs: 0
    Queries
    www.google.com: type A, class IN
    Name: www.google.com
    Type: A (Host address)
    Class: IN (0x0001)
    Answers
    www.google.com: type CNAME, class IN, cname www.l.google.com
    Name: www.google.com
    Type: CNAME (Canonical name for an alias)
    Class: IN (0x0001)
    Time to live: 3 days, 21 hours, 52 minutes, 57 seconds
    Data length: 18
    Primary name: www.l.google.com
    www.l.google.com: type A, class IN, addr 66.249.89.99
    Name: www.l.google.com
    Type: A (Host address)
    Class: IN (0x0001)
    Time to live: 3 minutes, 47 seconds
    Data length: 4
    Addr: 66.249.89.99
    www.l.google.com: type A, class IN, addr 66.249.89.104
    Name: www.l.google.com
    Type: A (Host address)
    Class: IN (0x0001)
    Time to live: 3 minutes, 47 seconds
    Data length: 4
    Addr: 66.249.89.104


    I'm reading this to acquaint myself better with DNS generally.

    https://tools.ietf.org/html/rfc1035

    Also, here is the standard module that Zmap uses for DNS.

    https://github.com/zmap/zmap/blob/master/src/probe_modules/module_dns.c

    This is just for learning C better and a bit more about how DNS servers work generally. If i get a list of suitable DNS servers out of it in return all the better. Anyway, thoughts? Ideas? Cheeky commentary?
Jump to Top