afl: add dcerpc entry points

Add for requests and mix of request/responses.

Implement storing the files to disk and rereading them.
pull/2857/head
Victor Julien 9 years ago
parent e5eb0bbe32
commit 31daf43579

@ -1170,13 +1170,13 @@ static uint32_t DCERPCParseREQUEST(DCERPC *dcerpc, uint8_t *input, uint32_t inpu
/** \internal
* \retval stub_len or 0 in case of error */
static uint32_t StubDataParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len)
static uint32_t StubDataParser(DCERPC *dcerpc, const uint8_t *input, uint32_t input_len)
{
SCEnter();
uint8_t **stub_data_buffer = NULL;
uint32_t *stub_data_buffer_len = NULL;
uint8_t *stub_data_fresh = NULL;
uint16_t stub_len = 0;
uint32_t stub_len = 0;
void *ptmp;
/* request PDU. Retrieve the request stub buffer */
@ -1192,7 +1192,7 @@ static uint32_t StubDataParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_le
stub_data_fresh = &dcerpc->dcerpcresponse.stub_data_fresh;
}
stub_len = (dcerpc->padleft < input_len) ? dcerpc->padleft : input_len;
stub_len = MIN(dcerpc->padleft, input_len);
if (stub_len == 0) {
SCLogError(SC_ERR_DCERPC, "stub_len is NULL. We shouldn't be seeing "
"this. In case you are, there is something gravely wrong "
@ -1246,7 +1246,7 @@ static uint32_t StubDataParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_le
#ifdef DEBUG
if (SCLogDebugEnabled()) {
int i = 0;
uint32_t i = 0;
for (i = 0; i < stub_len; i++) {
SCLogDebug("0x%02x ", input[i]);
}

@ -1473,6 +1473,10 @@ void AppLayerParserStatePrintDetails(AppLayerParserState *pstate)
#ifdef AFLFUZZ_APPLAYER
int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filename)
{
struct timeval ts;
memset(&ts, 0, sizeof(ts));
gettimeofday(&ts, NULL);
int result = 1;
Flow *f = NULL;
TcpSession ssn;
@ -1495,7 +1499,8 @@ int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filen
f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[64];
uint8_t buffer[65536];
uint32_t cnt = 0;
#ifdef AFLFUZZ_PERSISTANT_MODE
while (__AFL_LOOP(1000)) {
@ -1513,10 +1518,16 @@ int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filen
if (size < sizeof(buffer))
done = 1;
char outfilename[256];
snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u",
(unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, cnt);
FILE *out_fp = fopen(outfilename, "w");
BUG_ON(out_fp == NULL);
(void)fwrite(buffer, size, 1, out_fp);
fclose(out_fp);
//SCLogInfo("result %u done %d start %d", (uint)result, done, start);
uint8_t flags = STREAM_TOSERVER;
if (start--) {
flags |= STREAM_START;
}
@ -1527,6 +1538,8 @@ int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filen
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
buffer, size);
cnt++;
if (done)
break;
}
@ -1537,6 +1550,79 @@ int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filen
}
#endif /* AFLFUZZ_PERSISTANT_MODE */
/* if we get here there was no crash, so we can remove our files */
uint32_t x = 0;
for (x = 0; x < cnt; x++) {
char rmfilename[256];
snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u",
(unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, x);
unlink(rmfilename);
}
result = 0;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (f != NULL) {
FlowFree(f);
}
return result;
}
/* load a serie of files generated by DecoderParseDataFromFile() in
* the same order as it was produced. */
int AppLayerParserRequestFromFileSerie(uint8_t ipproto, AppProto alproto, char *fileprefix)
{
uint32_t cnt = 0;
int start = 1;
int result = 1;
Flow *f = NULL;
TcpSession ssn;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&ssn, 0, sizeof(ssn));
f = SCCalloc(1, sizeof(Flow));
if (f == NULL)
goto end;
FLOW_INITIALIZE(f);
f->flags |= FLOW_IPV4;
f->src.addr_data32[0] = 0x01020304;
f->dst.addr_data32[0] = 0x05060708;
f->sp = 10000;
f->dp = 80;
f->protoctx = &ssn;
f->proto = ipproto;
f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[65536];
char filename[256];
snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
FILE *fp;
while ((fp = fopen(filename, "r")) != NULL)
{
memset(buffer, 0, sizeof(buffer));
size_t size = fread(&buffer, 1, sizeof(buffer), fp);
uint8_t flags = STREAM_TOSERVER;
if (start--) {
flags |= STREAM_START;
}
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
buffer, size);
fclose(fp);
cnt++;
snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
}
result = 0;
end:
@ -1550,6 +1636,10 @@ end:
int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
{
struct timeval ts;
memset(&ts, 0, sizeof(ts));
gettimeofday(&ts, NULL);
int result = 1;
Flow *f = NULL;
TcpSession ssn;
@ -1572,7 +1662,8 @@ int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[64];
uint8_t buffer[65536];
uint32_t cnt = 0;
#ifdef AFLFUZZ_PERSISTANT_MODE
while (__AFL_LOOP(1000)) {
@ -1591,6 +1682,13 @@ int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
if (size < sizeof(buffer))
done = 1;
char outfilename[256];
snprintf(outfilename, sizeof(outfilename), "dump/%u-%u.%u",
(unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, cnt);
FILE *out_fp = fopen(outfilename, "w");
BUG_ON(out_fp == NULL);
(void)fwrite(buffer, size, 1, out_fp);
fclose(out_fp);
//SCLogInfo("result %u done %d start %d", (uint)result, done, start);
uint8_t flags = 0;
@ -1612,6 +1710,9 @@ int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
buffer, size);
cnt++;
if (done)
break;
}
@ -1622,7 +1723,88 @@ int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
}
#endif /* AFLFUZZ_PERSISTANT_MODE */
/* if we get here there was no crash, so we can remove our files */
uint32_t x = 0;
for (x = 0; x < cnt; x++) {
char rmfilename[256];
snprintf(rmfilename, sizeof(rmfilename), "dump/%u-%u.%u",
(unsigned int)ts.tv_sec, (unsigned int)ts.tv_usec, x);
unlink(rmfilename);
}
result = 0;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (f != NULL) {
FlowFree(f);
}
return result;
}
/* load a serie of files generated by DecoderParseDataFromFile() in
* the same order as it was produced. */
int AppLayerParserFromFileSerie(uint8_t ipproto, AppProto alproto, char *fileprefix)
{
uint32_t cnt = 0;
int start = 1;
int result = 1;
Flow *f = NULL;
TcpSession ssn;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&ssn, 0, sizeof(ssn));
f = SCCalloc(1, sizeof(Flow));
if (f == NULL)
goto end;
FLOW_INITIALIZE(f);
f->flags |= FLOW_IPV4;
f->src.addr_data32[0] = 0x01020304;
f->dst.addr_data32[0] = 0x05060708;
f->sp = 10000;
f->dp = 80;
f->protoctx = &ssn;
f->proto = ipproto;
f->protomap = FlowGetProtoMapping(f->proto);
f->alproto = alproto;
uint8_t buffer[65536];
int flip = 0;
char filename[256];
snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
FILE *fp;
while ((fp = fopen(filename, "r")) != NULL)
{
memset(buffer, 0, sizeof(buffer));
size_t size = fread(&buffer, 1, sizeof(buffer), fp);
uint8_t flags = 0;
if (flip) {
flags = STREAM_TOCLIENT;
flip = 0;
} else {
flags = STREAM_TOSERVER;
flip = 1;
}
if (start--) {
flags |= STREAM_START;
}
(void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
buffer, size);
fclose(fp);
cnt++;
snprintf(filename, sizeof(filename), "dump/%s.%u", fileprefix, cnt);
}
result = 0;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
@ -1631,6 +1813,7 @@ end:
}
return result;
}
#endif /* AFLFUZZ_APPLAYER */
/***** Unittests *****/

