1 /* 2 * $Id: fp.h,v 1.6 2003/05/16 08:58:45 skyper Exp $ 3 * 4 * Port State fingerprinting 5 */ 6 7 #ifndef __THCRUT_FP_H__ 8 #define __THCRUT_FP_H__ 1 9 #include <pcre.h> 10 #include <libnet.h> 11 12 /* 13 * We store category<->testnr value in one tuple. 14 * 15 * The introduction of categories was probably a design mistake. 16 * The idea was to have the tests sorted by category so that 17 * tests from one category can be performed before another category. 18 * It makes for example sense to run the banner-grapping tests 19 * before the open ports tests. 20 * 21 * We enumarate each tests so that we can look them up quickly when 22 * we have to make a decission if a test matches the results of a host. 23 * This would be easier with a linear number of tests and would 24 * not require a switchtable. 25 * 26 * To still have them sorted by category but linear numbered we should 27 * sort them after we read them in and do the enumeration after 28 * sorting (e.g. a for loop through all categories that copies the 29 * tests one by one). This would require to read in the file 30 * twice. First to load and sort the Testsuite itself, then to 31 * assign the testnumber to the single test-lines. 32 */ 33 #define FP_TEST_CAT_NR(cat, nr) (((nr & 0x1f) << 3) | (cat & 0x7)) 34 #define FP_TEST_NR(test) (((test)->testnr_cat & ~0x7) >> 3) 35 #define FP_TEST_CAT(test) ((test)->testnr_cat & 0x7) 36 struct _fp_test 37 { 38 pcre *pattern; 39 pcre_extra *hints; 40 unsigned char testnr_cat; /* Number and cat of this test */ 41 unsigned char flags; /* port state */ 42 char *varname; /* != NULL: It's a variable. use accuracy */ 43 /* value from variable-hash. */ 44 char accuracy; /* 1 for port, 2 for banner default */ 45 }; 46 47 #define FP_TEST_CLOSED 0x01 /* same for UDP/TCP */ 48 #define FP_TEST_OPEN 0x02 49 #define FP_TEST_REGEX 0x03 /* Must match string *str */ 50 51 /* 52 * One 'Fingerprint.*' line may be followed by many 53 * fingerprint test lines. Currently we allocate a new _fp for each 54 * of these lines even if they all point to the same Fingerprint.* line. 55 */ 56 struct _fp 57 { 58 struct _fp *next; 59 unsigned int class; 60 unsigned short ofs_string; 61 62 unsigned char n_tests; /* Number of checks for THIS fp */ 63 struct _fp_test fp_tests[0]; /* we love C */ 64 }; 65 66 67 /* 68 * Type W is the www test. 69 * W test occupies 4 bytes of memory 70 * S test occupies 4 bytes of memory 71 * T and U test 2 bytes 72 * 73 * We can even use static char here. We dont expect the user 74 * to have more than 128 different ports. 75 * 76 * Testsuite must carry the human representation of the tests. 77 */ 78 struct _fp_ts_test 79 { 80 unsigned short port; 81 }; 82 83 struct _fp_category 84 { 85 unsigned char n_tests; 86 size_t size; /* total size of bytes for results of this category */ 87 struct _fp_ts_test tests[32]; 88 }; 89 90 /* 91 * If you change this you also want to change the 2 bit's in 92 * struct _state_fp 93 */ 94 #define FP_CAT_TCP 0x00 95 #define FP_CAT_UDP 0x01 96 #define FP_CAT_BANNER 0x02 97 #define FP_CAT_WWW 0x03 98 #define FP_CAT_SNMP 0x04 99 #define FP_CAT_NVT 0x05 100 #define FP_CAT_SMB 0x06 /* RESERVED */ 101 #define FP_CAT_RES3 0x07 /* RESERVERD */ 102 #define FP_CAT_MAX 0x08 /* change state.h if exceeded */ 103 104 /* 105 * The performed tests are dynamic and read form the thcrut-os-fingerprints 106 * file. The access to the results of the tests is thus also 107 * dynamic. 108 */ 109 struct _fp_testsuite 110 { 111 int ofs_test_tcp; 112 int ofs_test_udp; 113 int ofs_test_banner; 114 int ofs_test_www; 115 int ofs_test_snmp; 116 int ofs_test_nvt; 117 unsigned char n_tests; /* Total number of different tests in fp-file */ 118 struct _fp_category cat[6]; 119 120 unsigned char *strings; 121 struct _fp *fps; /* Linked list of Fingerprints */ 122 }; 123 /* 124 * Required size for the results of the unique tests. 125 */ 126 #define FP_WTEST_SZ (64) /* HEAD / test output */ 127 #define FP_BTEST_SZ (128) /* Banner test */ 128 #define FP_STEST_SZ (128) /* SNMP test */ 129 #define FP_NTEST_SZ (128) /* NVT Terminal */ 130 131 struct _fp_nodequery 132 { 133 unsigned short trans_id; 134 unsigned short flags; 135 unsigned short questions; 136 unsigned short answers; 137 unsigned short auth_rrs; 138 unsigned short add_rrs; 139 }; 140 141 /* 142 * Right now all variables are stored lineary. 143 * We do not expect to have more than 50 144 */ 145 struct _fp_vararray 146 { 147 unsigned short ofs_varname; 148 char accuracy; 149 struct _fp_tests *tests; /* Linked list of Tests for this Varname */ 150 }; 151 152 /* 153 * Windows NODE query request (port 137). 154 * How dirty to use a static request but it never changes unless 155 * MS decides to change their protocol suite. This wont happen :> 156 */ 157 #define FP_NODEQUERY "\x20\x43\x4b\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x00\x00\x21\x00\x01" 158 #define FP_NODEQUERY_LEN (38) 159 160 /* 161 * WIndows DCE bind request. 162 */ 163 #define FP_DCEBIND "\x05\x00\x0b\x03\x10\x00\x00\x00\x48\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x10\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x00\x08\x83\xaf\xe1\x1f\x5d\xc9\x11\x91\xa4\x08\x00\x2b\x14\xa0\xfa\x03\x00\x00\x00\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00\x2b\x10\x48\x60\x02\x00\x00\x00" 164 /* It is actually enough to send 1 byte of payload to trigger windows for a 165 * reject packet. 166 */ 167 #define FP_DCEBIND_LEN (50) 168 169 /* 170 * SNMP 'public' GET-NEXT system.sysDescr.0 171 */ 172 #define FP_SNMP "\x30\x82\x00\x27\x02\x01\x00\x04\x06\x70\x75\x62\x6c\x69\x63\xa1\x1a\x02\x01\x01\x02\x01\x00\x02\x01\x00\x30\x0f\x30\x82\x00\x0b\x06\x07\x2b\x06\x01\x02\x01\x01\x00\x05\x00" 173 #define FP_SNMP_LEN (43) 174 175 #define FP_MAX_LEN (50) 176 177 union _classid 178 { 179 struct 180 { 181 #if LIBNET_BIG_ENDIAN 182 unsigned int genre:9; 183 unsigned int vendor:6; 184 unsigned int os:5; 185 /* 9 + 6 + 5 = 20 bits */ 186 unsigned int d:4; 187 unsigned int dd:4; 188 unsigned int ddd:4; 189 #elif LIBNET_LIL_ENDIAN 190 unsigned int ddd:4; 191 unsigned int dd:4; 192 unsigned int d:4; 193 /* 9 + 6 + 5 = 20 bits */ 194 unsigned int os:5; 195 unsigned int vendor:6; 196 unsigned int genre:9; 197 #endif 198 } st; 199 unsigned int id; 200 }; 201 202 203 int FP_TS_load(struct _fp_testsuite *fpts, const char *filename); 204 void FP_TS_dump(struct _fp_testsuite *fpts); 205 char *FP_class2str(char *dst, unsigned int val); 206 unsigned int FP_class2int(const char *input); 207 208 #endif /* !__THCRUT_FP_H__ */ 209