This commit is contained in:
zhuzhenjun
2023-09-22 15:59:40 +08:00
parent 91e6b79afc
commit 554867aa4e
16 changed files with 73081 additions and 344 deletions

View File

@@ -15,9 +15,9 @@
#include <pcap.h>
#include "libosfp.h"
#include "libosfp_fingerprint.h"
#include "libosfp_score_db.h"
#define DEFAULT_FP_FILE "./fp.json"
#define DEFAULT_FP_FILE_PATH "./fp.json"
#define ETHERNET_HEADER_LEN 14
#define VLAN_HEADER_LEN 4
@@ -131,6 +131,9 @@ typedef struct Packet_ {
struct ipv6hdr *ip6h;
struct tcphdr *tcph;
char srcip[46];
char dstip[46];
Address src;
Address dst;
union {
@@ -154,7 +157,10 @@ typedef struct Packet_ {
} Packet;
unsigned char *fp_file;
unsigned char *fp_file_path;
unsigned char *fp_output_file_path;
FILE *fingerprinting_output_fp;
unsigned char *if_name;
unsigned char *pcap_file_name;
unsigned char *bpf_string;
@@ -172,7 +178,7 @@ void usage(void) {
" -i iface - listen on the specified network interface\n"
" -r file - read offline pcap data from a given file\n"
" -f file - read fingerprint database from 'file' (%s)\n",
DEFAULT_FP_FILE);
DEFAULT_FP_FILE_PATH);
exit(1);
}
@@ -427,50 +433,39 @@ const char *PrintInet(int af, const void *src, char *dst, socklen_t size)
return NULL;
}
void example_header_match(libosfp_context_t *libosfp_context, Packet *p)
void example_detect(libosfp_context_t *libosfp_context, Packet *p)
{
// tcp/ip header match
int ret;
char str_buf[1024];
unsigned char *iph = (unsigned char *)(p->iph != NULL ? (void *)p->iph : (void *)p->ip6h);
unsigned char *tcph = (unsigned char *)p->tcph;
libosfp_result_t result;
unsigned int os_class_flags = LIBOSFP_OS_CLASS_FLAG_WINDOWS | LIBOSFP_OS_CLASS_FLAG_LINUX | LIBOSFP_OS_CLASS_FLAG_MAC_OS;
printf("Example header match: --------------------------\n");
printf("Example header detect: --------------------------\n");
ret = libosfp_header_match(libosfp_context, iph, tcph, &result);
ret = libosfp_detect(libosfp_context, os_class_flags, iph, tcph, &result);
if (ret != 0) {
printf("libosfp header match failed, erro: %s\n", "?");
goto exit;
}
char srcip[46] = {0}, dstip[46] = {0};
Port sp, dp;
if (p->iph) {
PrintInet(AF_INET, (const void *)&(p->src.addr_data32[0]), srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)&(p->dst.addr_data32[0]), dstip, sizeof(dstip));
} else if (p->ip6h) {
PrintInet(AF_INET6, (const void *)&(p->src.address), srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)&(p->dst.address), dstip, sizeof(dstip));
}
sp = p->sp;
dp = p->dp;
printf("Connection info: %s:%d -> %s:%d\n", srcip, sp, dstip, dp);
printf("Connection info: %s:%d -> %s:%d\n", p->srcip, p->sp, p->dstip, p->dp);
printf("Most likely os class: %s\n", libosfp_result_likely_os_class_name_get(&result));
printf("Likely score: %u/100\n", libosfp_result_likely_os_class_score_get(&result));
printf("Likely score: %u/100\n", result.score.likely_score);
libosfp_result_to_buf(&result, str_buf, sizeof(str_buf));
fprintf(stdout, "%s\n", str_buf);
printf("Details:\n");
if (libosfp_result_to_buf(&result, str_buf, sizeof(str_buf))) {
printf("%s", str_buf);
}
exit:
return;
}
void example_fingerprint_match(libosfp_context_t *libosfp_context, Packet *p)
void example_detect_fingerprint(libosfp_context_t *libosfp_context, Packet *p)
{
// fingerprint match
int ret;
char str_buf[1024];
@@ -479,8 +474,9 @@ void example_fingerprint_match(libosfp_context_t *libosfp_context, Packet *p)
libosfp_result_t result;
libosfp_fingerprint_t fp;
printf("Example fingerprint match: --------------------------\n");
// fingerprinting
printf("Example fingerprint detect: --------------------------\n");
memset(&fp, 0, sizeof(libosfp_fingerprint_t));
ret = libosfp_fingerprinting(iph, tcph, &fp);
if (ret != 0) {
printf("libosfp fingerprinting failed\n");
@@ -488,20 +484,31 @@ void example_fingerprint_match(libosfp_context_t *libosfp_context, Packet *p)
}
libosfp_fingerprint_to_json_buf(&fp, str_buf, sizeof(str_buf));
fprintf(stdout, "%s\n", str_buf);
printf("%s\n", str_buf);
ret = libosfp_score_db_score(libosfp_context, &fp, &result);
// output fingerprint with connection info line
if (fingerprinting_output_fp) {
fprintf(fingerprinting_output_fp, "Connection info: %s:%d -> %s:%d\n", p->srcip, p->sp, p->dstip, p->dp);
fprintf(fingerprinting_output_fp, "%s\n", str_buf);
fflush(fingerprinting_output_fp);
}
// score
memset(&result, 0, sizeof(libosfp_result_t));
ret = libosfp_score_db_score(libosfp_context->score_db, 0, &fp, &result.score);
if (ret != 0) {
printf("libosfp fingerprint score failed, error: %d\n", ret);
goto exit;
}
printf("Connection info: %s\n", "");
printf("Connection info: %s:%d -> %s:%d\n", p->srcip, p->sp, p->dstip, p->dp);
printf("Most likely os class: %s\n", libosfp_result_likely_os_class_name_get(&result));
printf("Likely score: %u/100\n", libosfp_result_likely_os_class_score_get(&result));
printf("Likely score: %u/100\n", result.score.likely_score);
libosfp_result_to_buf(&result, str_buf, sizeof(str_buf));
fprintf(stdout, "%s\n", str_buf);
printf("Details:\n");
if (libosfp_result_to_buf(&result, str_buf, sizeof(str_buf))) {
printf("%s", str_buf);
}
exit:
return;
@@ -524,9 +531,19 @@ void process_packet(char *user, struct pcap_pkthdr *h, u_char *pkt)
goto exit;
}
example_header_match(libosfp_context, p);
if (p->iph) {
PrintInet(AF_INET, (const void *)&(p->src.addr_data32[0]), p->srcip, sizeof(p->srcip));
PrintInet(AF_INET, (const void *)&(p->dst.addr_data32[0]), p->dstip, sizeof(p->dstip));
} else if (p->ip6h) {
PrintInet(AF_INET6, (const void *)&(p->src.address), p->srcip, sizeof(p->srcip));
PrintInet(AF_INET6, (const void *)&(p->dst.address), p->dstip, sizeof(p->dstip));
}
example_fingerprint_match(libosfp_context, p);
// fingerprint detect example for libosfp developer
example_detect_fingerprint(libosfp_context, p);
// tcp/ip header detect example for user
example_detect(libosfp_context, p);
printf("--------------------------- processed packet count %d\n", ++processed_packet);
@@ -538,14 +555,14 @@ int main(int argc, char *argv[])
{
int r;
while ((r = getopt(argc, argv, "+f:i:r:")) != -1) {
while ((r = getopt(argc, argv, "+f:i:r:o:")) != -1) {
switch(r) {
case 'f':
if (fp_file) {
if (fp_file_path) {
printf("Multiple -f options not supported.\n");
exit(1);
}
fp_file = (unsigned char*)optarg;
fp_file_path = (unsigned char*)optarg;
break;
case 'i':
if (if_name) {
@@ -561,6 +578,13 @@ int main(int argc, char *argv[])
}
pcap_file_name = (unsigned char*)optarg;
break;
case 'o':
if (fp_output_file_path) {
printf("Multiple -o options not supported.\n");
exit(1);
}
fp_output_file_path = (unsigned char*)optarg;
break;
default:
usage();
break;
@@ -576,6 +600,15 @@ int main(int argc, char *argv[])
}
}
// fingerprinting out file create
if (fp_output_file_path) {
fingerprinting_output_fp = fopen(fp_output_file_path, "a+");
if (!fingerprinting_output_fp) {
printf("No such file: %s\n", fp_output_file_path);
exit(1);
}
}
// prepare pcap handle
char pcap_err[PCAP_ERRBUF_SIZE];
@@ -621,13 +654,14 @@ int main(int argc, char *argv[])
link_type = pcap_datalink(pcap_handle);
// create libosfp context
if (fp_file == NULL) {
fp_file = DEFAULT_FP_FILE;
if (fp_file_path == NULL) {
fp_file_path = DEFAULT_FP_FILE_PATH;
}
libosfp_context_t *libosfp_context = libosfp_context_create(fp_file);
//libosfp_context_t *libosfp_context = libosfp_context_create(fp_file_path);
libosfp_context_t *libosfp_context = libosfp_context_create(NULL);
if (libosfp_context == NULL) {
printf("could not create libosfp context. fingerprints file: %s\n", fp_file);
printf("could not create libosfp context. fingerprints file: %s\n", fp_file_path);
exit(1);
}
@@ -635,9 +669,12 @@ int main(int argc, char *argv[])
r = libosfp_context_setup(libosfp_context);
if (r != LIBOSFP_NOERR) {
printf("could not setup libosfp context. error: %d\n", LIBOSFP_NOERR);
libosfp_context_destroy(libosfp_context);
exit(1);
}
libosfp_score_db_debug_print(libosfp_context->score_db);
// loop
while (1) {
int r = pcap_dispatch(pcap_handle, 0, (pcap_handler)process_packet, (void*)libosfp_context);
@@ -647,7 +684,7 @@ int main(int argc, char *argv[])
}
}
// create libosfp context
// destroy libosfp context
libosfp_context_destroy(libosfp_context);
return 0;