Skip to content

Commit

Permalink
Work on ja4
Browse files Browse the repository at this point in the history
  • Loading branch information
phaag committed Mar 10, 2024
1 parent ab0810d commit 595952a
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 24 deletions.
9 changes: 4 additions & 5 deletions src/libnfdump/ja4/ja4.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,21 +194,20 @@ ja4_t *ja4Process(ssl_t *ssl, uint8_t proto) {
} // End of DecodeJA4

char *ja4String(ja4_t *ja4, char *buff) {
#define JA4LEN 40
if (buff == NULL) buff = malloc(JA4LEN);
if (buff == NULL) buff = malloc(SIZEja4);
if (buff == NULL) {
LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno));
return NULL;
}

snprintf(buff, JA4LEN - 1, "%s_%s_%s", ja4->ja4.a, ja4->ja4.b, ja4->ja4.c);
buff[JA4LEN - 1] = '\0';
snprintf(buff, SIZEja4, "%s_%s_%s", ja4->ja4.a, ja4->ja4.b, ja4->ja4.c);
buff[SIZEja4 - 1] = '\0';

return buff;
} // End of ja4String

void ja4Print(ja4_t *ja4) {
char buff[JA4LEN];
char buff[SIZEja4];
printf("ja4: %s\n", ja4String(ja4, buff));
} // End of ja4Print

Expand Down
21 changes: 21 additions & 0 deletions src/libnfdump/ja4/ja4.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,27 @@

#include "ssl/ssl.h"

/*
example fingerprint:
t13d1516h2_8daaf6152771_b186095e22b6
(QUIC=”q” or TCP=”t”)
(2 character TLS version)
(SNI=”d” defined or SNI=”i” no SNI defined)
(2 character count of ciphers)
(2 character count of extensions)
(first and last characters of first ALPN extension value)
_
(sha256 hash of the list of cipher hex codes sorted in hex order, truncated to 12 characters)
_
(sha256 hash of (the list of extension hex codes sorted in hex order)_(the list of signature algorithms), truncated to 12 characters)
*/

// the true size is 37 incl. '\0'
#define SIZEja4 37

