comparison fuzz/fuzz-sshpacketmutator.c @ 1771:af9ed0815818

Use SSH packet mutator for preauth too Get rid of separate client mutator. Have 0.1% chance of llvm random mutation Add comments
author Matt Johnston <matt@ucc.asn.au>
date Thu, 29 Oct 2020 22:41:37 +0800
parents 3e1e1f82eba6
children 833bf9947603
comparison
equal deleted inserted replaced
1770:66b29b054896 1771:af9ed0815818
1 /* A mutator/crossover for SSH protocol streams.
2 Attempts to mutate each SSH packet individually, keeping
3 lengths intact.
4 It will prepend a SSH-2.0-dbfuzz\r\n version string.
5
6 Linking this file to a binary will make libfuzzer pick up the custom mutator.
7
8 Care is taken to avoid memory allocation which would otherwise
9 slow exec/s substantially */
10
1 #include "fuzz.h" 11 #include "fuzz.h"
2 #include "dbutil.h" 12 #include "dbutil.h"
3 13
4 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize); 14 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
15
16 static const char* FIXED_VERSION = "SSH-2.0-dbfuzz\r\n";
17 static const size_t MAX_FUZZ_PACKETS = 500;
18 /* XXX This might need tuning */
19 static const size_t MAX_OUT_SIZE = 50000;
20
21 /* Splits packets from an input stream buffer "inp".
22 The initial SSH version identifier is discarded.
23 If packets are not recognised it will increment until an uint32 of valid
24 packet length is found. */
5 25
6 /* out_packets an array of num_out_packets*buffer, each of size RECV_MAX_PACKET_LEN */ 26 /* out_packets an array of num_out_packets*buffer, each of size RECV_MAX_PACKET_LEN */
7 static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) { 27 static void fuzz_get_packets(buffer *inp, buffer **out_packets, unsigned int *num_out_packets) {
8 /* Skip any existing banner. Format is 28 /* Skip any existing banner. Format is
9 SSH-protoversion-softwareversion SP comments CR LF 29 SSH-protoversion-softwareversion SP comments CR LF
50 buf_putbytes(new_packet, buf_getptr(inp, packet_len), packet_len); 70 buf_putbytes(new_packet, buf_getptr(inp, packet_len), packet_len);
51 buf_incrpos(inp, packet_len); 71 buf_incrpos(inp, packet_len);
52 } 72 }
53 } 73 }
54 74
55 /* Mutate in-place */ 75 /* Mutate a packet buffer in-place */
56 void buf_llvm_mutate(buffer *buf) { 76 static void buf_llvm_mutate(buffer *buf) {
57 /* Position it after packet_length and padding_length */ 77 /* Position it after packet_length and padding_length */
58 const unsigned int offset = 5; 78 const unsigned int offset = 5;
59 if (buf->len < offset) { 79 if (buf->len < offset) {
60 return; 80 return;
61 } 81 }
67 buf_putint(buf, new_size); 87 buf_putint(buf, new_size);
68 buf_setlen(buf, offset + new_size); 88 buf_setlen(buf, offset + new_size);
69 } 89 }
70 90
71 91
72 static const char* FIXED_VERSION = "SSH-2.0-dbfuzz\r\n";
73 static const size_t MAX_FUZZ_PACKETS = 500;
74 /* XXX This might need tuning */
75 static const size_t MAX_OUT_SIZE = 50000;
76
77 /* Persistent buffers to avoid constant allocations */ 92 /* Persistent buffers to avoid constant allocations */
78 static buffer *oup; 93 static buffer *oup;
79 static buffer *alloc_packetA; 94 static buffer *alloc_packetA;
80 static buffer *alloc_packetB; 95 static buffer *alloc_packetB;
81 buffer* packets1[MAX_FUZZ_PACKETS]; 96 buffer* packets1[MAX_FUZZ_PACKETS];
109 unsigned int i; 124 unsigned int i;
110 unsigned short randstate[3] = {0,0,0}; 125 unsigned short randstate[3] = {0,0,0};
111 memcpy(randstate, &Seed, sizeof(Seed)); 126 memcpy(randstate, &Seed, sizeof(Seed));
112 127
113 // printhex("mutator input", Data, Size); 128 // printhex("mutator input", Data, Size);
114 #if 0 129
115 /* 1% chance straight llvm mutate */ 130 /* 0.1% chance straight llvm mutate */
116 if (nrand48(randstate) % 100 == 0) { 131 if (nrand48(randstate) % 1000 == 0) {
117 return LLVMFuzzerMutate(Data, Size, MaxSize); 132 return LLVMFuzzerMutate(Data, Size, MaxSize);
118 } 133 }
119 #endif
120 134
121 buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0}; 135 buffer inp_buf = {.data = Data, .size = Size, .len = Size, .pos = 0};
122 buffer *inp = &inp_buf; 136 buffer *inp = &inp_buf;
123 137
124 /* Parse packets */ 138 /* Parse packets */