Skip to content

Commit e0c809e

Browse files
GabrielGannefklassen
authored andcommitted
fuzzing ignores layers 2, 3, and 4 (appneta#341)
For example, this means : - skipping TCP SYN packets - no ethertype, ip addresses, not port number will be modified Signed-off-by: Gabriel Ganne <[email protected]>
1 parent 59cd724 commit e0c809e

File tree

1 file changed

+100
-25
lines changed

1 file changed

+100
-25
lines changed

src/tcpedit/fuzzing.c

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ fuzz_get_sgt_size(uint32_t r, uint32_t caplen)
3737
}
3838

3939
static inline int
40-
fuzz_reduce_packet_size(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
41-
u_char **pktdata, COUNTER new_len)
40+
fuzz_reduce_packet_size(tcpedit_t * tcpedit, struct pcap_pkthdr * pkthdr,
41+
COUNTER new_len)
4242
{
4343
assert(new_len <= pkthdr->len);
4444

@@ -60,25 +60,100 @@ fuzz_reduce_packet_size(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
6060
return 1;
6161
}
6262

63+
64+
static inline int
65+
fuzz_get_datalen(tcpedit_t * tcpedit, struct pcap_pkthdr * pkthdr,
66+
u_char ** pktdata)
67+
{
68+
int datalen;
69+
uint8_t l4proto;
70+
u_char * l3data, * l4data;
71+
72+
datalen = pkthdr->len;
73+
74+
l3data = tcpedit->dlt_ctx->encoder->plugin_get_layer3(tcpedit->dlt_ctx,
75+
*pktdata, pkthdr->caplen);
76+
if (l3data == NULL) {
77+
return -1;
78+
}
79+
datalen -= l3data - *pktdata;
80+
81+
if (datalen <= 0) {
82+
return -1;
83+
}
84+
85+
/* switch on layer 2 */
86+
switch (ntohs(tcpedit->dlt_ctx->proto))
87+
{
88+
/* TODO: ntohs on constants could be done at compile time */
89+
case (ETHERTYPE_IP):
90+
{
91+
l4data = get_layer4_v4((ipv4_hdr_t*) l3data, datalen);
92+
if (l4data == NULL) {
93+
return -1;
94+
}
95+
l4proto = ((ipv4_hdr_t *) l3data)->ip_p;
96+
break;
97+
}
98+
case (ETHERTYPE_IP6):
99+
{
100+
l4data = get_layer4_v6((ipv6_hdr_t*) l3data, datalen);
101+
if (l4data == NULL) {
102+
return -1;
103+
}
104+
l4proto = ((ipv6_hdr_t *) l3data)->ip_nh;
105+
break;
106+
}
107+
default:
108+
/* apply fuzzing on unknown packet types */
109+
return datalen;
110+
}
111+
112+
datalen -= (l4data - l3data);
113+
114+
/* switch on layer 3 */
115+
switch (l4proto) {
116+
case IPPROTO_TCP:
117+
datalen -= sizeof(tcp_hdr_t);
118+
break;
119+
case IPPROTO_UDP:
120+
datalen -= sizeof(udp_hdr_t);
121+
break;
122+
}
123+
124+
return datalen;
125+
}
126+
63127
int
64-
fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
65-
u_char **pktdata)
128+
fuzzing(tcpedit_t * tcpedit, struct pcap_pkthdr * pkthdr,
129+
u_char ** _pktdata)
66130
{
67131
int packet_changed;
68132
uint32_t r;
69133
unsigned int * len;
134+
int datalen;
135+
u_char * pktdata;
70136

71137
assert(tcpedit != NULL);
72138
assert(pkthdr != NULL);
73-
assert(pktdata != NULL);
139+
assert(_pktdata != NULL);
74140

75141
if (fuzz_running == 0) {
76142
return 0;
77143
}
78144

79145
len = &(pkthdr->caplen);
80146
packet_changed = 0;
147+
148+
/* skip packets without payload */
149+
datalen = fuzz_get_datalen(tcpedit, pkthdr, _pktdata);
150+
if (datalen <= 0 || datalen >= *len) {
151+
return 0;
152+
}
153+
154+
r = rand();
81155
r = tcpr_random(&fuzz_seed);
156+
pktdata = *_pktdata + (*len - datalen);
82157

83158
/* TODO sktip ip/tcp/udp headers */
84159

@@ -93,7 +168,7 @@ fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
93168
case FUZZING_DROP_PACKET:
94169
{
95170
/* simulate droping the packet */
96-
packet_changed = fuzz_reduce_packet_size(tcpedit, pkthdr, pktdata, 0);
171+
packet_changed = fuzz_reduce_packet_size(tcpedit, pkthdr, 0);
97172
if (packet_changed < 0) {
98173
/* could not change packet size, so packet left unchanged */
99174
return 0;
@@ -104,7 +179,7 @@ fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
104179
{
105180
/* reduce packet size */
106181
uint32_t new_len = (r % ((*len) - 1)) + 1;
107-
packet_changed = fuzz_reduce_packet_size(tcpedit, pkthdr, pktdata, new_len);
182+
packet_changed = fuzz_reduce_packet_size(tcpedit, pkthdr, new_len);
108183
if (packet_changed < 0) {
109184
/* could not change packet size, so packet left unchanged */
110185
return 0;
@@ -115,72 +190,72 @@ fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
115190
case FUZZING_CHANGE_START_ZERO:
116191
{
117192
/* fuzz random-size segment at the begining of the packet with 0x00 */
118-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
119-
memset((*pktdata), 0x00, sgt_size);
193+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
194+
memset(pktdata, 0x00, sgt_size);
120195
packet_changed = 1;
121196
}
122197
break;
123198
case FUZZING_CHANGE_START_RANDOM:
124199
{
125200
/* fuzz random-size segment at the begining of the packet with random Bytes */
126201
int i;
127-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
202+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
128203
for (i = 0; i < sgt_size; i++) {
129-
(*pktdata)[i] = (*pktdata)[i] ^ (r >> 4);
204+
pktdata[i] = pktdata[i] ^ (r >> 4);
130205
}
131206
packet_changed = 1;
132207
}
133208
break;
134209
case FUZZING_CHANGE_START_FF:
135210
{
136211
/* fuzz random-size segment at the begining of the packet with 0xff */
137-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
138-
memset((*pktdata), 0xff, sgt_size);
212+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
213+
memset(pktdata, 0xff, sgt_size);
139214
packet_changed = 1;
140215
}
141216
break;
142217
case FUZZING_CHANGE_MID_ZERO:
143218
{
144219
/* fuzz random-size segment inside the packet with 0x00 */
145220
uint32_t offset = ((r >> 16) % ((*len) - 1)) + 1;
146-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len) - offset);
147-
memset((*pktdata) + offset, 0x00, sgt_size);
221+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen - offset);
222+
memset(pktdata + offset, 0x00, sgt_size);
148223
packet_changed = 1;
149224
}
150225
break;
151226
case FUZZING_CHANGE_MID_FF:
152227
{
153228
/* fuzz random-size segment inside the packet with 0xff */
154229
uint32_t offset = ((r >> 16) % ((*len) - 1)) + 1;
155-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len) - offset);
156-
memset((*pktdata) + offset, 0xff, sgt_size);
230+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen - offset);
231+
memset(pktdata + offset, 0xff, sgt_size);
157232
packet_changed = 1;
158233
}
159234
break;
160235
case FUZZING_CHANGE_END_ZERO:
161236
{
162237
/* fuzz random-sized segment at the end of the packet with 0x00 */
163-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
164-
memset((*pktdata) + (*len) - sgt_size, 0x00, sgt_size);
238+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
239+
memset(pktdata + (*len) - sgt_size, 0x00, sgt_size);
165240
packet_changed = 1;
166241
}
167242
break;
168243
case FUZZING_CHANGE_END_RANDOM:
169244
{
170245
/* fuzz random-sized segment at the end of the packet with random Bytes */
171246
int i;
172-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
247+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
173248
for (i = ((*len) - sgt_size); i < (*len); i++) {
174-
(*pktdata)[i] = (*pktdata)[i] ^ (r >> 4);
249+
pktdata[i] = pktdata[i] ^ (r >> 4);
175250
}
176251
packet_changed = 1;
177252
}
178253
break;
179254
case FUZZING_CHANGE_END_FF:
180255
{
181256
/* fuzz random-sized segment at the end of the packet with 0xff00 */
182-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len));
183-
memset((*pktdata) + (*len) - sgt_size, 0xff, sgt_size);
257+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen);
258+
memset(pktdata + (*len) - sgt_size, 0xff, sgt_size);
184259
packet_changed = 1;
185260
}
186261
break;
@@ -191,9 +266,9 @@ fuzzing(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
191266
/* fuzz random-size segment inside the packet with random Bytes */
192267
int i;
193268
uint32_t offset = ((r >> 16) % ((*len) - 1)) + 1;
194-
uint32_t sgt_size = fuzz_get_sgt_size(r, (*len) - offset);
269+
uint32_t sgt_size = fuzz_get_sgt_size(r, datalen - offset);
195270
for (i = offset; i < offset + sgt_size; i++) {
196-
(*pktdata)[i] = (*pktdata)[i] ^ (r >> 4);
271+
pktdata[i] = pktdata[i] ^ (r >> 4);
197272
}
198273
packet_changed = 1;
199274
}

0 commit comments

Comments
 (0)