typedef struct ja4_s {
struct {
char a[16];
Expand Down
5 changes: 3 additions & 2 deletions src/libnfdump/ssl/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ static int ProcessExtALPN(ssl_t *ssl, BytesStream_t *sslStream) {
uint16_t alpnLength;
ByteStream_GET_u16(*sslStream, alpnLength);

if (alpnLength > ByteStream_AVAILABLE(*sslStream) || alpnLength >= ALPNmaxLen) {
LogError("%s():%d ALPN extension length error", __FUNCTION__, __LINE__);
if (alpnLength > ByteStream_AVAILABLE(*sslStream)) {
printf("## alpnLength: %u, available: %zu\n", alpnLength, ByteStream_AVAILABLE(*sslStream));
LogError("%s(): ALPN extension length error in %s:%d", __FUNCTION__, __FILE__, __LINE__);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libnfdump/ssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ typedef struct ssl_s {
uint16Array_t ellipticCurves;
uint16Array_t ellipticCurvesPF;
uint16Array_t signatures;
#define ALPNmaxLen 16
#define ALPNmaxLen 256
// ALPN are currently defined up to 8 bytes
char alpnName[ALPNmaxLen];
char sniName[256];
Expand Down
2 changes: 1 addition & 1 deletion src/libnffile/nffileV2.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct fileHeaderV2_s {
#define LAYOUT_VERSION_2 2

uint32_t nfdversion; // version of nfdump created this file
#define NFDVERSION 0xF1070200
#define NFDVERSION 0xF1070400
// 4bytes 1.7.1-1 0x01070101
// 4bytes 1.7.1-1 0xF1070101 - git repo based on 1.7.1
time_t created; // file create time
Expand Down
2 changes: 1 addition & 1 deletion src/libnffile/nfxV3.h
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ typedef struct EXpfinfo_s {
h->numElements++; \
h->size += s;

#define ExtensionLength(ext) ((elementHeader_t *)((void *)ext - sizeof(elementHeader_t)))->length
#define ExtensionLength(ext) (((elementHeader_t *)((void *)ext - sizeof(elementHeader_t)))->length - sizeof(elementHeader_t))

#define EXTENSION(s) \
{ s##ID, s##Size, #s }
Expand Down
44 changes: 34 additions & 10 deletions src/nfdump/nfstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#include "blocksort.h"
#include "config.h"
#include "ja3/ja3.h"
#include "ja4/ja4.h"
#include "ja4/ja4s.h"
#include "khash.h"
#include "maxmind/maxmind.h"
#include "nfdump.h"
Expand Down Expand Up @@ -180,7 +182,7 @@ struct StatParameter_s {
{"al", "Application Latency", {EXlatencyID, OFFusecApplLatency, SIZEusecApplLatency, 0}, IS_LATENCY, NOPROC},
{"nbar", "Nbar", {EXnbarAppID, OFFnbarAppID, SIZEnbarAppID, 0}, IS_NBAR, NOPROC},
{"ja3", " ja3", {EXlocal, OFFja3, SIZEja3, 0}, IS_JA3, JA3},
{"ja4", " ja4", {EXlocal, 0, 0, 0}, IS_JA4, JA4},
{"ja4", " ja4", {EXlocal, 0, 0, SIZEja4}, IS_JA4, JA4},
{"odid", "Obs DomainID", {EXobservationID, OFFdomainID, SIZEdomainID, 0}, IS_HEXNUMBER, NOPROC},
{"opid", "Obs PointID", {EXobservationID, OFFpointID, SIZEpointID, 0}, IS_HEXNUMBER, NOPROC},
{"event", " Event", {EXnselCommonID, OFFfwEvent, SIZEfwEvent, 0}, IS_EVENT, NOPROC},
Expand Down Expand Up @@ -485,39 +487,39 @@ int SetElementStat(char *elementStat, char *orderBy) {

} // End of SetElementStat

static inline void PreProcess(void *inPtr, preprocess_t process, recordHandle_t *recordHandle) {
static inline void *PreProcess(void *inPtr, preprocess_t process, recordHandle_t *recordHandle) {
EXgenericFlow_t *genericFlow = (EXgenericFlow_t *)recordHandle->extensionList[EXgenericFlowID];
EXipv4Flow_t *ipv4Flow = (EXipv4Flow_t *)recordHandle->extensionList[EXipv4FlowID];
EXipv6Flow_t *ipv6Flow = (EXipv6Flow_t *)recordHandle->extensionList[EXipv6FlowID];

switch (process) {
case NOPROC:
return;
return inPtr;
break;
case SRC_GEO: {
char *geo = (char *)inPtr;
if (HasGeoDB == 0 || geo[0]) return;
if (HasGeoDB == 0 || geo[0]) return inPtr;
if (ipv4Flow)
LookupV4Country(ipv4Flow->srcAddr, geo);
else if (ipv6Flow)
LookupV6Country(ipv6Flow->srcAddr, geo);
} break;
case DST_GEO: {
char *geo = (char *)inPtr;
if (HasGeoDB == 0 || geo[0]) return;
if (HasGeoDB == 0 || geo[0]) return inPtr;
if (ipv4Flow)
LookupV4Country(ipv4Flow->dstAddr, inPtr);
else if (ipv6Flow)
LookupV6Country(ipv6Flow->dstAddr, inPtr);
} break;
case SRC_AS: {
uint32_t *as = (uint32_t *)inPtr;
if (HasGeoDB == 0 || *as) return;
if (HasGeoDB == 0 || *as) return inPtr;
*as = ipv4Flow ? LookupV4AS(ipv4Flow->srcAddr) : (ipv6Flow ? LookupV6AS(ipv6Flow->srcAddr) : 0);
} break;
case DST_AS: {
uint32_t *as = (uint32_t *)inPtr;
if (HasGeoDB == 0 || *as) return;
if (HasGeoDB == 0 || *as) return inPtr;
*as = ipv4Flow ? LookupV4AS(ipv4Flow->dstAddr) : (ipv6Flow ? LookupV6AS(ipv6Flow->dstAddr) : 0);
} break;
case PREV_AS: {
Expand All @@ -526,7 +528,7 @@ static inline void PreProcess(void *inPtr, preprocess_t process, recordHandle_t
} break;
case JA3: {
EXinPayload_t *payload = (EXinPayload_t *)recordHandle->extensionList[EXinPayloadID];
if (payload == NULL || genericFlow->proto != IPPROTO_TCP || JA3DEFINED(recordHandle->ja3)) return;
if (payload == NULL || genericFlow->proto != IPPROTO_TCP || JA3DEFINED(recordHandle->ja3)) return inPtr;

uint32_t payloadLength = ExtensionLength(payload);
ssl_t *ssl = (ssl_t *)recordHandle->sslInfo;
Expand All @@ -535,11 +537,29 @@ static inline void PreProcess(void *inPtr, preprocess_t process, recordHandle_t
recordHandle->sslInfo = (void *)ssl;
}
ja3Process(ssl, recordHandle->ja3);

return inPtr;
} break;
case JA4: {
EXinPayload_t *payload = (EXinPayload_t *)recordHandle->extensionList[EXinPayloadID];
if (payload == NULL || genericFlow->proto != IPPROTO_TCP) return NULL;

uint32_t payloadLength = ExtensionLength(payload);
ssl_t *ssl = (ssl_t *)recordHandle->sslInfo;
if (ssl == NULL) {
ssl = sslProcess((const uint8_t *)payload, payloadLength);
if (ssl == NULL) return NULL;
recordHandle->sslInfo = (void *)ssl;
}
// ssl is defined
static char ja4StrBuff[SIZEja4];
ja4_t *ja4 = ja4Process(ssl, genericFlow->proto);
ja4String(ja4, ja4StrBuff);
inPtr = (void *)ja4StrBuff;
return inPtr;
} break;
}

return inPtr;
} // End of PreProcess

void AddElementStat(recordHandle_t *recordHandle) {
Expand All @@ -565,7 +585,11 @@ void AddElementStat(recordHandle_t *recordHandle) {

uint32_t length = StatParameters[index].element.length;
preprocess_t lookup = StatParameters[index].preprocess;
PreProcess(inPtr, lookup, recordHandle);
inPtr = PreProcess(inPtr, lookup, recordHandle);
if (inPtr == NULL) {
index++;
continue;
}

switch (length) {
case 0:
Expand Down
2 changes: 1 addition & 1 deletion src/nfpcapd/pcaproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ void ProcessPacket(packetParam_t *packetParam, const struct pcap_pkthdr *hdr, co
size_t size_ip = sizeof(struct ip6_hdr);

dataptr += size_ip;
if (dataptr > eodata) {
if (dataptr >= eodata) {
dbg_printf("Short packet: %u, Check line: %u", hdr->caplen, __LINE__);
packetParam->proc_stat.short_snap++;
goto END_FUNC;
Expand Down
6 changes: 3 additions & 3 deletions src/output/output_raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,13 +724,13 @@ static void inoutPayload(FILE *stream, recordHandle_t *recordHandle, uint8_t *pa
if (ssl) {
switch (ssl->tlsCharVersion[0]) {
case 's':
fprintf(stream, " TLS version = SSL %c ", ssl->tlsCharVersion[1]);
fprintf(stream, " TLS version = SSL %c \n", ssl->tlsCharVersion[1]);
break;
case '1':
fprintf(stream, " TLS version = 1.%c", ssl->tlsCharVersion[1]);
fprintf(stream, " TLS version = TLS 1.%c\n", ssl->tlsCharVersion[1]);
break;
default:
fprintf(stream, " TLS version = 0x%4x", ssl->tlsVersion);
fprintf(stream, " TLS version = 0x%4x\n", ssl->tlsVersion);
break;
}

Expand Down

0 comments on commit 595952a

Please sign in to comment.