CEFParser extends BasicParser { @SuppressWarnings("unchecked") public List<JSONObject> parse(byte[] rawMessage) { List<JSONObject> messages = new ArrayList<>(); String cefString = new String(rawMessage, getReadCharset()); Matcher matcher = p.matcher(cefString); while (matcher.find()) { JSONObject obj = new JSONObject(); if (matcher.matches()) { LOG.debug("Found %d groups", matcher.groupCount()); obj.put("DeviceVendor", matcher.group("DeviceVendor")); obj.put("DeviceProduct", matcher.group("DeviceProduct")); obj.put("DeviceVersion", matcher.group("DeviceVersion")); obj.put("DeviceEvent", matcher.group("DeviceEvent")); obj.put("Name", matcher.group("Name")); obj.put("Severity", standardizeSeverity(matcher.group("Severity"))); } parseExtensions(matcher.group("extensions"), obj); obj = mutate(obj, "dst", "ip_dst_addr"); obj = mutate(obj, "dpt", "ip_dst_port"); obj = convertToInt(obj, "ip_dst_port"); obj = mutate(obj, "src", "ip_src_addr"); obj = mutate(obj, "spt", "ip_src_port"); obj = convertToInt(obj, "ip_src_port"); obj = mutate(obj, "act", "deviceAction"); obj = mutate(obj, "app", "protocol"); obj.put("original_string", cefString); if (obj.containsKey("rt")) { String rt = (String) obj.get("rt"); try { obj.put("timestamp", DateUtils.parseMultiformat(rt, DateUtils.DATE_FORMATS_CEF)); } catch (java.text.ParseException e) { throw new IllegalStateException("rt field present in CEF but cannot be parsed", e); } } else { String logTimestamp = matcher.group("syslogTime"); if (!(logTimestamp == null || logTimestamp.isEmpty())) { try { obj.put("timestamp", SyslogUtils.parseTimestampToEpochMillis(logTimestamp, Clock.systemUTC())); } catch (ParseException e) { throw new IllegalStateException("Cannot parse syslog timestamp", e); } } else { obj.put("timestamp", System.currentTimeMillis()); } } String host = matcher.group("syslogHost"); if (!(host == null || host.isEmpty())) { obj.put("host", host); } messages.add(obj); } return messages; }  void init(); static void parseExtensions(String ext, JSONObject obj); @SuppressWarnings("unchecked") List<JSONObject> parse(byte[] rawMessage); @Override void configure(Map<String, Object> config);  }
@Test public void testInvalid() { List<JSONObject> obj = parse("test test test nonsense\n"); assertEquals(0, obj.size()); }
@Test public void testEscaping() { for (JSONObject obj : parse( "Sep 19 08:26:10 host CEF:0|security|threatmanager|1.0|100|detected a \\ in packet|10|src=10.0.0.1 act=blocked a \\ dst=1.1.1.1")) { assertEquals("10.0.0.1", obj.get(Fields.SRC_ADDR.getName())); assertEquals("blocked a \\", obj.get("deviceAction")); assertEquals("1.1.1.1", obj.get(Fields.DST_ADDR.getName())); } }
@Test public void testBasicHeader() { for (JSONObject obj : parse( "CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232")) { assertEquals("Security", obj.get("DeviceVendor")); assertEquals("threatmanager", obj.get("DeviceProduct")); assertEquals("1.0", obj.get("DeviceVersion")); assertEquals("100", obj.get("DeviceEvent")); assertEquals("worm successfully stopped", obj.get("Name")); assertEquals(10, obj.get("Severity")); } }
@Test public void testBasicExtensions() { for (JSONObject obj : parse( "CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232")) { assertEquals("10.0.0.1", obj.get(Fields.SRC_ADDR.getName())); assertEquals("2.1.2.2", obj.get(Fields.DST_ADDR.getName())); assertEquals(1232, obj.get(Fields.SRC_PORT.getName())); } }
@Test public void testCustomLabelWithSpace() { for (JSONObject obj : parse( "CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232 custom=Text with space customLabel=Label with space")) { assertEquals(true, obj.containsKey("Label with space")); assertEquals("Text with space", obj.get("Label with space")); } }
@Test public void testTimestampPriority() throws java.text.ParseException { long correctTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz").parse("2016-05-01T09:29:11.356-0400") .getTime(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz"); for (JSONObject obj : parse( "CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 rt=May 1 2016 09:29:11.356 -0400 dst=2.1.2.2 spt=1232")) { assertEquals(new Date(correctTime), new Date((long) obj.get(Fields.TIMESTAMP.getName()))); assertEquals(correctTime, obj.get(Fields.TIMESTAMP.getName())); } for (JSONObject obj : parse( "2016-06-01T09:29:11.356-04:00 host CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 rt=May 1 2016 09:29:11.356 -0400 dst=2.1.2.2 spt=1232")) { assertEquals(new Date(correctTime), new Date((long) obj.get(Fields.TIMESTAMP.getName()))); assertEquals(correctTime, obj.get(Fields.TIMESTAMP.getName())); } for (JSONObject obj : parse( "2016-05-01T09:29:11.356-04:00 host CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232")) { assertEquals(new Date(correctTime), new Date((long) obj.get(Fields.TIMESTAMP.getName()))); assertEquals(correctTime, obj.get(Fields.TIMESTAMP.getName())); } for (JSONObject obj : parse( "CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 dst=2.1.2.2 spt=1232")) { assertNotNull(obj.get(Fields.TIMESTAMP.getName())); } }
@Test public void testRtValueAsEpochTimestamp() throws java.text.ParseException { long correctTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz").parse("2016-05-01T09:29:11.356-0400") .getTime(); for (JSONObject obj : parse("CEF:0|Security|threatmanager|1.0|100|worm successfully stopped|10|src=10.0.0.1 rt=" + String.valueOf(correctTime) + " dst=2.1.2.2 spt=1232")) { assertEquals(new Date(correctTime), new Date((long) obj.get(Fields.TIMESTAMP.getName()))); assertEquals(correctTime, obj.get(Fields.TIMESTAMP.getName())); } }
@Test public void testSuccessfulWhenCEFContainsJSON() throws JsonProcessingException, IOException { List<JSONObject> parse = parse(sample); JSONObject obj = parse.get(0); assertEquals("TestVendor", obj.get("DeviceVendor")); assertEquals(1423441663000L, obj.get(Fields.TIMESTAMP.getName())); assertEquals("9223372036854775807", obj.get("Test Long")); assertEquals(obj.get("Test FP Number"), String.valueOf(1.234F)); assertEquals("00:00:0c:07:ac:00", obj.get("smac")); assertEquals("2001:cdba::3257:9652", obj.get("Test IPv6")); assertEquals("test test test chocolate", obj.get("Test String")); assertEquals("123.123.123.123", obj.get("destinationTranslatedAddress")); JsonNode inner = new ObjectMapper().readTree((String) obj.get("JSON payload")); assertEquals("chocolate!", inner.get("test_test_test").asText()); }