#ifndef PROTO_BANNER1_H #define PROTO_BANNER1_H #include #include #include "masscan-app.h" #include "proto-banout.h" #include "proto-x509.h" #include "proto-spnego.h" struct stack_handle_t; struct Banner1; struct StreamState; typedef void (*BannerParser)( const struct Banner1 *banner1, void *banner1_private, struct StreamState *stream_state, const unsigned char *px, size_t length, struct BannerOutput *banout, struct stack_handle_t *socket); struct Banner1 { struct lua_State *L; struct SMACK *smack; struct SMACK *http_fields; struct SMACK *html_fields; struct SMACK *memcached_responses; struct SMACK *memcached_stats; unsigned is_capture_html:1; unsigned is_capture_cert:1; unsigned is_capture_servername:1; unsigned is_capture_heartbleed:1; unsigned is_capture_ticketbleed:1; unsigned is_heartbleed:1; unsigned is_ticketbleed:1; unsigned is_poodle_sslv3:1; struct { const struct ProtocolParserStream *tcp[65536]; } payloads; BannerParser parser[PROTO_end_of_list]; }; struct BannerBase64 { unsigned state:2; unsigned temp:24; }; struct SSL_SERVER_HELLO { unsigned state; unsigned remaining; unsigned timestamp; unsigned short cipher_suite; unsigned short ext_tag; unsigned short ext_remaining; unsigned char compression_method; unsigned char version_major; unsigned char version_minor; }; struct SSL_SERVER_CERT { unsigned state; unsigned remaining; struct { unsigned remaining; } sub; struct CertDecode x509; }; struct SSL_SERVER_ALERT { unsigned char level; unsigned char description; }; struct SSLRECORD { unsigned char type; unsigned char version_major; unsigned char version_minor; struct { unsigned state; unsigned char type; unsigned remaining; } handshake; union { struct { /* all these structs should start with state */ unsigned state; } all; struct SSL_SERVER_HELLO server_hello; struct SSL_SERVER_CERT server_cert; struct SSL_SERVER_ALERT server_alert; } x; }; struct PIXEL_FORMAT { unsigned short red_max; unsigned short green_max; unsigned short blue_max; unsigned char red_shift; unsigned char green_shift; unsigned char blue_shift; unsigned char bits_per_pixel; unsigned char depth; unsigned big_endian_flag:1; unsigned true_colour_flag:1; }; struct VNCSTUFF { unsigned sectype; unsigned char version; unsigned char len; unsigned short width; unsigned short height; struct PIXEL_FORMAT pixel; }; struct FTPSTUFF { unsigned code; unsigned is_last:1; }; struct MCSTUFF { char * banmem; size_t totalLen; size_t imgstart; size_t imgend; int brackcount; }; struct SMTPSTUFF { unsigned code; unsigned is_last:1; }; struct POP3STUFF { unsigned code; unsigned is_last:1; }; struct MEMCACHEDSTUFF { unsigned match; }; struct Smb72_Negotiate { uint16_t DialectIndex; uint16_t SecurityMode; uint64_t SystemTime; uint32_t SessionKey; uint32_t Capabilities; uint16_t ServerTimeZone; uint8_t ChallengeLength; uint8_t ChallengeOffset; }; struct Smb73_Setup { uint16_t BlobLength; uint16_t BlobOffset; }; struct SMBSTUFF { unsigned nbt_state; unsigned char nbt_type; unsigned char nbt_flags; unsigned is_printed_ver:1; unsigned is_printed_guid:1; unsigned is_printed_time:1; unsigned is_printed_boottime:1; unsigned nbt_length; unsigned nbt_err; union { struct { unsigned char command; unsigned status; unsigned char flags1; unsigned short flags2; unsigned pid; unsigned char signature[8]; unsigned short tid; unsigned short uid; unsigned short mid; unsigned short param_length; unsigned short param_offset; unsigned short byte_count; unsigned short byte_offset; unsigned short byte_state; unsigned short unicode_char; } smb1; struct { unsigned seqno; unsigned short header_length; unsigned short offset; unsigned short state; unsigned short opcode; unsigned short struct_length; unsigned is_dynamic:1; unsigned char flags; unsigned ntstatus; unsigned number; unsigned short blob_offset; unsigned short blob_length; } smb2; } hdr; union { struct Smb72_Negotiate negotiate; struct Smb73_Setup setup; struct { uint64_t current_time; uint64_t boot_time; } negotiate2; } parms; struct SpnegoDecode spnego; }; struct RDPSTUFF { unsigned short tpkt_length; struct { unsigned state; unsigned short dstref; unsigned short srcref; unsigned char len; unsigned char type; unsigned char flags; } cotp; struct { unsigned state; unsigned result; unsigned char type; unsigned char flags; unsigned char len; } cc; }; struct SSHSTUFF{ size_t packet_length; }; struct StreamState { unsigned state; unsigned remaining; unsigned short port; unsigned short app_proto; unsigned is_sent_sslhello:1; struct BannerBase64 base64; union { struct SSLRECORD ssl; struct VNCSTUFF vnc; struct FTPSTUFF ftp; struct SMTPSTUFF smtp; struct POP3STUFF pop3; struct MEMCACHEDSTUFF memcached; struct SMBSTUFF smb; struct RDPSTUFF rdp; struct MCSTUFF mc; struct SSHSTUFF ssh; } sub; }; enum StreamFlags { SF__none = 0, SF__close = 0x01, /* send FIN after the static Hello is sent*/ SF__nowait_hello = 0x02, /* send our hello immediately, don't wait for their hello */ }; /** * A registration structure for various TCP stream protocols * like HTTP, SSL, and SSH */ struct ProtocolParserStream { const char *name; unsigned port; const void *hello; size_t hello_length; enum StreamFlags flags; int (*selftest)(void); void *(*init)(struct Banner1 *b); void (*parse)( const struct Banner1 *banner1, void *banner1_private, struct StreamState *stream_state, const unsigned char *px, size_t length, struct BannerOutput *banout, struct stack_handle_t *socket); void (*cleanup)(struct StreamState *stream_state); void (*transmit_hello)(const struct Banner1 *banner1, struct stack_handle_t *socket); /* When multiple items are registered for a port. When one * connection is closed, the next will be opened.*/ struct ProtocolParserStream *next; /*NOTE: the 'next' parameter should be the last one in this structure, * because we statically initialize the rest of the members at compile * time, and then use this last parameter to link up structures * at runtime */ }; /** * Patterns that match the data from the start of a TCP connection. * This will hint at what protocol that connection might be. */ struct Patterns { /** A string like "SSH-" or "220 " that matches a banner */ const char *pattern; /** The length of that string, since it may be binary containing * nul characters */ unsigned pattern_length; /** An integer arbitrarily assigned to this pattern, which should * probably match the protocol ID that we are looking for */ unsigned id; /** * Whether this string matches only at the beginning ('anchored') * or anywhere in the input. Virtually all the patterns are anchored. */ unsigned is_anchored; /** * Some extra flags for the pattern matcher for a few of the patterns. */ unsigned extra; }; struct Banner1 * banner1_create(void); void banner1_destroy(struct Banner1 *b); unsigned banner1_parse( const struct Banner1 *banner1, struct StreamState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout, struct stack_handle_t *socket); /** * Test the banner protocol-parsing system by reading * in a capture file */ void banner1_test(const char *filename); int banner1_selftest(void); #endif