@ -252,7 +252,9 @@ void AppLayerParserStatePrintDetails(AppLayerParserState *pstate);
#ifdef AFLFUZZ_APPLAYER
int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filename);
int AppLayerParserRequestFromFileSerie(uint8_t ipproto, AppProto alproto, char *prefix);
int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename);
int AppLayerParserFromFileSerie(uint8_t ipproto, AppProto alproto, char *prefix);
#endif
/***** Unittests *****/

@ -1341,7 +1341,28 @@ static void ParseCommandLineAFL(const char *opt_name, char *opt_arg)
AppLayerParserSetup();
RegisterSMBParsers();
exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_SMB, opt_arg));
} else if(strstr(opt_name, "afl-dcerpc-request") != NULL) {
//printf("arg: //%s\n", opt_arg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterDCERPCParsers();
if (strcmp(opt_name, "afl-dcerpc-request") == 0)
exit(AppLayerParserRequestFromFile(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
else
exit(AppLayerParserRequestFromFileSerie(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
} else if(strstr(opt_name, "afl-dcerpc") != NULL) {
//printf("arg: //%s\n", opt_arg);
MpmTableSetup();
SpmTableSetup();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
RegisterDCERPCParsers();
if (strcmp(opt_name, "afl-dcerpc") == 0)
exit(AppLayerParserFromFile(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
else
exit(AppLayerParserFromFileSerie(IPPROTO_TCP, ALPROTO_DCERPC, opt_arg));
} else if(strcmp(opt_name, "afl-modbus-request") == 0) {
//printf("arg: //%s\n", opt_arg);
AppLayerParserSetup();
@ -1496,6 +1517,10 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
{"afl-mime", required_argument, 0 , 0},
{"afl-dnp3-request", required_argument, 0, 0},
{"afl-dnp3", required_argument, 0, 0},
{"afl-dcerpc", required_argument, 0, 0},
{"afl-dcerpc-serie", required_argument, 0, 0},
{"afl-dcerpc-request", required_argument, 0, 0},
{"afl-dcerpc-request-serie", required_argument, 0, 0},
/* Other AFL options. */
{"afl-rules", required_argument, 0 , 0},

Loading…
Cancel
Save