suricata
fuzz_sigpcap.c
Go to the documentation of this file.
1 /**
2  * @file
3  * @author Philippe Antoine <contact@catenacyber.fr>
4  * fuzz target for AppLayerProtoDetectGetProto
5  */
6 
7 #include "suricata-common.h"
8 #include "source-pcap-file.h"
9 #include "detect-engine.h"
11 #include "util-reference-config.h"
12 #include "app-layer.h"
13 #include "tm-queuehandlers.h"
14 #include "util-cidr.h"
15 #include "util-proto-name.h"
16 #include "detect-engine-tag.h"
18 #include "host-bit.h"
19 #include "ippair-bit.h"
20 #include "app-layer-htp.h"
21 #include "detect-fast-pattern.h"
22 #include "util-unittest-helper.h"
23 #include "conf-yaml-loader.h"
24 #include "pkt-var.h"
25 
26 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
27 
28 
29 static int initialized = 0;
32 //FlowWorkerThreadData
33 void *fwd;
35 
36 const char configNoChecksum[] = "\
37 %YAML 1.1\n\
38 ---\n\
39 pcap-file:\n\
40 \n\
41  checksum-checks: no\n\
42 \n\
43 stream:\n\
44 \n\
45  checksum-validation: no\n\
46 outputs:\n\
47  - fast:\n\
48  enabled: yes\n\
49  filename: /dev/null\n\
50  - eve-log:\n\
51  enabled: yes\n\
52  filetype: regular\n\
53  filename: /dev/null\n\
54  xff:\n\
55  enabled: yes\n\
56  mode: extra-data\n\
57  deployment: reverse\n\
58  header: X-Forwarded-For\n\
59  types:\n\
60  - alert:\n\
61  payload: yes\n\
62  payload-printable: yes\n\
63  packet: yes\n\
64  metadata: yes\n\
65  http-body: yes\n\
66  http-body-printable: yes\n\
67  tagged-packets: yes\n\
68  - anomaly:\n\
69  enabled: yes\n\
70  types:\n\
71  decode: yes\n\
72  stream: yes\n\
73  applayer: yes\n\
74  packethdr: yes\n\
75  - http:\n\
76  extended: yes\n\
77  dump-all-headers: both\n\
78  - dns\n\
79  - tls:\n\
80  extended: yes\n\
81  session-resumption: yes\n\
82  - files\n\
83  - smtp:\n\
84  extended: yes\n\
85  - dnp3\n\
86  - ftp\n\
87  - rdp\n\
88  - nfs\n\
89  - smb\n\
90  - tftp\n\
91  - ikev2\n\
92  - krb5\n\
93  - snmp\n\
94  - rfb\n\
95  - sip\n\
96  - dhcp:\n\
97  enabled: yes\n\
98  extended: yes\n\
99  - ssh\n\
100  - flow\n\
101  - netflow\n\
102  - metadata\n\
103  - http-log:\n\
104  enabled: yes\n\
105  filename: /dev/null\n\
106  extended: yes\n\
107  - tls-log:\n\
108  enabled: yes\n\
109  filename: /dev/null\n\
110  extended: yes\n\
111 app-layer:\n\
112  protocols:\n\
113  rdp:\n\
114  enabled: yes\n\
115  modbus:\n\
116  enabled: yes\n\
117  detection-ports:\n\
118  dp: 502\n\
119  dnp3:\n\
120  enabled: yes\n\
121  detection-ports:\n\
122  dp: 20000\n\
123  enip:\n\
124  enabled: yes\n\
125  detection-ports:\n\
126  dp: 44818\n\
127  sp: 44818\n\
128  sip:\n\
129  enabled: yes\n\
130  ssh:\n\
131  enabled: yes\n\
132  hassh: yes\n\
133  mqtt:\n\
134  enabled: yes\n\
135  http2:\n\
136  enabled: yes\n\
137 ";
138 
139 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
140 {
141  pcap_t * pkts;
142  char errbuf[PCAP_ERRBUF_SIZE];
143  const u_char *pkt;
144  struct pcap_pkthdr *header;
145  int r;
146  Packet *p;
147  size_t pos;
148 
149  if (initialized == 0) {
150  //Redirects logs to /dev/null
151  setenv("SC_LOG_OP_IFACE", "file", 0);
152  setenv("SC_LOG_FILE", "/dev/null", 0);
153 
154  InitGlobal();
155 
158  //redirect logs to /tmp
159  ConfigSetLogDirectory("/tmp/");
160  //disables checksums validation for fuzzing
162  abort();
163  }
164  surifuzz.sig_file = strdup("/tmp/fuzz.rules");
166  //loads rules after init
168 
172 
173  memset(&tv, 0, sizeof(tv));
175  if (tv.flow_queue == NULL)
176  abort();
181 
183  initialized = 1;
184  }
185 
186  /* TODO add yaml config
187  for (pos = 0; pos < size; pos++) {
188  if (data[pos] == 0) {
189  break;
190  }
191  }
192  if (ConfYamlLoadString(data, pos) != 0) {
193  return 0;
194  }
195  if (pos < size) {
196  //skip zero
197  pos++;
198  }
199  data += pos;
200  size -= pos;*/
201 
202  for (pos=0; pos < size; pos++) {
203  if (data[pos] == 0) {
204  break;
205  }
206  }
207  if (pos > 0 && pos < size) {
208  // dump signatures to a file so as to reuse SigLoadSignatures
209  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos-1) < 0) {
210  return 0;
211  }
212  } else {
213  if (TestHelperBufferToFile(surifuzz.sig_file, data, pos) < 0) {
214  return 0;
215  }
216  }
217 
218  if (DetectEngineReload(&surifuzz) < 0) {
219  return 0;
220  }
221  if (pos < size) {
222  //skip zero
223  pos++;
224  }
225  data += pos;
226  size -= pos;
227 
228  //rewrite buffer to a file as libpcap does not have buffer inputs
229  if (TestHelperBufferToFile("/tmp/fuzz.pcap", data, size) < 0) {
230  return 0;
231  }
232 
233  //initialize structure
234  pkts = pcap_open_offline("/tmp/fuzz.pcap", errbuf);
235  if (pkts == NULL) {
236  return 0;
237  }
238 
239  //loop over packets
240  r = pcap_next_ex(pkts, &header, &pkt);
241  p = PacketGetFromAlloc();
242  p->datalink = pcap_datalink(pkts);
243  while (r > 0) {
244  PacketCopyData(p, pkt, header->caplen);
245  //DecodePcapFile
247  if (ecode == TM_ECODE_FAILED) {
248  break;
249  }
250  Packet *extra_p = PacketDequeueNoLock(&tv.decode_pq);
251  while (extra_p != NULL) {
252  PacketFree(extra_p);
253  extra_p = PacketDequeueNoLock(&tv.decode_pq);
254  }
256  extra_p = PacketDequeueNoLock(&tv.decode_pq);
257  while (extra_p != NULL) {
258  PacketFree(extra_p);
259  extra_p = PacketDequeueNoLock(&tv.decode_pq);
260  }
261  r = pcap_next_ex(pkts, &header, &pkt);
262  PACKET_RECYCLE(p);
263  }
264  //close structure
265  pcap_close(pkts);
266  PacketFree(p);
267 
268  return 0;
269 }
ThreadVars_::flow_queue
struct FlowQueue_ * flow_queue
Definition: threadvars.h:133
detect-engine.h
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:262
source-pcap-file.h
tv
ThreadVars tv
Definition: fuzz_sigpcap.c:30
fwd
void * fwd
Definition: fuzz_sigpcap.c:33
ippair-bit.h
LLVMFuzzerTestOneInput
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
Definition: fuzz_sigpcap.c:139
StatsSetupPrivate
int StatsSetupPrivate(ThreadVars *tv)
Definition: counters.c:1194
GlobalsInitPreConfig
void GlobalsInitPreConfig(void)
Definition: suricata.c:316
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
util-unittest-helper.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_sigpcap.c:31
Packet_::datalink
int datalink
Definition: decode.h:583
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:484
util-cidr.h
app-layer-htp.h
PreRunPostPrivsDropInit
void PreRunPostPrivsDropInit(const int runmode)
Definition: suricata.c:2033
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
util-reference-config.h
SCInstance_::delayed_detect
int delayed_detect
Definition: suricata.h:148
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
PacketFree
void PacketFree(Packet *p)
Return a malloced packet.
Definition: decode.c:105
TestHelperBufferToFile
int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size)
writes the contents of a buffer into a file
Definition: util-unittest-helper.c:101
ConfYamlLoadString
int ConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:463
PostConfLoadedSetup
int PostConfLoadedSetup(SCInstance *suri)
Definition: suricata.c:2440
detect-engine-tag.h
Packet_
Definition: decode.h:414
PostConfLoadedDetectSetup
void PostConfLoadedDetectSetup(SCInstance *suri)
Definition: suricata.c:2321
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
conf-yaml-loader.h
TMM_DECODEPCAPFILE
@ TMM_DECODEPCAPFILE
Definition: tm-threads-common.h:41
TmEcode
TmEcode
Definition: tm-threads-common.h:79
util-proto-name.h
setenv
void setenv(const char *name, const char *value, int overwrite)
TMM_FLOWWORKER
@ TMM_FLOWWORKER
Definition: tm-threads-common.h:34
tm-queuehandlers.h
detect-fast-pattern.h
suricata-common.h
run_mode
int run_mode
Definition: suricata.c:201
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
util-classification-config.h
SCInstance_::sig_file
char * sig_file
Definition: suricata.h:128
ConfigSetLogDirectory
TmEcode ConfigSetLogDirectory(const char *name)
Definition: util-conf.c:30
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:144
SCInstance_::sig_file_exclusive
int sig_file_exclusive
Definition: suricata.h:129
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:631
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:639
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:110
FlowQueueNew
FlowQueue * FlowQueueNew()
Definition: flow-queue.c:36
PacketPoolInitEmpty
void PacketPoolInitEmpty(void)
Definition: tmqh-packetpool.c:287
DetectEngineReload
int DetectEngineReload(const SCInstance *suri)
Reload the detection engine.
Definition: detect-engine.c:4063
SCInstance_
Definition: suricata.h:123
InitGlobal
int InitGlobal(void)
Global initialization common to all runmodes.
Definition: suricata.c:2670
surifuzz
SCInstance surifuzz
Definition: fuzz_sigpcap.c:34
RUNMODE_PCAP_FILE
@ RUNMODE_PCAP_FILE
Definition: runmodes.h:30
configNoChecksum
const char configNoChecksum[]
Definition: fuzz_sigpcap.c:36
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:827
host-bit.h
detect-engine-threshold.h
app-layer.h