Mercurial > dropbear
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 */ |