mirror of
https://github.com/telekom-security/tpotce.git
synced 2025-07-02 01:27:27 -04:00
include docker repos
... skip emobility since it is a dev repo
This commit is contained in:
27
docker/p0f/Dockerfile
Normal file
27
docker/p0f/Dockerfile
Normal file
@ -0,0 +1,27 @@
|
||||
FROM alpine
|
||||
MAINTAINER MO
|
||||
|
||||
# Add source
|
||||
ADD . /opt/p0f
|
||||
|
||||
# Install packages
|
||||
RUN apk -U upgrade && \
|
||||
apk add bash build-base git jansson-dev libpcap-dev procps && \
|
||||
|
||||
# Setup user, groups and configs
|
||||
addgroup -g 2000 p0f && \
|
||||
adduser -S -s /bin/bash -u 2000 -D -g 2000 p0f && \
|
||||
|
||||
# Download and compile p0f
|
||||
cd /opt/p0f && \
|
||||
./build.sh && \
|
||||
|
||||
# Clean up
|
||||
apk del build-base git jansson-dev libpcap-dev && \
|
||||
apk add jansson libpcap && \
|
||||
rm -rf /root/* && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Start suricata
|
||||
WORKDIR /opt/p0f
|
||||
CMD /bin/bash -c "exec /opt/p0f/p0f -u p0f -j -o /var/log/p0f/p0f.json -i $(/sbin/ip address | grep '^2: ' | awk '{ print $2 }' | tr -d [:punct:])"
|
21
docker/p0f/Makefile
Normal file
21
docker/p0f/Makefile
Normal file
@ -0,0 +1,21 @@
|
||||
#
|
||||
# p0f - make wrapper
|
||||
# ------------------
|
||||
#
|
||||
# Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
#
|
||||
# Distributed under the terms and conditions of GNU LGPL.
|
||||
#
|
||||
|
||||
all:
|
||||
@./build.sh all
|
||||
|
||||
debug:
|
||||
@./build.sh debug
|
||||
|
||||
clean:
|
||||
@./build.sh clean
|
||||
|
||||
publish:
|
||||
@./build.sh publish
|
||||
|
4
docker/p0f/README.md
Normal file
4
docker/p0f/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
[](https://microbadger.com/images/dtagdevsec/p0f:1706 "Get your own version badge on microbadger.com") [](https://microbadger.com/images/dtagdevsec/p0f:1706 "Get your own image badge on microbadger.com")
|
||||
|
||||
# dockerized p0f
|
||||
|
485
docker/p0f/alloc-inl.h
Normal file
485
docker/p0f/alloc-inl.h
Normal file
@ -0,0 +1,485 @@
|
||||
/*
|
||||
p0f - error-checking, memory-zeroing alloc routines
|
||||
---------------------------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_ALLOC_INL_H
|
||||
#define _HAVE_ALLOC_INL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define ALLOC_CHECK_SIZE(_s) do { \
|
||||
if ((_s) > MAX_ALLOC) \
|
||||
ABORT("Bad alloc request: %u bytes", (_s)); \
|
||||
} while (0)
|
||||
|
||||
#define ALLOC_CHECK_RESULT(_r,_s) do { \
|
||||
if (!(_r)) \
|
||||
ABORT("Out of memory: can't allocate %u bytes", (_s)); \
|
||||
} while (0)
|
||||
|
||||
#define ALLOC_MAGIC 0xFF00
|
||||
#define ALLOC_MAGIC_F 0xFE00
|
||||
|
||||
#define ALLOC_C(_ptr) (((u16*)(_ptr))[-3])
|
||||
#define ALLOC_S(_ptr) (((u32*)(_ptr))[-1])
|
||||
|
||||
#define CHECK_PTR(_p) do { \
|
||||
if ((_p) && ALLOC_C(_p) != ALLOC_MAGIC) {\
|
||||
if (ALLOC_C(_p) == ALLOC_MAGIC_F) \
|
||||
ABORT("Use after free."); \
|
||||
else \
|
||||
ABORT("Bad alloc canary."); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define CHECK_PTR_EXPR(_p) ({ \
|
||||
typeof (_p) _tmp = (_p); \
|
||||
CHECK_PTR(_tmp); \
|
||||
_tmp; \
|
||||
})
|
||||
|
||||
#ifdef CHECK_UAF
|
||||
# define CP(_p) CHECK_PTR_EXPR(_p)
|
||||
#else
|
||||
# define CP(_p) (_p)
|
||||
#endif /* ^CHECK_UAF */
|
||||
|
||||
#ifdef ALIGN_ACCESS
|
||||
# define ALLOC_OFF 8
|
||||
#else
|
||||
# define ALLOC_OFF 6
|
||||
#endif /* ^ALIGN_ACCESS */
|
||||
|
||||
|
||||
static inline void* DFL_ck_alloc(u32 size) {
|
||||
void* ret;
|
||||
|
||||
if (!size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF;
|
||||
|
||||
ALLOC_C(ret) = ALLOC_MAGIC;
|
||||
ALLOC_S(ret) = size;
|
||||
|
||||
return memset(ret, 0, size);
|
||||
}
|
||||
|
||||
|
||||
static inline void* DFL_ck_realloc(void* orig, u32 size) {
|
||||
void* ret;
|
||||
u32 old_size = 0;
|
||||
|
||||
if (!size) {
|
||||
|
||||
if (orig) {
|
||||
|
||||
CHECK_PTR(orig);
|
||||
|
||||
/* Catch pointer issues sooner. */
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
memset(orig - ALLOC_OFF, 0xFF, ALLOC_S(orig) + ALLOC_OFF);
|
||||
#endif /* DEBUG_BUILD */
|
||||
|
||||
free(orig - ALLOC_OFF);
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if (orig) {
|
||||
|
||||
CHECK_PTR(orig);
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
ALLOC_C(orig) = ALLOC_MAGIC_F;
|
||||
#endif /* !DEBUG_BUILD */
|
||||
|
||||
old_size = ALLOC_S(orig);
|
||||
orig -= ALLOC_OFF;
|
||||
|
||||
ALLOC_CHECK_SIZE(old_size);
|
||||
|
||||
}
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
ret = realloc(orig, size + ALLOC_OFF);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
#else
|
||||
|
||||
/* Catch pointer issues sooner: force relocation and make sure that the
|
||||
original buffer is wiped. */
|
||||
|
||||
ret = malloc(size + ALLOC_OFF);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
if (orig) {
|
||||
|
||||
memcpy(ret + ALLOC_OFF, orig + ALLOC_OFF, MIN(size, old_size));
|
||||
memset(orig, 0xFF, old_size + ALLOC_OFF);
|
||||
|
||||
ALLOC_C(orig + ALLOC_OFF) = ALLOC_MAGIC_F;
|
||||
|
||||
free(orig);
|
||||
|
||||
}
|
||||
|
||||
#endif /* ^!DEBUG_BUILD */
|
||||
|
||||
ret += ALLOC_OFF;
|
||||
|
||||
ALLOC_C(ret) = ALLOC_MAGIC;
|
||||
ALLOC_S(ret) = size;
|
||||
|
||||
if (size > old_size)
|
||||
memset(ret + old_size, 0, size - old_size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline void* DFL_ck_realloc_kb(void* orig, u32 size) {
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
if (orig) {
|
||||
|
||||
CHECK_PTR(orig);
|
||||
|
||||
if (ALLOC_S(orig) >= size) return orig;
|
||||
|
||||
size = ((size >> 10) + 1) << 10;
|
||||
}
|
||||
|
||||
#endif /* !DEBUG_BUILD */
|
||||
|
||||
return DFL_ck_realloc(orig, size);
|
||||
}
|
||||
|
||||
|
||||
static inline u8* DFL_ck_strdup(u8* str) {
|
||||
void* ret;
|
||||
u32 size;
|
||||
|
||||
if (!str) return NULL;
|
||||
|
||||
size = strlen((char*)str) + 1;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF;
|
||||
|
||||
ALLOC_C(ret) = ALLOC_MAGIC;
|
||||
ALLOC_S(ret) = size;
|
||||
|
||||
return memcpy(ret, str, size);
|
||||
}
|
||||
|
||||
|
||||
static inline void* DFL_ck_memdup(void* mem, u32 size) {
|
||||
void* ret;
|
||||
|
||||
if (!mem || !size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF;
|
||||
|
||||
ALLOC_C(ret) = ALLOC_MAGIC;
|
||||
ALLOC_S(ret) = size;
|
||||
|
||||
return memcpy(ret, mem, size);
|
||||
}
|
||||
|
||||
|
||||
static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
|
||||
u8* ret;
|
||||
|
||||
if (!mem || !size) return NULL;
|
||||
|
||||
ALLOC_CHECK_SIZE(size);
|
||||
ret = malloc(size + ALLOC_OFF + 1);
|
||||
ALLOC_CHECK_RESULT(ret, size);
|
||||
|
||||
ret += ALLOC_OFF;
|
||||
|
||||
ALLOC_C(ret) = ALLOC_MAGIC;
|
||||
ALLOC_S(ret) = size;
|
||||
|
||||
memcpy(ret, mem, size);
|
||||
ret[size] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline void DFL_ck_free(void* mem) {
|
||||
|
||||
if (mem) {
|
||||
|
||||
CHECK_PTR(mem);
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
|
||||
/* Catch pointer issues sooner. */
|
||||
memset(mem - ALLOC_OFF, 0xFF, ALLOC_S(mem) + ALLOC_OFF);
|
||||
|
||||
#endif /* DEBUG_BUILD */
|
||||
|
||||
ALLOC_C(mem) = ALLOC_MAGIC_F;
|
||||
|
||||
free(mem - ALLOC_OFF);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef DEBUG_BUILD
|
||||
|
||||
/* Non-debugging mode - straightforward aliasing. */
|
||||
|
||||
#define ck_alloc DFL_ck_alloc
|
||||
#define ck_realloc DFL_ck_realloc
|
||||
#define ck_realloc_kb DFL_ck_realloc_kb
|
||||
#define ck_strdup DFL_ck_strdup
|
||||
#define ck_memdup DFL_ck_memdup
|
||||
#define ck_memdup_str DFL_ck_memdup_str
|
||||
#define ck_free DFL_ck_free
|
||||
|
||||
#else
|
||||
|
||||
/* Debugging mode - include additional structures and support code. */
|
||||
|
||||
#define ALLOC_BUCKETS 4096
|
||||
#define ALLOC_TRK_CHUNK 256
|
||||
|
||||
struct TRK_obj {
|
||||
void *ptr;
|
||||
char *file, *func;
|
||||
u32 line;
|
||||
};
|
||||
|
||||
|
||||
extern struct TRK_obj* TRK[ALLOC_BUCKETS];
|
||||
extern u32 TRK_cnt[ALLOC_BUCKETS];
|
||||
|
||||
#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)
|
||||
|
||||
/* Adds a new entry to the list of allocated objects. */
|
||||
|
||||
static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
if (!ptr) return;
|
||||
|
||||
bucket = TRKH(ptr);
|
||||
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
|
||||
if (!TRK[bucket][i].ptr) {
|
||||
|
||||
TRK[bucket][i].ptr = ptr;
|
||||
TRK[bucket][i].file = (char*)file;
|
||||
TRK[bucket][i].func = (char*)func;
|
||||
TRK[bucket][i].line = line;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* No space available. */
|
||||
|
||||
if (!(i % ALLOC_TRK_CHUNK)) {
|
||||
|
||||
TRK[bucket] = DFL_ck_realloc(TRK[bucket],
|
||||
(TRK_cnt[bucket] + ALLOC_TRK_CHUNK) * sizeof(struct TRK_obj));
|
||||
|
||||
}
|
||||
|
||||
TRK[bucket][i].ptr = ptr;
|
||||
TRK[bucket][i].file = (char*)file;
|
||||
TRK[bucket][i].func = (char*)func;
|
||||
TRK[bucket][i].line = line;
|
||||
|
||||
TRK_cnt[bucket]++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Removes entry from the list of allocated objects. */
|
||||
|
||||
static inline void TRK_free_buf(void* ptr, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
if (!ptr) return;
|
||||
|
||||
bucket = TRKH(ptr);
|
||||
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
|
||||
if (TRK[bucket][i].ptr == ptr) {
|
||||
|
||||
TRK[bucket][i].ptr = 0;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
WARN("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)",
|
||||
func, file, line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Does a final report on all non-deallocated objects. */
|
||||
|
||||
static inline void TRK_report(void) {
|
||||
|
||||
u32 i, bucket;
|
||||
|
||||
fflush(0);
|
||||
|
||||
for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)
|
||||
for (i = 0; i < TRK_cnt[bucket]; i++)
|
||||
if (TRK[bucket][i].ptr)
|
||||
WARN("ALLOC: Memory never freed, created in %s (%s:%u)",
|
||||
TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Simple wrappers for non-debugging functions: */
|
||||
|
||||
static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
void* ret = DFL_ck_alloc(size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_realloc(orig, size);
|
||||
TRK_free_buf(orig, file, func, line);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_realloc_kb(void* orig, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_realloc_kb(orig, size);
|
||||
TRK_free_buf(orig, file, func, line);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,
|
||||
u32 line) {
|
||||
|
||||
void* ret = DFL_ck_strdup(str);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_memdup(mem, size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
void* ret = DFL_ck_memdup_str(mem, size);
|
||||
TRK_alloc_buf(ret, file, func, line);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline void TRK_ck_free(void* ptr, const char* file,
|
||||
const char* func, u32 line) {
|
||||
|
||||
TRK_free_buf(ptr, file, func, line);
|
||||
DFL_ck_free(ptr);
|
||||
|
||||
}
|
||||
|
||||
/* Alias user-facing names to tracking functions: */
|
||||
|
||||
#define ck_alloc(_p1) \
|
||||
TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_realloc(_p1, _p2) \
|
||||
TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_realloc_kb(_p1, _p2) \
|
||||
TRK_ck_realloc_kb(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_strdup(_p1) \
|
||||
TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_memdup(_p1, _p2) \
|
||||
TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_memdup_str(_p1, _p2) \
|
||||
TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#define ck_free(_p1) \
|
||||
TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)
|
||||
|
||||
#endif /* ^!DEBUG_BUILD */
|
||||
|
||||
#define alloc_printf(_str...) ({ \
|
||||
u8* _tmp; \
|
||||
s32 _len = snprintf(NULL, 0, _str); \
|
||||
if (_len < 0) FATAL("Whoa, snprintf() fails?!"); \
|
||||
_tmp = ck_alloc(_len + 1); \
|
||||
snprintf((char*)_tmp, _len + 1, _str); \
|
||||
_tmp; \
|
||||
})
|
||||
|
||||
#endif /* ! _HAVE_ALLOC_INL_H */
|
106
docker/p0f/api.c
Normal file
106
docker/p0f/api.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
p0f - API query code
|
||||
--------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#define _FROM_API
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "alloc-inl.h"
|
||||
#include "p0f.h"
|
||||
#include "api.h"
|
||||
#include "process.h"
|
||||
#include "readfp.h"
|
||||
|
||||
/* Process API queries. */
|
||||
|
||||
void handle_query(struct p0f_api_query* q, struct p0f_api_response* r) {
|
||||
|
||||
struct host_data* h;
|
||||
|
||||
memset(r, 0, sizeof(struct p0f_api_response));
|
||||
|
||||
r->magic = P0F_RESP_MAGIC;
|
||||
|
||||
if (q->magic != P0F_QUERY_MAGIC) {
|
||||
|
||||
WARN("Query with bad magic (0x%x).", q->magic);
|
||||
|
||||
r->status = P0F_STATUS_BADQUERY;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
switch (q->addr_type) {
|
||||
|
||||
case P0F_ADDR_IPV4:
|
||||
case P0F_ADDR_IPV6:
|
||||
h = lookup_host(q->addr, q->addr_type);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
WARN("Query with unknown address type %u.\n", q->addr_type);
|
||||
r->status = P0F_STATUS_BADQUERY;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!h) {
|
||||
r->status = P0F_STATUS_NOMATCH;
|
||||
return;
|
||||
}
|
||||
|
||||
r->status = P0F_STATUS_OK;
|
||||
r->first_seen = h->first_seen;
|
||||
r->last_seen = h->last_seen;
|
||||
r->total_conn = h->total_conn;
|
||||
|
||||
if (h->last_name_id != -1) {
|
||||
|
||||
strncpy((char*)r->os_name, (char*)fp_os_names[h->last_name_id],
|
||||
P0F_STR_MAX + 1);
|
||||
|
||||
if (h->last_flavor)
|
||||
strncpy((char*)r->os_flavor, (char*)h->last_flavor, P0F_STR_MAX + 1);
|
||||
|
||||
}
|
||||
|
||||
if (h->http_name_id != -1) {
|
||||
|
||||
strncpy((char*)r->http_name, (char*)fp_os_names[h->http_name_id],
|
||||
P0F_STR_MAX + 1);
|
||||
|
||||
if (h->http_flavor)
|
||||
strncpy((char*)r->http_flavor, (char*)h->http_flavor, P0F_STR_MAX + 1);
|
||||
|
||||
}
|
||||
|
||||
if (h->link_type)
|
||||
strncpy((char*)r->link_type, (char*)h->link_type, P0F_STR_MAX + 1);
|
||||
|
||||
if (h->language)
|
||||
strncpy((char*)r->language, (char*)h->language, P0F_STR_MAX + 1);
|
||||
|
||||
r->bad_sw = h->bad_sw;
|
||||
r->last_nat = h->last_nat;
|
||||
r->last_chg = h->last_chg;
|
||||
r->up_mod_days = h->up_mod_days;
|
||||
r->distance = h->distance;
|
||||
r->os_match_q = h->last_quality;
|
||||
|
||||
if (h->last_up_min != -1) r->uptime_min = h->last_up_min;
|
||||
|
||||
}
|
79
docker/p0f/api.h
Normal file
79
docker/p0f/api.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
p0f - API query code
|
||||
--------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_API_H
|
||||
#define _HAVE_API_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define P0F_QUERY_MAGIC 0x50304601
|
||||
#define P0F_RESP_MAGIC 0x50304602
|
||||
|
||||
#define P0F_STATUS_BADQUERY 0x00
|
||||
#define P0F_STATUS_OK 0x10
|
||||
#define P0F_STATUS_NOMATCH 0x20
|
||||
|
||||
#define P0F_ADDR_IPV4 0x04
|
||||
#define P0F_ADDR_IPV6 0x06
|
||||
|
||||
#define P0F_STR_MAX 31
|
||||
|
||||
#define P0F_MATCH_FUZZY 0x01
|
||||
#define P0F_MATCH_GENERIC 0x02
|
||||
|
||||
/* Keep these structures aligned to avoid architecture-specific padding. */
|
||||
|
||||
struct p0f_api_query {
|
||||
|
||||
u32 magic; /* Must be P0F_QUERY_MAGIC */
|
||||
u8 addr_type; /* P0F_ADDR_* */
|
||||
u8 addr[16]; /* IP address (big endian left align) */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
struct p0f_api_response {
|
||||
|
||||
u32 magic; /* Must be P0F_RESP_MAGIC */
|
||||
u32 status; /* P0F_STATUS_* */
|
||||
|
||||
u32 first_seen; /* First seen (unix time) */
|
||||
u32 last_seen; /* Last seen (unix time) */
|
||||
u32 total_conn; /* Total connections seen */
|
||||
|
||||
u32 uptime_min; /* Last uptime (minutes) */
|
||||
u32 up_mod_days; /* Uptime modulo (days) */
|
||||
|
||||
u32 last_nat; /* NAT / LB last detected (unix time) */
|
||||
u32 last_chg; /* OS chg last detected (unix time) */
|
||||
|
||||
s16 distance; /* System distance */
|
||||
|
||||
u8 bad_sw; /* Host is lying about U-A / Server */
|
||||
u8 os_match_q; /* Match quality */
|
||||
|
||||
u8 os_name[P0F_STR_MAX + 1]; /* Name of detected OS */
|
||||
u8 os_flavor[P0F_STR_MAX + 1]; /* Flavor of detected OS */
|
||||
|
||||
u8 http_name[P0F_STR_MAX + 1]; /* Name of detected HTTP app */
|
||||
u8 http_flavor[P0F_STR_MAX + 1]; /* Flavor of detected HTTP app */
|
||||
|
||||
u8 link_type[P0F_STR_MAX + 1]; /* Link type */
|
||||
|
||||
u8 language[P0F_STR_MAX + 1]; /* Language */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
#ifdef _FROM_P0F
|
||||
|
||||
void handle_query(struct p0f_api_query* q, struct p0f_api_response* r);
|
||||
|
||||
#endif /* _FROM_API */
|
||||
|
||||
#endif /* !_HAVE_API_H */
|
357
docker/p0f/build.sh
Executable file
357
docker/p0f/build.sh
Executable file
@ -0,0 +1,357 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# p0f - build script
|
||||
# ------------------
|
||||
#
|
||||
# Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
#
|
||||
# Distributed under the terms and conditions of GNU LGPL.
|
||||
#
|
||||
|
||||
PROGNAME="p0f"
|
||||
VERSION="3.09b"
|
||||
|
||||
test "$CC" = "" && CC="gcc"
|
||||
|
||||
BASIC_CFLAGS="-Wall -Wno-format -I/usr/local/include/ \
|
||||
-I/opt/local/include/ -DVERSION=\"$VERSION\" $CFLAGS"
|
||||
|
||||
BASIC_LDFLAGS="-L/usr/local/lib/ -L/opt/local/lib $LDFLAGS"
|
||||
|
||||
USE_CFLAGS="-fstack-protector-all -fPIE -D_FORTIFY_SOURCE=2 -g -ggdb \
|
||||
$BASIC_CFLAGS"
|
||||
|
||||
USE_LDFLAGS="-Wl,-z,relro -pie $BASIC_LDFLAGS"
|
||||
|
||||
if [ "$OSTYPE" = "cygwin" ]; then
|
||||
USE_LIBS="-lwpcap $LIBS"
|
||||
elif [ "$OSTYPE" = "solaris" ]; then
|
||||
USE_LIBS="-lsocket -lnsl $LIBS"
|
||||
else
|
||||
USE_LIBS="-lpcap -ljansson $LIBS"
|
||||
fi
|
||||
|
||||
OBJFILES="api.c process.c fp_tcp.c fp_mtu.c fp_http.c readfp.c"
|
||||
|
||||
echo "Welcome to the build script for $PROGNAME $VERSION!"
|
||||
echo "Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>"
|
||||
echo
|
||||
|
||||
if [ "$#" -gt "1" ]; then
|
||||
|
||||
echo "[-] Please specify one build target at a time."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [ "$1" = "clean" -o "$1" = "publish" ]; then
|
||||
|
||||
echo "[*] Cleaning up build environment..."
|
||||
rm -f -- "$PROGNAME" *.exe *.o a.out *~ core core.[1-9][0-9]* *.stackdump COMPILER-WARNINGS 2>/dev/null
|
||||
|
||||
( cd tools && make clean ) &>/dev/null
|
||||
|
||||
if [ "$1" = "publish" ]; then
|
||||
|
||||
if [ ! "`basename -- \"$PWD\"`" = "$PROGNAME" ]; then
|
||||
echo "[-] Invalid working directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! "$HOSTNAME" = "raccoon" ]; then
|
||||
echo "[-] You are not my real dad!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET="/var/www/lcamtuf/p0f3/$PROGNAME-devel.tgz"
|
||||
|
||||
echo "[*] Creating $TARGET..."
|
||||
|
||||
cd ..
|
||||
rm -rf "$PROGNAME-$VERSION"
|
||||
cp -pr "$PROGNAME" "$PROGNAME-$VERSION"
|
||||
tar cfvz "$TARGET" "$PROGNAME-$VERSION"
|
||||
|
||||
fi
|
||||
|
||||
echo "[+] All done!"
|
||||
|
||||
exit 0
|
||||
|
||||
elif [ "$1" = "all" -o "$1" = "" ]; then
|
||||
|
||||
echo "[+] Configuring production build."
|
||||
BASIC_CFLAGS="$BASIC_CFLAGS -O3"
|
||||
USE_CFLAGS="$USE_CFLAGS -O3"
|
||||
|
||||
elif [ "$1" = "debug" ]; then
|
||||
|
||||
echo "[+] Configuring debug build."
|
||||
BASIC_CFLAGS="$BASIC_CFLAGS -DDEBUG_BUILD=1"
|
||||
USE_CFLAGS="$USE_CFLAGS -DDEBUG_BUILD=1"
|
||||
|
||||
else
|
||||
|
||||
echo "[-] Unrecognized build target '$1', sorry."
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
rm -f COMPILER-WARNINGS 2>/dev/null
|
||||
|
||||
echo -n "[*] Checking for a sane build environment... "
|
||||
|
||||
if ls -ld ./ | grep -q '^d.......w'; then
|
||||
|
||||
echo "FAIL (bad permissions)"
|
||||
echo
|
||||
echo "Duuude, don't build stuff in world-writable directories."
|
||||
echo
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
TMP=".build-$$"
|
||||
|
||||
rm -f "$TMP" 2>/dev/null
|
||||
|
||||
if [ -f "$TMP" ]; then
|
||||
|
||||
echo "FAIL (can't delete)"
|
||||
echo
|
||||
echo "Check directory permissions and try again."
|
||||
echo
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
touch "$TMP" 2>/dev/null
|
||||
|
||||
if [ ! -f "$TMP" ]; then
|
||||
|
||||
echo "FAIL (can't create)"
|
||||
echo
|
||||
echo "Check directory permissions and try again."
|
||||
echo
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -s "$PROGNAME.c" ]; then
|
||||
|
||||
echo "FAIL (no source)"
|
||||
echo
|
||||
echo "I'm no doctor, but I think the source code is missing from CWD."
|
||||
echo
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
echo -n "[*] Checking for working GCC... "
|
||||
|
||||
rm -f "$TMP" || exit 1
|
||||
|
||||
echo "int main() { return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $BASIC_CFLAGS $BASIC_LDFLAGS "$TMP.c" -o "$TMP" &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
|
||||
echo "FAIL"
|
||||
echo
|
||||
echo "Your compiler can't produce working binaries. You need a functioning install of"
|
||||
echo "GCC and libc (including development headers) to continue. If you have these,"
|
||||
echo "try setting CC, CFLAGS, and LDFLAGS appropriately."
|
||||
echo
|
||||
echo "Output from an attempt to execute GCC:"
|
||||
cat "$TMP.log" | head -10
|
||||
echo
|
||||
rm -f "$TMP" "$TMP.log" "$TMP.c"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
echo -n "[*] Checking for *modern* GCC... "
|
||||
|
||||
rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
|
||||
|
||||
echo "int main() { return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
|
||||
echo "FAIL (but we can live with it)"
|
||||
USE_CFLAGS="$BASIC_CFLAGS"
|
||||
USE_LDFLAGS="$BASIC_LDFLAGS"
|
||||
|
||||
else
|
||||
|
||||
echo "OK"
|
||||
|
||||
fi
|
||||
|
||||
echo -n "[*] Checking if memory alignment is required... "
|
||||
|
||||
rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
|
||||
|
||||
echo -e "#include \"types.h\"\nvolatile u8 tmp[6]; int main() { printf(\"%d\x5cn\", *(u32*)(tmp+1)); return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
|
||||
echo "FAIL"
|
||||
echo
|
||||
echo "Well, something went horribly wrong, sorry. Here's the output from GCC:"
|
||||
echo
|
||||
cat "$TMP.log"
|
||||
echo
|
||||
echo "Sorry! You may want to ping <lcamtuf@coredump.cx> about this."
|
||||
echo
|
||||
rm -f "$TMP.log"
|
||||
exit 1
|
||||
|
||||
else
|
||||
|
||||
ulimit -c 0 &>/dev/null
|
||||
./"$TMP" &>/dev/null
|
||||
|
||||
if [ "$?" = "0" ]; then
|
||||
|
||||
echo "nope"
|
||||
|
||||
else
|
||||
|
||||
echo "yes"
|
||||
USE_CFLAGS="$USE_CFLAGS -DALIGN_ACCESS=1"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
|
||||
echo -n "[*] Checking for working libpcap... "
|
||||
|
||||
rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
|
||||
|
||||
echo -e "#include <pcap.h>\nint main() { char i[PCAP_ERRBUF_SIZE]; pcap_lookupdev(i); return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
echo "FAIL"
|
||||
echo
|
||||
|
||||
if [ "$OSTYPE" = "cygwin" ]; then
|
||||
|
||||
echo "You need a functioning install of winpcap. Download both of those:"
|
||||
echo
|
||||
echo " Main library : http://www.winpcap.org/install/default.htm"
|
||||
echo " Developer tools : http://www.winpcap.org/devel.htm"
|
||||
echo
|
||||
echo "Under cygwin, copy the contents of wpdpack/include to /usr/include/, and"
|
||||
echo "wpdpack/lib to /lib/. At that point, you should be able to build p0f."
|
||||
echo
|
||||
|
||||
else
|
||||
|
||||
echo "You need a functioning installation of libpcap (including development headers)."
|
||||
echo "You can download it from here:"
|
||||
echo
|
||||
echo " http://www.tcpdump.org/#latest-release"
|
||||
echo
|
||||
|
||||
fi
|
||||
|
||||
echo "If you have the library installed at an unorthodox location, try setting CFLAGS"
|
||||
echo "and LDFLAGS to point us in the right direction."
|
||||
echo
|
||||
echo "Output from an attempt to compile sample program:"
|
||||
cat "$TMP.log" | head -10
|
||||
echo
|
||||
rm -f "$TMP" "$TMP.log" "$TMP.c"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
echo -n "[*] Checking for working BPF... "
|
||||
|
||||
rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
|
||||
|
||||
echo -e "#include <pcap.h>\n#include <pcap-bpf.h>\nint main() { return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
|
||||
rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
|
||||
|
||||
echo -e "#include <pcap.h>\n#include <net/bpf.h>\nint main() { return 0; }" >"$TMP.c" || exit 1
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$TMP" ]; then
|
||||
echo "FAIL"
|
||||
echo
|
||||
echo "Could not find a working version of pcap-bpf.h or net/bpf.h on your system."
|
||||
echo "If it's available in a non-standard directory, set CFLAGS accordingly; if it"
|
||||
echo "lives under a different name, you may need to edit the source and recompile."
|
||||
echo
|
||||
|
||||
rm -f "$TMP" "$TMP.log" "$TMP.c"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
USE_CFLAGS="$USE_CFLAGS -DNET_BPF=1"
|
||||
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
rm -f "$TMP" "$TMP.log" "$TMP.c" || exit 1
|
||||
|
||||
echo "[+] Okay, you seem to be good to go. Fingers crossed!"
|
||||
|
||||
echo -n "[*] Compiling $PROGNAME... "
|
||||
|
||||
rm -f "$PROGNAME" || exit 1
|
||||
|
||||
$CC $USE_CFLAGS $USE_LDFLAGS "$PROGNAME.c" $OBJFILES -o "$PROGNAME" $USE_LIBS &>"$TMP.log"
|
||||
|
||||
if [ ! -x "$PROGNAME" ]; then
|
||||
|
||||
echo "FAIL"
|
||||
echo
|
||||
echo "Well, something went horribly wrong, sorry. Here's the output from GCC:"
|
||||
echo
|
||||
cat "$TMP.log"
|
||||
echo
|
||||
echo "Sorry! You may want to ping <lcamtuf@coredump.cx> about this."
|
||||
echo
|
||||
rm -f "$TMP.log"
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
if [ -s "$TMP.log" ]; then
|
||||
|
||||
echo "OK (see COMPILER-WARNINGS)"
|
||||
mv "$TMP.log" COMPILER-WARNINGS
|
||||
|
||||
test "$1" = "debug" && cat COMPILER-WARNINGS
|
||||
|
||||
else
|
||||
|
||||
rm -f "$TMP.log"
|
||||
echo "OK"
|
||||
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Well, that's it. Be sure to review README. If you run into any problems, you"
|
||||
echo "can reach the author at <lcamtuf@coredump.cx>."
|
||||
echo
|
||||
|
||||
exit 0
|
271
docker/p0f/config.h
Normal file
271
docker/p0f/config.h
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
p0f - vaguely configurable bits
|
||||
-------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_CONFIG_H
|
||||
#define _HAVE_CONFIG_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/********************************************
|
||||
* Things you may reasonably want to change *
|
||||
********************************************/
|
||||
|
||||
/* Default location of p0f.fp: */
|
||||
|
||||
#ifndef FP_FILE
|
||||
# define FP_FILE "p0f.fp"
|
||||
#endif /* !FP_FILE */
|
||||
|
||||
/* Initial permissions on log files: */
|
||||
|
||||
#ifndef LOG_MODE
|
||||
# define LOG_MODE 0600
|
||||
#endif /* !LOG_MODE */
|
||||
|
||||
/* Initial permissions on API sockets: */
|
||||
|
||||
#ifndef API_MODE
|
||||
# define API_MODE 0666
|
||||
#endif /* !API_MODE */
|
||||
|
||||
/* Default connection and host cache sizes (adjustable via -m): */
|
||||
|
||||
#ifndef MAX_HOSTS
|
||||
# define MAX_CONN 1000
|
||||
# define MAX_HOSTS 10000
|
||||
#endif /* !MAX_HOSTS */
|
||||
|
||||
/* Default connection and host time limits (adjustable via -t): */
|
||||
|
||||
#ifndef HOST_IDLE_LIMIT
|
||||
# define CONN_MAX_AGE 30 /* seconds */
|
||||
# define HOST_IDLE_LIMIT 120 /* minutes */
|
||||
#endif /* !HOST_IDLE_LIMIT */
|
||||
|
||||
/* Default number of API connections permitted (adjustable via -c): */
|
||||
|
||||
#ifndef API_MAX_CONN
|
||||
# define API_MAX_CONN 20
|
||||
#endif /* !API_MAX_CONN */
|
||||
|
||||
/* Maximum TTL distance for non-fuzzy signature matching: */
|
||||
|
||||
#ifndef MAX_DIST
|
||||
# define MAX_DIST 35
|
||||
#endif /* !MAX_DIST */
|
||||
|
||||
/* Detect use-after-free, at the expense of some performance cost: */
|
||||
|
||||
#define CHECK_UAF 1
|
||||
|
||||
/************************
|
||||
* Really obscure stuff *
|
||||
************************/
|
||||
|
||||
/* Maximum allocator request size (keep well under INT_MAX): */
|
||||
|
||||
#define MAX_ALLOC 0x40000000
|
||||
|
||||
/* Percentage of host entries / flows to prune when limits exceeded: */
|
||||
|
||||
#define KILL_PERCENT 10
|
||||
|
||||
/* PCAP snapshot length: */
|
||||
|
||||
#define SNAPLEN 65535
|
||||
|
||||
/* Maximum request, response size to keep per flow: */
|
||||
|
||||
#define MAX_FLOW_DATA 8192
|
||||
|
||||
/* Maximum number of TCP options we will process (< 256): */
|
||||
|
||||
#define MAX_TCP_OPT 24
|
||||
|
||||
/* Minimum and maximum frequency for timestamp clock (Hz). Note that RFC
|
||||
1323 permits 1 - 1000 Hz . At 1000 Hz, the 32-bit counter overflows
|
||||
after about 50 days. */
|
||||
|
||||
#define MIN_TSCALE 0.7
|
||||
#define MAX_TSCALE 1500
|
||||
|
||||
/* Minimum and maximum interval (ms) for measuring timestamp progrssion. This
|
||||
is used to make sure the timestamps are fresh enough to be of any value,
|
||||
and that the measurement is not affected by network performance too
|
||||
severely. */
|
||||
|
||||
#define MIN_TWAIT 25
|
||||
#define MAX_TWAIT (1000 * 60 * 10)
|
||||
|
||||
/* Time window in which to tolerate timestamps going back slightly or
|
||||
otherwise misbehaving during NAT checks (ms): */
|
||||
|
||||
#define TSTAMP_GRACE 100
|
||||
|
||||
/* Maximum interval between packets used for TS-based NAT checks (ms): */
|
||||
|
||||
#define MAX_NAT_TS (1000 * 60 * 60 * 24)
|
||||
|
||||
/* Minimum port drop to serve as a NAT detection signal: */
|
||||
|
||||
#define MIN_PORT_DROP 64
|
||||
|
||||
/* Threshold before letting NAT detection make a big deal out of TTL change
|
||||
for remote hosts (this is to account for peering changes): */
|
||||
|
||||
#define SMALL_TTL_CHG 2
|
||||
|
||||
/* The distance up to which the system is considered to be local, and therefore
|
||||
the SMALL_TTL_CHG threshold should not be taken account: */
|
||||
|
||||
#define LOCAL_TTL_LIMIT 5
|
||||
|
||||
/* The distance past which the system is considered to be really distant,
|
||||
and therefore, changes within SMALL_TTL_CHG should be completely ignored: */
|
||||
|
||||
#define NEAR_TTL_LIMIT 9
|
||||
|
||||
/* Number of packet scores to keep for NAT detection (< 256): */
|
||||
|
||||
#define NAT_SCORES 32
|
||||
|
||||
/* Number of hash buckets for p0f.fp signatures: */
|
||||
|
||||
#define SIG_BUCKETS 64
|
||||
|
||||
/* Number of hash buckets for active connections: */
|
||||
|
||||
#define FLOW_BUCKETS 256
|
||||
|
||||
/* Number of hash buckets for host data: */
|
||||
|
||||
#define HOST_BUCKETS 1024
|
||||
|
||||
/* Cache expiration interval (every n packets received): */
|
||||
|
||||
#define EXPIRE_INTERVAL 50
|
||||
|
||||
/* Non-alphanumeric chars to permit in OS names. This is to allow 'sys' syntax
|
||||
to be used unambiguously, yet allow some freedom: */
|
||||
|
||||
#define NAME_CHARS " ./-_!?()"
|
||||
|
||||
/* Special window size and MSS used by p0f-sendsyn, and detected by p0f: */
|
||||
|
||||
#define SPECIAL_MSS 1331
|
||||
#define SPECIAL_WIN 1337
|
||||
|
||||
/* Maximum length of an HTTP URL line we're willing to entertain. The same
|
||||
limit is also used for the first line of a response: */
|
||||
|
||||
#define HTTP_MAX_URL 1024
|
||||
|
||||
/* Maximum number of HTTP headers: */
|
||||
|
||||
#define HTTP_MAX_HDRS 32
|
||||
|
||||
/* Maximum length of a header name: */
|
||||
|
||||
#define HTTP_MAX_HDR_NAME 32
|
||||
|
||||
/* Maximum length of a header value: */
|
||||
|
||||
#define HTTP_MAX_HDR_VAL 1024
|
||||
|
||||
/* Maximum length of a header value for display purposes: */
|
||||
|
||||
#define HTTP_MAX_SHOW 200
|
||||
|
||||
/* Maximum HTTP 'Date' progression jitter to overlook (s): */
|
||||
|
||||
#define HTTP_MAX_DATE_DIFF 10
|
||||
|
||||
#ifdef _FROM_FP_HTTP
|
||||
|
||||
#include "fp_http.h"
|
||||
|
||||
/* Headers that should be tagged as optional by the HTTP fingerprinter in any
|
||||
generated signatures: */
|
||||
|
||||
static struct http_id req_optional[] = {
|
||||
{ "Cookie", 0 },
|
||||
{ "Referer", 0 },
|
||||
{ "Origin", 0 },
|
||||
{ "Range", 0 },
|
||||
{ "If-Modified-Since", 0 },
|
||||
{ "If-None-Match", 0 },
|
||||
{ "Via", 0 },
|
||||
{ "X-Forwarded-For", 0 },
|
||||
{ "Authorization", 0 },
|
||||
{ "Proxy-Authorization", 0 },
|
||||
{ "Cache-Control", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static struct http_id resp_optional[] = {
|
||||
{ "Set-Cookie", 0 },
|
||||
{ "Last-Modified", 0 },
|
||||
{ "ETag", 0 },
|
||||
{ "Content-Length", 0 },
|
||||
{ "Content-Disposition", 0 },
|
||||
{ "Cache-Control", 0 },
|
||||
{ "Expires", 0 },
|
||||
{ "Pragma", 0 },
|
||||
{ "Location", 0 },
|
||||
{ "Refresh", 0 },
|
||||
{ "Content-Range", 0 },
|
||||
{ "Vary", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/* Common headers that are expected to be present at all times, and deserve
|
||||
a special mention if absent in a signature: */
|
||||
|
||||
static struct http_id req_common[] = {
|
||||
{ "Host", 0 },
|
||||
{ "User-Agent", 0 },
|
||||
{ "Connection", 0 },
|
||||
{ "Accept", 0 },
|
||||
{ "Accept-Encoding", 0 },
|
||||
{ "Accept-Language", 0 },
|
||||
{ "Accept-Charset", 0 },
|
||||
{ "Keep-Alive", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static struct http_id resp_common[] = {
|
||||
{ "Content-Type", 0 },
|
||||
{ "Connection", 0 },
|
||||
{ "Keep-Alive", 0 },
|
||||
{ "Accept-Ranges", 0 },
|
||||
{ "Date", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/* Headers for which values change depending on the context, and therefore
|
||||
should not be included in proposed signatures. This is on top of the
|
||||
"optional" header lists, which already implies skipping the value. */
|
||||
|
||||
static struct http_id req_skipval[] = {
|
||||
{ "Host", 0 },
|
||||
{ "User-Agent", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static struct http_id resp_skipval[] = {
|
||||
{ "Date", 0 },
|
||||
{ "Content-Type", 0 },
|
||||
{ "Server", 0 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
#endif /* _FROM_FP_HTTP */
|
||||
|
||||
#endif /* ! _HAVE_CONFIG_H */
|
54
docker/p0f/debug.h
Normal file
54
docker/p0f/debug.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
p0f - debug / error handling macros
|
||||
-----------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_DEBUG_H
|
||||
#define _HAVE_DEBUG_H
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
# define DEBUG(x...) fprintf(stderr, x)
|
||||
#else
|
||||
# define DEBUG(x...) do {} while (0)
|
||||
#endif /* ^DEBUG_BUILD */
|
||||
|
||||
#define ERRORF(x...) fprintf(stderr, x)
|
||||
#define SAYF(x...) printf(x)
|
||||
|
||||
#define WARN(x...) do { \
|
||||
ERRORF("[!] WARNING: " x); \
|
||||
ERRORF("\n"); \
|
||||
} while (0)
|
||||
|
||||
#define FATAL(x...) do { \
|
||||
ERRORF("[-] PROGRAM ABORT : " x); \
|
||||
ERRORF("\n Location : %s(), %s:%u\n\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
#define ABORT(x...) do { \
|
||||
ERRORF("[-] PROGRAM ABORT : " x); \
|
||||
ERRORF("\n Location : %s(), %s:%u\n\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#define PFATAL(x...) do { \
|
||||
ERRORF("[-] SYSTEM ERROR : " x); \
|
||||
ERRORF("\n Location : %s(), %s:%u\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
perror(" OS message "); \
|
||||
ERRORF("\n"); \
|
||||
exit(1); \
|
||||
} while (0)
|
||||
|
||||
#endif /* ! _HAVE_DEBUG_H */
|
498
docker/p0f/docs/COPYING
Normal file
498
docker/p0f/docs/COPYING
Normal file
@ -0,0 +1,498 @@
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
128
docker/p0f/docs/ChangeLog
Normal file
128
docker/p0f/docs/ChangeLog
Normal file
@ -0,0 +1,128 @@
|
||||
Version 3.09b:
|
||||
--------------
|
||||
|
||||
- Fixed a likely only cosmetic bug with a one-byte overread of the pcap
|
||||
packet buffer, which would cause an error under ASAN. Spotted by
|
||||
Xavid Pretzer.
|
||||
|
||||
- Added a new signature for Chrome.
|
||||
|
||||
- Updated another signature for Chrome.
|
||||
|
||||
Version 3.08b:
|
||||
--------------
|
||||
|
||||
- An awful fix for a packet loss bug (probably kernel or libpcap-related)
|
||||
with some VMs.
|
||||
|
||||
- Improvement to avoid warnings with -r.
|
||||
|
||||
Version 3.07b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Improvement to API handling to avoid FATAL() on short API reads & writes.
|
||||
|
||||
- Minor bug fix to IP parsing in one of the companion utilities.
|
||||
|
||||
Improvements:
|
||||
|
||||
- New signatures.
|
||||
|
||||
Version 3.06b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Made os_match_q actually functional in api.c (thanks to Anthony Howe).
|
||||
|
||||
- Fixed api.c struct packing issue (thanks to Tomoyuki Murakami).
|
||||
|
||||
- Improved logic around the vlan behavior (thanks to Anthony Howe).
|
||||
|
||||
Version 3.05b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Cleaned up hash.h to avoid pointless OOB reads, alignment issues.
|
||||
|
||||
- Fixed divide-by-zero in MSS calculations
|
||||
|
||||
Version 3.04b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Fixed a realloc bug (not normally triggered in p0f)
|
||||
|
||||
Version 3.03b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Potential NULL ptr in p0f-client on some 64-bit systems.
|
||||
|
||||
Version 3.02b:
|
||||
--------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Cygwin compile issue fixed.
|
||||
|
||||
Improvements:
|
||||
|
||||
- New signatures.
|
||||
|
||||
Version 3.01b (2012-01-17):
|
||||
---------------------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- 'Date' comparisons for server sigs now work as expected.
|
||||
|
||||
- Bad TS reading now allowed on initial SYN (improves uptime detection).
|
||||
|
||||
Improvements:
|
||||
|
||||
- New signatures.
|
||||
|
||||
- Solaris support (in theory).
|
||||
|
||||
Version 3.00b (2012-01-17):
|
||||
---------------------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- Alignment-related SIGBUS non-x86 fixed.
|
||||
|
||||
- Cache expiration algorithm now works as expected.
|
||||
|
||||
- p0f -L no longer leads to NULL ptr when no interfaces visible.
|
||||
|
||||
- Greppable output format no longer mixes up cli and srv fields.
|
||||
|
||||
- Added '|' to banned characters in reported header values.
|
||||
|
||||
Improvements:
|
||||
|
||||
- Multiple new HTTP and TCP signatures.
|
||||
|
||||
- Improved MSS/MTU matching to account for peer MTU.
|
||||
|
||||
- New HTTP fingerprinting logic with optional headers (? prefix).
|
||||
|
||||
- Memory leak detection added (but nothing found).
|
||||
|
||||
- API now indicates the value of 'generic' / 'fuzzy' fields and several
|
||||
other parameters.
|
||||
|
||||
- General style improvements.
|
||||
|
||||
- Delay added to p0f-sendsyn to aid with packet ordering.
|
||||
|
||||
Version 3.00-rc0 (2012-01-10):
|
||||
------------------------------
|
||||
|
||||
- Initial public release, complete rewrite.
|
916
docker/p0f/docs/README
Normal file
916
docker/p0f/docs/README
Normal file
@ -0,0 +1,916 @@
|
||||
=============================
|
||||
p0f v3: passive fingerprinter
|
||||
=============================
|
||||
|
||||
http://lcamtuf.coredump.cx/p0f3.shtml
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
|
||||
---------------
|
||||
1. What's this?
|
||||
---------------
|
||||
|
||||
P0f is a tool that utilizes an array of sophisticated, purely passive traffic
|
||||
fingerprinting mechanisms to identify the players behind any incidental TCP/IP
|
||||
communications (often as little as a single normal SYN) without interfering in
|
||||
any way.
|
||||
|
||||
Some of its capabilities include:
|
||||
|
||||
- Highly scalable and extremely fast identification of the operating system
|
||||
and software on both endpoints of a vanilla TCP connection - especially in
|
||||
settings where NMap probes are blocked, too slow, unreliable, or would
|
||||
simply set off alarms,
|
||||
|
||||
- Measurement of system uptime and network hookup, distance (including
|
||||
topology behind NAT or packet filters), and so on.
|
||||
|
||||
- Automated detection of connection sharing / NAT, load balancing, and
|
||||
application-level proxying setups.
|
||||
|
||||
- Detection of dishonest clients / servers that forge declarative statements
|
||||
such as X-Mailer or User-Agent.
|
||||
|
||||
The tool can be operated in the foreground or as a daemon, and offers a simple
|
||||
real-time API for third-party components that wish to obtain additional
|
||||
information about the actors they are talking to.
|
||||
|
||||
Common uses for p0f include reconnaissance during penetration tests; routine
|
||||
network monitoring; detection of unauthorized network interconnects in corporate
|
||||
environments; providing signals for abuse-prevention tools; and miscellanous
|
||||
forensics.
|
||||
|
||||
A snippet of typical p0f output may look like this:
|
||||
|
||||
.-[ 1.2.3.4/1524 -> 4.3.2.1/80 (syn) ]-
|
||||
|
|
||||
| client = 1.2.3.4
|
||||
| os = Windows XP
|
||||
| dist = 8
|
||||
| params = none
|
||||
| raw_sig = 4:120+8:0:1452:65535,0:mss,nop,nop,sok:df,id+:0
|
||||
|
|
||||
`----
|
||||
|
||||
.-[ 1.2.3.4/1524 -> 4.3.2.1/80 (syn+ack) ]-
|
||||
|
|
||||
| server = 4.3.2.1
|
||||
| os = Linux 3.x
|
||||
| dist = 0
|
||||
| params = none
|
||||
| raw_sig = 4:64+0:0:1460:mss*10,0:mss,nop,nop,sok:df:0
|
||||
|
|
||||
`----
|
||||
|
||||
.-[ 1.2.3.4/1524 -> 4.3.2.1/80 (mtu) ]-
|
||||
|
|
||||
| client = 1.2.3.4
|
||||
| link = DSL
|
||||
| raw_mtu = 1492
|
||||
|
|
||||
`----
|
||||
|
||||
.-[ 1.2.3.4/1524 -> 4.3.2.1/80 (uptime) ]-
|
||||
|
|
||||
| client = 1.2.3.4
|
||||
| uptime = 0 days 11 hrs 16 min (modulo 198 days)
|
||||
| raw_freq = 250.00 Hz
|
||||
|
|
||||
`----
|
||||
|
||||
A live demonstration can be seen here:
|
||||
|
||||
http://lcamtuf.coredump.cx/p0f3/
|
||||
|
||||
--------------------
|
||||
2. How does it work?
|
||||
--------------------
|
||||
|
||||
A vast majority of metrics used by p0f were invented specifically for this tool,
|
||||
and include data extracted from IPv4 and IPv6 headers, TCP headers, the dynamics
|
||||
of the TCP handshake, and the contents of application-level payloads.
|
||||
|
||||
For TCP/IP, the tool fingerprints the client-originating SYN packet and the
|
||||
first SYN+ACK response from the server, paying attention to factors such as the
|
||||
ordering of TCP options, the relation between maximum segment size and window
|
||||
size, the progression of TCP timestamps, and the state of about a dozen possible
|
||||
implementation quirks (e.g. non-zero values in "must be zero" fields).
|
||||
|
||||
The metrics used for application-level traffic vary from one module to another;
|
||||
where possible, the tool relies on signals such as the ordering or syntax of
|
||||
HTTP headers or SMTP commands, rather than any declarative statements such as
|
||||
User-Agent. Application-level fingerprinting modules currently support HTTP.
|
||||
Before the tool leaves "beta", I want to add SMTP and FTP. Other protocols,
|
||||
such as FTP, POP3, IMAP, SSH, and SSL, may follow.
|
||||
|
||||
The list of all the measured parameters is reviewed in section 5 later on.
|
||||
Some of the analysis also happens on a higher level: inconsistencies in the
|
||||
data collected from various sources, or in the data from the same source
|
||||
obtained over time, may be indicative of address translation, proxying, or
|
||||
just plain trickery. For example, a system where TCP timestamps jump back
|
||||
and forth, or where TTLs and MTUs change subtly, is probably a NAT device.
|
||||
|
||||
-------------------------------
|
||||
3. How do I compile and use it?
|
||||
-------------------------------
|
||||
|
||||
To compile p0f, try running './build.sh'; if that fails, you will be probably
|
||||
given some tips about the probable cause. If the tips are useless, send me a
|
||||
mean-spirited mail.
|
||||
|
||||
It is also possible to build a debug binary ('./build.sh debug'), in which case,
|
||||
verbose packet parsing and signature matching information will be written to
|
||||
stderr. This is useful when troubleshooting problems, but that's about it.
|
||||
|
||||
The tool should compile cleanly under any reasonably new version of Linux,
|
||||
FreeBSD, OpenBSD, MacOS X, and so forth. You can also builtdit on Windows using
|
||||
cygwin and winpcap. I have not tested it on all possible varieties of un*x, but
|
||||
if there are issues, they should be fairly superficial.
|
||||
|
||||
Once you have the binary compiled, you should be aware of the following
|
||||
command-line options:
|
||||
|
||||
-f fname - reads fingerprint database (p0f.fp) from the specified location.
|
||||
See section 5 for more information about the contents of this
|
||||
file.
|
||||
|
||||
The default location is ./p0f.fp. If you want to install p0f, you
|
||||
may want to change FP_FILE in config.h to /etc/p0f.fp.
|
||||
|
||||
-i iface - asks p0f to listen on a specific network interface. On un*x, you
|
||||
should reference the interface by name (e.g., eth0). On Windows,
|
||||
you can use adapter index instead (0, 1, 2...).
|
||||
|
||||
Multiple -i parameters are not supported; you need to run
|
||||
separate instances of p0f for that. On Linux, you can specify
|
||||
'any' to access a pseudo-device that combines the traffic on
|
||||
all other interfaces; the only limitation is that libpcap will
|
||||
not recognize VLAN-tagged frames in this mode, which may be
|
||||
an issue in some of the more exotic setups.
|
||||
|
||||
If you do not specify an interface, libpcap will probably pick
|
||||
the first working interface in your system.
|
||||
|
||||
-L - lists all available network interfaces, then quits. Particularly
|
||||
useful on Windows, where the system-generated interface names
|
||||
are impossible to memorize.
|
||||
|
||||
-r fname - instead of listening for live traffic, reads pcap captures from
|
||||
the specified file. The data can be collected with tcpdump or any
|
||||
other compatible tool. Make sure that snapshot length (-s
|
||||
option in tcpdump) is large enough not to truncate packets; the
|
||||
default may be too small.
|
||||
|
||||
As with -i, only one -r option can be specified at any given
|
||||
time.
|
||||
|
||||
-o fname - appends grep-friendly log data to the specified file. The log
|
||||
contains all observations made by p0f about every matching
|
||||
connection, and may grow large; plan accordingly.
|
||||
|
||||
Only one instance of p0f should be writing to a particular file
|
||||
at any given time; where supported, advisory locking is used to
|
||||
avoid problems.
|
||||
|
||||
-s fname - listens for API queries on the specified filesystem socket. This
|
||||
allows other programs to ask p0f about its current thoughts about
|
||||
a particular host. More information about the API protocol can be
|
||||
found in section 4 below.
|
||||
|
||||
Only one instance of p0f can be listening on a particular socket
|
||||
at any given time. The mode is also incompatible with -r.
|
||||
|
||||
-d - runs p0f in daemon mode: the program will fork into background
|
||||
and continue writing to the specified log file or API socket. It
|
||||
will continue running until killed, until the listening interface
|
||||
is shut down, or until some other fatal error is encountered.
|
||||
|
||||
This mode requires either -o or -s to be specified.
|
||||
|
||||
To continue capturing p0f debug output and error messages (but
|
||||
not signatures), redirect stderr to another non-TTY destination,
|
||||
e.g.:
|
||||
|
||||
./p0f -o /var/log/p0f.log -d 2>>/var/log/p0f.error
|
||||
|
||||
Note that if -d is specified and stderr points to a TTY, error
|
||||
messages will be lost.
|
||||
|
||||
-u user - causes p0f to drop privileges, switching to the specified user
|
||||
and chroot()ing itself to said user's home directory.
|
||||
|
||||
This mode is *highly* advisable (but not required) on un*x
|
||||
systems, especially in daemon mode. See section 7 for more info.
|
||||
|
||||
More arcane settings (you probably don't need to touch these):
|
||||
|
||||
-j - Log in JSON format.
|
||||
|
||||
-l - Line buffered mode for logging to output file.
|
||||
|
||||
-p - puts the interface specified with -i in promiscuous mode. If
|
||||
supported by the firmware, the card will also process frames not
|
||||
addressed to it.
|
||||
|
||||
-S num - sets the maximum number of simultaneous API connections. The
|
||||
default is 20; the upper cap is 100.
|
||||
|
||||
-m c,h - sets the maximum number of connections (c) and hosts (h) to be
|
||||
tracked at the same time (default: c = 1,000, h = 10,000). Once
|
||||
the limit is reached, the oldest 10% entries gets pruned to make
|
||||
room for new data.
|
||||
|
||||
This setting effectively controls the memory footprint of p0f.
|
||||
The cost of tracking a single host is under 400 bytes; active
|
||||
connections have a worst-case footprint of about 18 kB. High
|
||||
limits have some CPU impact, too, by the virtue of complicating
|
||||
data lookups in the cache.
|
||||
|
||||
NOTE: P0f tracks connections only until the handshake is done,
|
||||
and if protocol-level fingerprinting is possible, until few
|
||||
initial kilobytes of data have been exchanged. This means that
|
||||
most connections are dropped from the cache in under 5 seconds;
|
||||
consequently, the 'c' variable can be much lower than the real
|
||||
number of parallel connections happening on the wire.
|
||||
|
||||
-t c,h - sets the timeout for collecting signatures for any connection
|
||||
(c); and for purging idle hosts from in-memory cache (h). The
|
||||
first parameter is given in seconds, and defaults to 30 s; the
|
||||
second one is in minutes, and defaults to 120 min.
|
||||
|
||||
The first value must be just high enough to reliably capture
|
||||
SYN, SYN+ACK, and the initial few kB of traffic. Low-performance
|
||||
sites may want to increase it slightly.
|
||||
|
||||
The second value governs for how long API queries about a
|
||||
previously seen host can be made; and what's the maximum interval
|
||||
between signatures to still trigger NAT detection and so on.
|
||||
Raising it is usually not advisable; lowering it to 5-10 minutes
|
||||
may make sense for high-traffic servers, where it is possible to
|
||||
see several unrelated visitors subsequently obtaining the same
|
||||
dynamic IP from their ISP.
|
||||
|
||||
Well, that's about it. You probably need to run the tool as root. Some of the
|
||||
most common use cases:
|
||||
|
||||
# ./p0f -i eth0
|
||||
|
||||
# ./p0f -i eth0 -d -u p0f-user -o /var/log/p0f.log
|
||||
|
||||
# ./p0f -r some_capture.cap
|
||||
|
||||
The greppable log format (-o) uses pipe ('|') as a delimiter, with name=value
|
||||
pairs describing the signature in a manner very similar to the pretty-printed
|
||||
output generated on stdout:
|
||||
|
||||
[2012/01/04 10:26:14] mod=mtu|cli=1.2.3.4/1234|srv=4.3.2.1/80|subj=cli|link=DSL|raw_mtu=1492
|
||||
|
||||
The 'mod' parameter identifies the subsystem that generated the entry; the
|
||||
'cli' and 'srv' parameters always describe the direction in which the TCP
|
||||
session is established; and 'subj' describes which of these two parties is
|
||||
actually being fingerprinted.
|
||||
|
||||
Command-line options may be followed by a single parameter containing a
|
||||
pcap-style traffic filtering rule. This allows you to reject some of the less
|
||||
interesting packets for performance or privacy reasons. Simple examples include:
|
||||
|
||||
'dst net 10.0.0.0/8 and port 80'
|
||||
|
||||
'not src host 10.1.2.3'
|
||||
|
||||
'port 22 or port 443'
|
||||
|
||||
You can read more about the supported syntax by doing 'man pcap-fiter'; if
|
||||
that fails, try this URL:
|
||||
|
||||
http://www.manpagez.com/man/7/pcap-filter/
|
||||
|
||||
Filters work both for online capture (-i) and for previously collected data
|
||||
produced by any other tool (-r).
|
||||
|
||||
-------------
|
||||
4. API access
|
||||
-------------
|
||||
|
||||
The API allows other applications running on the same system to get p0f's
|
||||
current opinion about a particular host. This is useful for integrating it with
|
||||
spam filters, web apps, and so on.
|
||||
|
||||
Clients are welcome to connect to the unix socket specified with -s using the
|
||||
SOCK_STREAM protocol, and may issue any number of fixed-length queries. The
|
||||
queries will be answered in the order they are received.
|
||||
|
||||
Note that there is no response caching, nor any software limits in place on p0f
|
||||
end, so it is your responsibility to write reasonably well-behaved clients.
|
||||
|
||||
Queries have exactly 21 bytes. The format is:
|
||||
|
||||
- Magic dword (0x50304601), in native endian of the platform.
|
||||
|
||||
- Address type byte: 4 for IPv4, 6 for IPv6.
|
||||
|
||||
- 16 bytes of address data, network endian. IPv4 addresses should be
|
||||
aligned to the left.
|
||||
|
||||
To such a query, p0f responds with:
|
||||
|
||||
- Another magic dword (0x50304602), native endian.
|
||||
|
||||
- Status dword: 0x00 for 'bad query', 0x10 for 'OK', and 0x20 for 'no match'.
|
||||
|
||||
- Host information, valid only if status is 'OK' (byte width in square
|
||||
brackets):
|
||||
|
||||
[4] first_seen - unix time (seconds) of first observation of the host.
|
||||
|
||||
[4] last_seen - unix time (seconds) of most recent traffic.
|
||||
|
||||
[4] total_conn - total number of connections seen.
|
||||
|
||||
[4] uptime_min - calculated system uptime, in minutes. Zero if not known.
|
||||
|
||||
[4] up_mod_days - uptime wrap-around interval, in days.
|
||||
|
||||
[4] last_nat - time of the most recent detection of IP sharing (NAT,
|
||||
load balancing, proxying). Zero if never detected.
|
||||
|
||||
[4] last_chg - time of the most recent individual OS mismatch (e.g.,
|
||||
due to multiboot or IP reuse).
|
||||
|
||||
[2] distance - system distance (derived from TTL; -1 if no data).
|
||||
|
||||
[1] bad_sw - p0f thinks the User-Agent or Server strings aren't
|
||||
accurate. The value of 1 means OS difference (possibly
|
||||
due to proxying), while 2 means an outright mismatch.
|
||||
|
||||
NOTE: If User-Agent is not present at all, this value
|
||||
stays at 0.
|
||||
|
||||
[1] os_match_q - OS match quality: 0 for a normal match; 1 for fuzzy
|
||||
(e.g., TTL or DF difference); 2 for a generic signature;
|
||||
and 3 for both.
|
||||
|
||||
[32] os_name - NUL-terminated name of the most recent positively matched
|
||||
OS. If OS not known, os_name[0] is NUL.
|
||||
|
||||
NOTE: If the host is first seen using an known system and
|
||||
then switches to an unknown one, this field is not
|
||||
reset.
|
||||
|
||||
[32] os_flavor - OS version. May be empty if no data.
|
||||
|
||||
[32] http_name - most recent positively identified HTTP application
|
||||
(e.g. 'Firefox').
|
||||
|
||||
[32] http_flavor - version of the HTTP application, if any.
|
||||
|
||||
[32] link_type - network link type, if recognized.
|
||||
|
||||
[32] language - system language, if recognized.
|
||||
|
||||
A simple reference implementation of an API client is provided in p0f-client.c.
|
||||
Implementations in C / C++ may reuse api.h from p0f source code, too.
|
||||
|
||||
Developers using the API should be aware of several important constraints:
|
||||
|
||||
- The maximum number of simultaneous API connections is capped to 20. The
|
||||
limit may be adjusted with the -S parameter, but rampant parallelism may
|
||||
lead to poorly controlled latency; consider a single query pipeline,
|
||||
possibly with prioritization and caching.
|
||||
|
||||
- The maximum number of hosts and connections tracked at any given time is
|
||||
subject to configurable limits. You should look at your traffic stats and
|
||||
see if the defaults are suitable.
|
||||
|
||||
You should also keep in mind that whenever you are subject to an ongoing
|
||||
DDoS or SYN spoofing DoS attack, p0f may end up dropping entries faster
|
||||
than you could query for them. It's that or running out of memory, so
|
||||
don't fret.
|
||||
|
||||
- Cache entries with no activity for more than 120 minutes will be dropped
|
||||
even if the cache is nearly empty. The timeout is adjustable with -t, but
|
||||
you should not use the API to obtain ancient data; if you routinely need to
|
||||
go back hours or days, parse the logs instead of wasting RAM.
|
||||
|
||||
-----------------------
|
||||
5. Fingerprint database
|
||||
-----------------------
|
||||
|
||||
Whenever p0f obtains a fingerprint from the observed traffic, it defers to
|
||||
the data read from p0f.fp to identify the operating system and obtain some
|
||||
ancillary data needed for other analysis tasks. The fingerprint database is a
|
||||
simple text file where lines starting with ; are ignored.
|
||||
|
||||
== Module specification ==
|
||||
|
||||
The file is split into sections based on the type of traffic the fingerprints
|
||||
apply to. Section identifiers are enclosed in square brackets, like so:
|
||||
|
||||
[module:direction]
|
||||
|
||||
module - the name of the fingerprinting module (e.g. 'tcp' or 'http').
|
||||
|
||||
direction - the direction of fingerprinted traffic: 'request' (from client to
|
||||
server) or 'response' (from server to client).
|
||||
|
||||
For the TCP module, 'client' matches the initial SYN; and
|
||||
'server' matches SYN+ACK.
|
||||
|
||||
The 'direction' part is omitted for MTU signatures, as they work equally well
|
||||
both ways.
|
||||
|
||||
== Signature groups ==
|
||||
|
||||
The actual signatures must be preceeded by an 'label' line, describing the
|
||||
fingerprinted software:
|
||||
|
||||
label = type:class:name:flavor
|
||||
|
||||
type - some signatures in p0f.fp offer broad, last-resort matching for
|
||||
less researched corner cases. The goal there is to give an
|
||||
answer slightly better than "unknown", but less precise than
|
||||
what the user may be expecting.
|
||||
|
||||
Normal, reasonably specific signatures that can't be radically
|
||||
improved should have their type specified as 's'; while generic,
|
||||
last-resort ones should be tagged with 'g'.
|
||||
|
||||
Note that generic signatures are considered only if no specific
|
||||
matches are found in the database.
|
||||
|
||||
class - the tool needs to distinguish between OS-identifying signatures
|
||||
(only one of which should be matched for any given host) and
|
||||
signatures that just identify user applications (many of which
|
||||
may be seen concurrently).
|
||||
|
||||
To assist with this, OS-specific signatures should specify the
|
||||
OS architecture family here (e.g., 'win', 'unix', 'cisco'); while
|
||||
application-related sigs (NMap, MSIE, Apache) should use a
|
||||
special value of '!'.
|
||||
|
||||
Most TCP signatures are OS-specific, and should have OS family
|
||||
defined. Other signatures, such as HTTP, should use '!' unless
|
||||
the fingerprinted component is deeply intertwined with the
|
||||
platform (e.g., Windows Update).
|
||||
|
||||
NOTE: To avoid variations (e.g. 'win' and 'windows' or 'unix'
|
||||
and 'linux'), all classes need to be pre-registered using a
|
||||
'classes' directive, seen near the beginning of p0f.fp.
|
||||
|
||||
name - a human-readable short name for what the fingerprint actually
|
||||
helps identify - say, 'Linux', 'Sendmail', or 'NMap'. The tool
|
||||
doesn't care about the exact value, but requires consistency - so
|
||||
don't switch between 'Internet Explorer' and 'MSIE', or 'MacOS'
|
||||
and 'Mac OS'.
|
||||
|
||||
flavor - anything you want to say to further qualify the observation. Can
|
||||
be the version of the identified software, or a description of
|
||||
what the application seems to be doing (e.g. 'SYN scan' for NMap).
|
||||
|
||||
NOTE: Don't be too specific: if you have a signature for Apache
|
||||
2.2.16, but have no reason to suspect that other recent versions
|
||||
behave in a radically different way, just say '2.x'.
|
||||
|
||||
P0f uses labels to group similar signatures that may be plausibly generated by
|
||||
the same system or application, and should not be considered a strong signal for
|
||||
NAT detection.
|
||||
|
||||
To further assist the tool in deciding which OS and application combinations are
|
||||
reasonable, and which ones are indicative of foul play, any 'label' line for
|
||||
applications (class '!') should be followed by a comma-delimited list of OS
|
||||
names or @-prefixed OS architecture classes on which this software is known to
|
||||
be used on. For example:
|
||||
|
||||
label = s:!:Uncle John's Networked ls Utility:2.3.0.1
|
||||
sys = Linux,FreeBSD,OpenBSD
|
||||
|
||||
...or:
|
||||
|
||||
label = s:!:Mom's Homestyle Browser:1.x
|
||||
sys = @unix,@win
|
||||
|
||||
The label can be followed by any number of module-specific signatures; all of
|
||||
them will be linked to the most recent label, and will be reported the same
|
||||
way.
|
||||
|
||||
All sections except for 'name' are omitted for [mtu] signatures, which do not
|
||||
convey any OS-specific information, and just describe link types.
|
||||
|
||||
== MTU signatures ==
|
||||
|
||||
Many operating systems derive the maximum segment size specified in TCP options
|
||||
from the MTU of their network interface; that value, in turn, normally depends
|
||||
on the design of the link-layer protocol. A different MTU is associated with
|
||||
PPPoE, a different one with IPSec, and a different one with Juniper VPN.
|
||||
|
||||
The format of the signatures in the [mtu] section is exceedingly simple,
|
||||
consisting just of a description and a list of values:
|
||||
|
||||
label = Ethernet
|
||||
sig = 1500
|
||||
|
||||
These will be matched for any wildcard MSS TCP packets (see below) not generated
|
||||
by userspace TCP tools.
|
||||
|
||||
== TCP signatures ==
|
||||
|
||||
For TCP traffic, signature layout is as follows:
|
||||
|
||||
sig = ver:ittl:olen:mss:wsize,scale:olayout:quirks:pclass
|
||||
|
||||
ver - signature for IPv4 ('4'), IPv6 ('6'), or both ('*').
|
||||
|
||||
NEW SIGNATURES: P0f documents the protocol observed on the wire,
|
||||
but you should replace it with '*' unless you have observed some
|
||||
actual differences between IPv4 and IPv6 traffic, or unless the
|
||||
software supports only one of these versions to begin with.
|
||||
|
||||
ittl - initial TTL used by the OS. Almost all operating systems use
|
||||
64, 128, or 255; ancient versions of Windows sometimes used
|
||||
32, and several obscure systems sometimes resort to odd values
|
||||
such as 60.
|
||||
|
||||
NEW SIGNATURES: P0f will usually suggest something, using the
|
||||
format of 'observed_ttl+distance' (e.g. 54+10). Consider using
|
||||
traceroute to check that the distance is accurate, then sum up
|
||||
the values. If initial TTL can't be guessed, p0f will output
|
||||
'nnn+?', and you need to use traceroute to estimate the '?'.
|
||||
|
||||
A handful of userspace tools will generate random TTLs. In these
|
||||
cases, determine maximum initial TTL and then add a - suffix to
|
||||
the value to avoid confusion.
|
||||
|
||||
olen - length of IPv4 options or IPv6 extension headers. Usually zero
|
||||
for normal IPv4 traffic; always zero for IPv6 due to the
|
||||
limitations of libpcap.
|
||||
|
||||
NEW SIGNATURES: Copy p0f output literally.
|
||||
|
||||
mss - maximum segment size, if specified in TCP options. Special value
|
||||
of '*' can be used to denote that MSS varies depending on the
|
||||
parameters of sender's network link, and should not be a part of
|
||||
the signature. In this case, MSS will be used to guess the
|
||||
type of network hookup according to the [mtu] rules.
|
||||
|
||||
NEW SIGNATURES: Use '*' for any commodity OSes where MSS is
|
||||
around 1300 - 1500, unless you know for sure that it's fixed.
|
||||
If the value is outside that range, you can probably copy it
|
||||
literally.
|
||||
|
||||
wsize - window size. Can be expressed as a fixed value, but many
|
||||
operating systems set it to a multiple of MSS or MTU, or a
|
||||
multiple of some random integer. P0f automatically detects these
|
||||
cases, and allows notation such as 'mss*4', 'mtu*4', or '%8192'
|
||||
to be used. Wilcard ('*') is possible too.
|
||||
|
||||
NEW SIGNATURES: Copy p0f output literally. If frequent variations
|
||||
are seen, look for obvious patterns. If there are no patterns,
|
||||
'*' is a possible alternative.
|
||||
|
||||
scale - window scaling factor, if specified in TCP options. Fixed value
|
||||
or '*'.
|
||||
|
||||
NEW SIGNATURES: Copy literally, unless the value varies randomly.
|
||||
Many systems alter between 2 or 3 scaling factors, in which case,
|
||||
it's better to have several 'sig' lines, rather than a wildcard.
|
||||
|
||||
olayout - comma-delimited layout and ordering of TCP options, if any. This
|
||||
is one of the most valuable TCP fingerprinting signals. Supported
|
||||
values:
|
||||
|
||||
eol+n - explicit end of options, followed by n bytes of padding
|
||||
nop - no-op option
|
||||
mss - maximum segment size
|
||||
ws - window scaling
|
||||
sok - selective ACK permitted
|
||||
sack - selective ACK (should not be seen)
|
||||
ts - timestamp
|
||||
?n - unknown option ID n
|
||||
|
||||
NEW SIGNATURES: Copy this string literally.
|
||||
|
||||
quirks - comma-delimited properties and quirks observed in IP or TCP
|
||||
headers:
|
||||
|
||||
df - "don't fragment" set (probably PMTUD); ignored for IPv6
|
||||
id+ - DF set but IPID non-zero; ignored for IPv6
|
||||
id- - DF not set but IPID is zero; ignored for IPv6
|
||||
ecn - explicit congestion notification support
|
||||
0+ - "must be zero" field not zero; ignored for IPv6
|
||||
flow - non-zero IPv6 flow ID; ignored for IPv4
|
||||
|
||||
seq- - sequence number is zero
|
||||
ack+ - ACK number is non-zero, but ACK flag not set
|
||||
ack- - ACK number is zero, but ACK flag set
|
||||
uptr+ - URG pointer is non-zero, but URG flag not set
|
||||
urgf+ - URG flag used
|
||||
pushf+ - PUSH flag used
|
||||
|
||||
ts1- - own timestamp specified as zero
|
||||
ts2+ - non-zero peer timestamp on initial SYN
|
||||
opt+ - trailing non-zero data in options segment
|
||||
exws - excessive window scaling factor (> 14)
|
||||
bad - malformed TCP options
|
||||
|
||||
If a signature scoped to both IPv4 and IPv6 contains quirks valid
|
||||
for just one of these protocols, such quirks will be ignored for
|
||||
on packets using the other protocol. For example, any combination
|
||||
of 'df', 'id+', and 'id-' is always matched by any IPv6 packet.
|
||||
|
||||
NEW SIGNATURES: Copy literally.
|
||||
|
||||
pclass - payload size classification: '0' for zero, '+' for non-zero,
|
||||
'*' for any. The packets we fingerprint right now normally have
|
||||
no payloads, but some corner cases exist.
|
||||
|
||||
NEW SIGNATURES: Copy literally.
|
||||
|
||||
NOTE: The TCP module allows some fuzziness when an exact match can't be found:
|
||||
'df' and 'id+' quirks are allowed to disappear; 'id-' or 'ecn' may appear; and
|
||||
TTLs can change.
|
||||
|
||||
To gather new SYN ('request') signatures, simply connect to the fingerprinted
|
||||
system, and p0f will provide you with the necessary data. To gather SYN+ACK
|
||||
('response') signatures, you should use the bundled p0f-sendsyn utility while p0f
|
||||
is running in the background; creating them manually is not advisable.
|
||||
|
||||
== HTTP signatures ==
|
||||
|
||||
A special directive should appear at the beginning of the [http:request]
|
||||
section, structured the following way:
|
||||
|
||||
ua_os = Linux,Windows,iOS=[iPad],iOS=[iPhone],Mac OS X,...
|
||||
|
||||
This list should specify OS names that should be looked for within the
|
||||
User-Agent string if the string is otherwise deemed to be honest. This input
|
||||
is not used for fingerprinting, but aids NAT detection in some useful ways.
|
||||
|
||||
The names have to match the names used in 'sig' specifiers across p0f.fp. If a
|
||||
particular name used by p0f differs from what typically appears in User-Agent,
|
||||
the name=[string] syntax may be used to define any number of aliases.
|
||||
|
||||
Other than that, HTTP signatures for GET and HEAD requests have the following
|
||||
layout:
|
||||
|
||||
sig = ver:horder:habsent:expsw
|
||||
|
||||
ver - 0 for HTTP/1.0, 1 for HTTP/1.1, or '*' for any.
|
||||
|
||||
NEW SIGNATURES: Copy the value literally, unless you have a
|
||||
specific reason to do otherwise.
|
||||
|
||||
horder - comma-separated, ordered list of headers that should appear in
|
||||
matching traffic. Substrings to match within each of these
|
||||
headers may be specified using a name=[value] notation.
|
||||
|
||||
The signature will be matched even if other headers appear in
|
||||
between, as long as the list itself is matched in the specified
|
||||
sequence.
|
||||
|
||||
Headers that usually do appear in the traffic, but may go away
|
||||
(e.g. Accept-Language if the user has no languages defined, or
|
||||
Referer if no referring site exists) should be prefixed with '?',
|
||||
e.g. "?Referer". P0f will accept their disappearance, but will
|
||||
not allow them to appear at any other location.
|
||||
|
||||
NEW SIGNATURES: Review the list and remove any headers that
|
||||
appear to be irrelevant to the fingerprinted software, and mark
|
||||
transient ones with '?'. Remove header values that do not add
|
||||
anything to the signature, or are request- or user-specific.
|
||||
In particular, pay attention to Accept, Accept-Language, and
|
||||
Accept-Charset, as they are highly specific to request type
|
||||
and user settings.
|
||||
|
||||
P0f automatically removes some headers, prefixes others with '?',
|
||||
and inhibits the value of fields such as 'Referer' or 'Cookie' -
|
||||
but this is not a substitute for manual review.
|
||||
|
||||
NOTE: Server signatures may differ depending on the request
|
||||
(HTTP/1.1 versus 1.0, keep-alive versus one-shot, etc) and on the
|
||||
returned resource (e.g., CGI versus static content). Play around,
|
||||
browse to several URLs, also try curl and wget.
|
||||
|
||||
habsent - comma-separated list of headers that must *not* appear in
|
||||
matching traffic. This is particularly useful for noting the
|
||||
absence of standard headers (e.g. 'Host'), or for differentiating
|
||||
between otherwise very similar signatures.
|
||||
|
||||
NEW SIGNATURES: P0f will automatically highlight the absence of
|
||||
any normally present headers; other entries may be added where
|
||||
necessary.
|
||||
|
||||
expsw - expected substring in 'User-Agent' or 'Server'. This is not
|
||||
used to match traffic, and merely serves to detect dishonest
|
||||
software. If you want to explicitly match User-Agent, you need
|
||||
to do this in the 'horder' section, e.g.:
|
||||
|
||||
User-Agent=[Firefox]
|
||||
|
||||
Any of these sections sections except for 'ver' may be blank.
|
||||
|
||||
There are many protocol-level quirks that p0f could be detecting - for example,
|
||||
the use of non-standard newlines, or missing or extra spacing between header
|
||||
field names and values. There is also some information to be gathered from
|
||||
responses to OPTIONS or POST. That said, it does not seem to be worth the
|
||||
effort: the protocol is so verbose, and implemented so arbitrarily, that we are
|
||||
getting more than enough information just with a simple GET / HEAD fingerprint.
|
||||
|
||||
== SMTP signatures ==
|
||||
|
||||
*** NOT IMPLEMENTED YET ***
|
||||
|
||||
== FTP signatures ==
|
||||
|
||||
*** NOT IMPLEMENTED YET ***
|
||||
|
||||
----------------
|
||||
6. NAT detection
|
||||
----------------
|
||||
|
||||
In addition to fairly straightforward measurements of intrinsic properties of
|
||||
a single TCP session, p0f also tries to compare signatures across sessions to
|
||||
detect client-side connection sharing (NAT, HTTP proxies) or server-side load
|
||||
balancing.
|
||||
|
||||
This is done in two steps: the first significant deviation usually prompts a
|
||||
"host change" entry (which may be also indicative of multi-boot, address reuse,
|
||||
or other one-off events); and a persistent pattern of changes prompts an
|
||||
"ip sharing" notification later on.
|
||||
|
||||
All of these messages are accompanied by a set of reason codes:
|
||||
|
||||
os_sig - the OS detected right now doesn't match the OS detected earlier
|
||||
on.
|
||||
|
||||
sig_diff - no definite OS detection data available, but protocol-level
|
||||
characteristics have changed drastically (e.g., different
|
||||
TCP option layout).
|
||||
|
||||
app_vs_os - the application detected running on the host is not supposed
|
||||
to work on the host's operating system.
|
||||
|
||||
x_known - the signature progressed from known to unknown, or vice versa.
|
||||
|
||||
The following additional codes are specific to TCP:
|
||||
|
||||
tstamp - TCP timestamps went back or jumped forward.
|
||||
|
||||
ttl - TTL values have changed.
|
||||
|
||||
port - source port number has decreased.
|
||||
|
||||
mtu - system MTU has changed.
|
||||
|
||||
fuzzy - the precision with which a TCP signature is matched has
|
||||
changed.
|
||||
|
||||
The following code is also issued by the HTTP module:
|
||||
|
||||
via - data explicitly includes Via / X-Forwarded-For.
|
||||
|
||||
us_vs_os - OS fingerprint doesn't match User-Agent data, and the
|
||||
User-Agent value otherwise looks honest.
|
||||
|
||||
app_srv_lb - server application signatures change, suggesting load
|
||||
balancing.
|
||||
|
||||
date - server-advertised date changes inconsistently.
|
||||
|
||||
Different reasons have different weights, balanced to keep p0f very sensitive
|
||||
even to very homogenous environments behind NAT. If you end up seeing false
|
||||
positives or other detection problems in your environment, please let me know!
|
||||
|
||||
-----------
|
||||
7. Security
|
||||
-----------
|
||||
|
||||
You should treat the output from this tool as advisory; the fingerprinting can
|
||||
be gambled with some minor effort, and it's also possible to evade it altogether
|
||||
(e.g. with excessive IP fragmentation or bad TCP checksums). Plan accordingly.
|
||||
|
||||
P0f should to be reasonably secure to operate as a daemon. That said, un*x
|
||||
users should employ the -u option to drop privileges and chroot() when running
|
||||
the tool continuously. This greatly minimizes the consequences of any mishaps -
|
||||
and mishaps in C just tend to happen.
|
||||
|
||||
To make this step meaningful, the user you are running p0f as should be
|
||||
completely unprivileged, and should have an empty, read-only home directory. For
|
||||
example, you can do:
|
||||
|
||||
# useradd -d /var/empty/p0f -M -r -s /bin/nologin p0f-user
|
||||
# mkdir -p -m 755 /var/empty/p0f
|
||||
|
||||
Please don't put the p0f binary itself, or any other valuable assets, inside
|
||||
that user's home directory; and certainly do not use any generic locations such
|
||||
as / or /bin/ in lieu of a proper home.
|
||||
|
||||
P0f running in the background should be fairly difficult to DoS, especially
|
||||
compared to any real TCP services it will be watching. Nevertheless, there are
|
||||
so many deployment-specific factors at play that you should always preemptively
|
||||
stress-test your setup, and see how it behaves.
|
||||
|
||||
Other than that, let's talk filesystem security. When using the tool in the
|
||||
API mode (-s), the listening socket is always re-created created with 666
|
||||
permissions, so that applications running as other uids can query it at will.
|
||||
If you want to preserve the privacy of captured traffic in a multi-user system,
|
||||
please ensure that the socket is created in a directory with finer-grained
|
||||
permissions; or change API_MODE in config.h.
|
||||
|
||||
The default file mode for binary log data (-o) is 600, on the account that
|
||||
others probably don't need access to historical data; if you need to share logs,
|
||||
you can pre-create the file or change LOG_MODE in config.h.
|
||||
|
||||
Don't build p0f, and do not store its source, binary, configuration files, logs,
|
||||
or query sockets in world-writable locations such as /tmp (or any
|
||||
subdirectories created therein).
|
||||
|
||||
Last but not least, please do not attempt to make p0f setuid, or otherwise
|
||||
grant it privileges higher than these of the calling user. Neither the tool
|
||||
itself, nor the third-party components it depends on, are designed to keep rogue
|
||||
less-privileged callers at bay. If you use /etc/sudoers to list p0f as the only
|
||||
program that user X should be able to run as root, that user will probably be
|
||||
able to compromise your system. The same goes for many other uses of sudo, by
|
||||
the way.
|
||||
|
||||
--------------
|
||||
8. Limitations
|
||||
--------------
|
||||
|
||||
Here are some of the known issues you may run into:
|
||||
|
||||
== General ==
|
||||
|
||||
1) RST, ACK, and other experimental fingerprinting modes offered in p0f v2 are
|
||||
no longer supported in v3. This is because they proved to have very low
|
||||
specificity. The consequence is that you can no longer fingerprint
|
||||
"connection refused" responses.
|
||||
|
||||
2) API queries or daemon execution are not supported when reading offline pcaps.
|
||||
While there may be some fringe use cases for that, offline pcaps use a
|
||||
much simpler event loop, and so supporting these features would require some
|
||||
extra effort.
|
||||
|
||||
3) P0f needs to observe at least about 25 milliseconds worth of qualifying
|
||||
traffic to estimate system uptime. This means that if you're testing it over
|
||||
loopback or LAN, you may need to let it see more than one connection.
|
||||
|
||||
Systems with extremely slow timestamp clocks may need longer acquisition
|
||||
periods (up to several seconds); very fast clocks (over 1.5 kHz) are rejected
|
||||
completely on account of being prohibited by the RFC. Almost all OSes are
|
||||
between 100 Hz and 1 kHz, which should work fine.
|
||||
|
||||
4) Some systems vary SYN+ACK responses based on the contents of the initial SYN,
|
||||
sometimes removing TCP options not supported by the other endpoint.
|
||||
Unfortunately, there is no easy way to account for this, so several SYN+ACK
|
||||
signatures may be required per system. The bundled p0f-sendsyn utility helps
|
||||
with collecting them.
|
||||
|
||||
Another consequence of this is that you will sometimes see server uptime only
|
||||
if your own system has RFC1323 timestamps enabled. Linux does that since
|
||||
version 2.2; on Windows, you need version 7 or newer. Client uptimes are not
|
||||
affected.
|
||||
|
||||
== Windows port ==
|
||||
|
||||
1) API sockets do not work on Windows. This is due to a limitation of winpcap;
|
||||
see live_event_loop(...) in p0f.c for more info.
|
||||
|
||||
2) The chroot() jail (-u) on Windows doesn't offer any real security. This is
|
||||
due to the limitations of cygwin.
|
||||
|
||||
3) The p0f-sendsyn utility doesn't work because of the limited capabilities of
|
||||
Windows raw sockets (this should be relatively easy to fix if there are any
|
||||
users who care).
|
||||
|
||||
---------------------------
|
||||
9. Acknowledgments and more
|
||||
---------------------------
|
||||
|
||||
P0f is made possible thanks to the contributions of several good souls,
|
||||
including:
|
||||
|
||||
Phil Ames
|
||||
Jannich Brendle
|
||||
Matthew Dempsky
|
||||
Jason DePriest
|
||||
Dalibor Dukic
|
||||
Mark Martinec
|
||||
Damien Miller
|
||||
Josh Newton
|
||||
Nibbler
|
||||
Bernhard Rabe
|
||||
Chris John Riley
|
||||
Sebastian Roschke
|
||||
Peter Valchev
|
||||
Jeff Weisberg
|
||||
Anthony Howe
|
||||
Tomoyuki Murakami
|
||||
Michael Petch
|
||||
|
||||
If you wish to help, the most immediate way to do so is to simply gather new
|
||||
signatures, especially from less popular or older platforms (servers, networking
|
||||
equipment, portable / embedded / specialty OSes, etc).
|
||||
|
||||
Problems? Suggestions? Complaints? Compliments? You can reach the author at
|
||||
<lcamtuf@coredump.cx>. The author is very lonely and appreciates your mail.
|
26
docker/p0f/docs/TODO
Normal file
26
docker/p0f/docs/TODO
Normal file
@ -0,0 +1,26 @@
|
||||
Signatures:
|
||||
|
||||
- More SYN sigs,
|
||||
|
||||
- A lot more SYN+ACK signatures,
|
||||
|
||||
- A lot more server signatures - maybe write a tool.
|
||||
|
||||
Modules:
|
||||
|
||||
- SMTP
|
||||
|
||||
- FTP
|
||||
|
||||
- POP3
|
||||
|
||||
- IMAP
|
||||
|
||||
- SSH
|
||||
|
||||
- SSL
|
||||
|
||||
Misc:
|
||||
|
||||
- Manpage.
|
||||
|
29
docker/p0f/docs/existential-notes.txt
Normal file
29
docker/p0f/docs/existential-notes.txt
Normal file
@ -0,0 +1,29 @@
|
||||
-----------------------------
|
||||
Some random food for thought:
|
||||
-----------------------------
|
||||
|
||||
1) If you run p0f on any reasonably popular server, you will probably see quite
|
||||
a few systems that seem to be leaking memory in TCP headers (e.g. ACK number
|
||||
or second timestamp set on SYN packets, URG pointer without URG flag, etc).
|
||||
You will also see HTTP traffic with non-stripped Proxy-Authorization headers
|
||||
and other hilarious abnormalities.
|
||||
|
||||
Unfortunately, pinpointing the sources of many of these leaks is pretty hard;
|
||||
they often trace to proprietary corporate proxies and firewalls, and unless
|
||||
it's *your* proxy or firewall, you won't be finding out more. If you wish to
|
||||
put some investigative effort into this, there are quite a few bugs waiting
|
||||
to be tracked down, though :-)
|
||||
|
||||
2) After some hesitation, I decided *against* the inclusion of encrypted traffic
|
||||
classification features into p0f. Timing, packet size, and direction
|
||||
information lets you, for example, reliably differentiate between interactive
|
||||
SSH sessions and SFTP uploads or downloads; automated and human password
|
||||
entry attemps; or failed and successful auth.
|
||||
|
||||
The same goes for SSL: you can tell normal HTTPS browsing from file uploads,
|
||||
from attempts to smuggle, say, PPP over SSL. In the end, however, it seems
|
||||
like stretch to cram it into p0f; one day, I might improve my ancient 'fl0p'
|
||||
tool, instead:
|
||||
|
||||
http://lcamtuf.coredump.cx/soft/fl0p-devel.tgz
|
||||
|
73
docker/p0f/docs/extra-sigs.txt
Normal file
73
docker/p0f/docs/extra-sigs.txt
Normal file
@ -0,0 +1,73 @@
|
||||
These need to be investigated:
|
||||
|
||||
# AVM FritzBox 7112 w/ BusyBox Linux - sendsyn response
|
||||
4:64+0:0:1460:mss*4,0:mss:df:0
|
||||
4:64+0:0:1460:mss*4,1:mss,nop,ws:df:0
|
||||
4:64+0:0:1460:mss*4,1:mss,nop,nop,sok,nop,ws:df:0
|
||||
4:64+0:0:1460:mss*4,1:mss,sok,ts,nop,ws:df:0
|
||||
4:64+0:0:1460:mss*4,1:mss,nop,nop,ts,nop,ws:df:0
|
||||
4:64+0:0:1460:mss*4,0:mss,nop,nop,sok:df:0
|
||||
4:64+0:0:1460:mss*4,0:mss,sok,ts:df:0
|
||||
4:64+0:0:1460:mss*4,0:mss,nop,nop,ts:df:0
|
||||
|
||||
# LaCIE Network storage - sendsyn response
|
||||
4:64+0:0:1460:mss*4,0:mss,nop,nop,sok:df:0
|
||||
4:64+0:0:1460:mss*4,0:mss,sok,ts:df:0
|
||||
4:64+0:0:1460:mss*4,0:mss,nop,nop,ts:df:0
|
||||
|
||||
# HP LaserJet printer CP1515 - sendsyn response
|
||||
4:64+0:0:*:mss*7,0:mss,nop,nop,sok::0
|
||||
4:64+0:0:*:mss*7,0:mss,nop,nop,sok,nop,nop,ts::0
|
||||
4:64+0:0:*:mss*7,0:mss,nop,nop,ts::0
|
||||
|
||||
# HP LaserJet printer CP1515 - http response
|
||||
1:Server,Transfer-Encoding=[chunked],Content-Type,?Expires,?Cache-Control:Connection,Keep-Alive,Accept-Ranges,Date:Virata-EmWeb/R6_2_1
|
||||
1:Server,?Content-Length,Content-Type,?ETag,?Last-Modified,?Cache-Control:Connection,Keep-Alive,Accept-Ranges,Date:Virata-EmWeb/R6_2_1
|
||||
1:Server,Transfer-Encoding=[chunked],Content-Type,?Expires,?Cache-Control:Connection,Keep-Alive,Accept-Ranges,Date:Virata-EmWeb/R6_2_1
|
||||
|
||||
Cherokee 1.0.8-5:
|
||||
1:Connection=[Keep-Alive],Keep-Alive=[timeout=15],Date,Server,?Content-Length,Content-Type,?Cache-Control,?Pragma:Accept-Ranges:Cherokee/1.0.8 (Debian GNU/Linux)
|
||||
|
||||
AOLserver 4.5.1-12:
|
||||
1:MIME-Version=[1.0],Date,Server,Content-Type,?Content-Length,Connection=[close]:Keep-Alive,Accept-Ranges:AOLserver/4.5.1
|
||||
|
||||
BOA 0.94.14rc21-3.1:
|
||||
1:Date,Server,Accept-Ranges=[bytes],Connection=[close],Content-Type:Keep-Alive:Boa/0.94.14rc21
|
||||
|
||||
Yaws 1.88-2:
|
||||
1:Connection=[close],Server,Date,?Content-Length,Content-Type:Keep-Alive,Accept-Ranges:Yaws/1.88 Yet Another Web Server
|
||||
|
||||
Ocsigen 1.3.3-1squeeze1:
|
||||
1:accept-ranges=[none],cache-control=[no-cache],content-type=[text/html; charset=iso-8859-1],date=[Wed, 18 Jan 2012 09:32:55 GMT],expires=[0],server=[Ocsigen],transfer-encoding=[chunked]:Content-Type,Connection,Keep-Alive,Accept-Ranges,Date:
|
||||
|
||||
dhttpd 1.02a-18:
|
||||
0:Date,Server,Content-type=[text/html]:Content-Type,Connection,Keep-Alive,Accept-Ranges:dhttpd/1.02a
|
||||
|
||||
thttpd 2.25b-11:
|
||||
1:Server,Content-Type,Date,?Last-Modified,Accept-Ranges=[bytes],Connection=[close]:Keep-Alive:thttpd/2.25b 29dec2003
|
||||
|
||||
------------
|
||||
|
||||
uhttpd version 7 (running on OpenWrt):
|
||||
0::Content-Type,Connection,Keep-Alive,Accept-Ranges,Date:
|
||||
|
||||
Cherokee 1.0.8-5:
|
||||
0:Connection=[close],Date,Server,Content-Type:Keep-Alive,Accept-Ranges:Cherokee/1.0.8 (Debian GNU/Linux)
|
||||
|
||||
AOLserver 4.5.1-12:
|
||||
0:MIME-Version=[1.0],Date,Server,Content-Type,?Content-Length,Connection=[close]:Keep-Alive,Accept-Ranges:AOLserver/4.5.1
|
||||
|
||||
BOA 0.94.14rc21-3.1:
|
||||
0:Date,Server,Accept-Ranges=[bytes],Connection=[close],?Last-Modified,Content-Type:Keep-Alive:Boa/0.94.14rc21
|
||||
|
||||
Ocsigen 1.3.3-1squeeze1:
|
||||
1:accept-ranges=[none],cache-control=[no-cache],content-type=[text/html; charset=iso-8859-1],date=[Tue, 17 Jan 2012 22:46:08 GMT],expires=[0],server=[Ocsigen]:Content-Type,Connection,Keep-Alive,Accept-Ranges,Date:
|
||||
|
||||
dhttpd 1.02a-18:
|
||||
0:Date,Server,Content-type=[text/html]:Content-Type,Connection,Keep-Alive,Accept-Ranges:dhttpd/1.02a
|
||||
|
||||
Yaws 1.88-2:
|
||||
1:Connection=[Keep-Alive],Server,Date,?Last-Modified,Etag=["2nu+xcAAGwK"],?Content-Length,Content-Type:Keep-Alive,Accept-Ranges:Yaws/1.88 Yet Another Web Server
|
||||
|
||||
thttpd 2.25b-11:
|
||||
0:Server,Content-Type,Date,?Last-Modified,Accept-Ranges=[bytes],Connection=[close]:Keep-Alive:thttpd/2.25b 29dec2003
|
1415
docker/p0f/fp_http.c
Normal file
1415
docker/p0f/fp_http.c
Normal file
File diff suppressed because it is too large
Load Diff
104
docker/p0f/fp_http.h
Normal file
104
docker/p0f/fp_http.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
p0f - HTTP fingerprinting
|
||||
-------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_FP_HTTP_H
|
||||
#define _HAVE_FP_HTTP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* A structure used for looking up various headers internally in fp_http.c: */
|
||||
|
||||
struct http_id {
|
||||
char* name;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
/* Another internal structure for UA -> OS maps: */
|
||||
|
||||
struct ua_map_record {
|
||||
u8* name;
|
||||
u32 id;
|
||||
};
|
||||
|
||||
/* HTTP header field: */
|
||||
|
||||
struct http_hdr {
|
||||
s32 id; /* Lookup ID (-1 = none) */
|
||||
u8* name; /* Text name (NULL = use lookup ID) */
|
||||
u8* value; /* Value, if any */
|
||||
u8 optional; /* Optional header? */
|
||||
};
|
||||
|
||||
/* Request / response signature collected from the wire: */
|
||||
|
||||
struct http_sig {
|
||||
|
||||
s8 http_ver; /* HTTP version (-1 = any) */
|
||||
|
||||
struct http_hdr hdr[HTTP_MAX_HDRS]; /* Mandatory / discovered headers */
|
||||
u32 hdr_cnt;
|
||||
|
||||
u64 hdr_bloom4; /* Bloom filter for headers */
|
||||
|
||||
u32 miss[HTTP_MAX_HDRS]; /* Missing headers */
|
||||
u32 miss_cnt;
|
||||
|
||||
u8* sw; /* Software string (U-A or Server) */
|
||||
u8* lang; /* Accept-Language */
|
||||
u8* via; /* Via or X-Forwarded-For */
|
||||
|
||||
u32 date; /* Parsed 'Date' */
|
||||
u32 recv_date; /* Actual receipt date */
|
||||
|
||||
/* Information used for matching with p0f.fp: */
|
||||
|
||||
struct http_sig_record* matched; /* NULL = no match */
|
||||
u8 dishonest; /* "sw" looks forged? */
|
||||
|
||||
};
|
||||
|
||||
/* Record for a HTTP signature read from p0f.fp: */
|
||||
|
||||
struct http_sig_record {
|
||||
|
||||
s32 class_id; /* OS class ID (-1 = user) */
|
||||
s32 name_id; /* OS name ID */
|
||||
u8* flavor; /* Human-readable flavor string */
|
||||
|
||||
u32 label_id; /* Signature label ID */
|
||||
|
||||
u32* sys; /* OS class / name IDs for user apps */
|
||||
u32 sys_cnt; /* Length of sys */
|
||||
|
||||
u32 line_no; /* Line number in p0f.fp */
|
||||
|
||||
u8 generic; /* Generic signature? */
|
||||
|
||||
struct http_sig* sig; /* Actual signature data */
|
||||
|
||||
};
|
||||
|
||||
/* Register new HTTP signature. */
|
||||
|
||||
struct packet_flow;
|
||||
|
||||
void http_parse_ua(u8* val, u32 line_no);
|
||||
|
||||
void http_register_sig(u8 to_srv, u8 generic, s32 sig_class, u32 sig_name,
|
||||
u8* sig_flavor, u32 label_id, u32* sys, u32 sys_cnt,
|
||||
u8* val, u32 line_no);
|
||||
|
||||
u8 process_http(u8 to_srv, struct packet_flow* f);
|
||||
|
||||
void free_sig_hdrs(struct http_sig* h);
|
||||
|
||||
void http_init(void);
|
||||
|
||||
#endif /* _HAVE_FP_HTTP_H */
|
92
docker/p0f/fp_mtu.c
Normal file
92
docker/p0f/fp_mtu.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
p0f - MTU matching
|
||||
------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "alloc-inl.h"
|
||||
#include "process.h"
|
||||
#include "readfp.h"
|
||||
#include "p0f.h"
|
||||
#include "tcp.h"
|
||||
|
||||
#include "fp_mtu.h"
|
||||
|
||||
static struct mtu_sig_record* sigs[SIG_BUCKETS];
|
||||
static u32 sig_cnt[SIG_BUCKETS];
|
||||
|
||||
|
||||
/* Register a new MTU signature. */
|
||||
|
||||
void mtu_register_sig(u8* name, u8* val, u32 line_no) {
|
||||
|
||||
u8* nxt = val;
|
||||
s32 mtu;
|
||||
u32 bucket;
|
||||
|
||||
while (isdigit(*nxt)) nxt++;
|
||||
|
||||
if (nxt == val || *nxt) FATAL("Malformed MTU value in line %u.", line_no);
|
||||
|
||||
mtu = atol((char*)val);
|
||||
|
||||
if (mtu <= 0 || mtu > 65535) FATAL("Malformed MTU value in line %u.", line_no);
|
||||
|
||||
bucket = mtu % SIG_BUCKETS;
|
||||
|
||||
sigs[bucket] = DFL_ck_realloc(sigs[bucket], (sig_cnt[bucket] + 1) *
|
||||
sizeof(struct mtu_sig_record));
|
||||
|
||||
sigs[bucket][sig_cnt[bucket]].mtu = mtu;
|
||||
sigs[bucket][sig_cnt[bucket]].name = name;
|
||||
|
||||
sig_cnt[bucket]++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fingerprint_mtu(u8 to_srv, struct packet_data* pk, struct packet_flow* f) {
|
||||
|
||||
u32 bucket, i, mtu;
|
||||
|
||||
if (!pk->mss || f->sendsyn) return;
|
||||
|
||||
start_observation("mtu", 2, to_srv, f);
|
||||
|
||||
if (pk->ip_ver == IP_VER4) mtu = pk->mss + MIN_TCP4;
|
||||
else mtu = pk->mss + MIN_TCP6;
|
||||
|
||||
bucket = (mtu) % SIG_BUCKETS;
|
||||
|
||||
for (i = 0; i < sig_cnt[bucket]; i++)
|
||||
if (sigs[bucket][i].mtu == mtu) break;
|
||||
|
||||
if (i == sig_cnt[bucket]) add_observation_field("link", NULL);
|
||||
else {
|
||||
|
||||
add_observation_field("link", sigs[bucket][i].name);
|
||||
|
||||
if (to_srv) f->client->link_type = sigs[bucket][i].name;
|
||||
else f->server->link_type = sigs[bucket][i].name;
|
||||
|
||||
}
|
||||
|
||||
OBSERVF("raw_mtu", "%u", mtu);
|
||||
|
||||
}
|
34
docker/p0f/fp_mtu.h
Normal file
34
docker/p0f/fp_mtu.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
p0f - MTU matching
|
||||
------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_FP_MTU_H
|
||||
#define _HAVE_FP_MTU_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* Record for a TCP signature read from p0f.fp: */
|
||||
|
||||
struct mtu_sig_record {
|
||||
|
||||
u8* name;
|
||||
u16 mtu;
|
||||
|
||||
};
|
||||
|
||||
#include "process.h"
|
||||
|
||||
struct packet_data;
|
||||
struct packet_flow;
|
||||
|
||||
void mtu_register_sig(u8* name, u8* val, u32 line_no);
|
||||
|
||||
void fingerprint_mtu(u8 to_srv, struct packet_data* pk, struct packet_flow* f);
|
||||
|
||||
#endif /* _HAVE_FP_MTU_H */
|
1341
docker/p0f/fp_tcp.c
Normal file
1341
docker/p0f/fp_tcp.c
Normal file
File diff suppressed because it is too large
Load Diff
95
docker/p0f/fp_tcp.h
Normal file
95
docker/p0f/fp_tcp.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
p0f - TCP/IP packet matching
|
||||
----------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_FP_TCP_H
|
||||
#define _HAVE_FP_TCP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* Simplified data for signature matching and NAT detection: */
|
||||
|
||||
struct tcp_sig {
|
||||
|
||||
u32 opt_hash; /* Hash of opt_layout & opt_cnt */
|
||||
u32 quirks; /* Quirks */
|
||||
|
||||
u8 opt_eol_pad; /* Amount of padding past EOL */
|
||||
u8 ip_opt_len; /* Length of IP options */
|
||||
|
||||
s8 ip_ver; /* -1 = any, IP_VER4, IP_VER6 */
|
||||
|
||||
u8 ttl; /* Actual TTL */
|
||||
|
||||
s32 mss; /* Maximum segment size (-1 = any) */
|
||||
u16 win; /* Window size */
|
||||
u8 win_type; /* WIN_TYPE_* */
|
||||
s16 wscale; /* Window scale (-1 = any) */
|
||||
|
||||
s8 pay_class; /* -1 = any, 0 = zero, 1 = non-zero */
|
||||
|
||||
u16 tot_hdr; /* Total header length */
|
||||
u32 ts1; /* Own timestamp */
|
||||
u64 recv_ms; /* Packet recv unix time (ms) */
|
||||
|
||||
/* Information used for matching with p0f.fp: */
|
||||
|
||||
struct tcp_sig_record* matched; /* NULL = no match */
|
||||
u8 fuzzy; /* Approximate match? */
|
||||
u8 dist; /* Distance */
|
||||
|
||||
};
|
||||
|
||||
/* Methods for matching window size in tcp_sig: */
|
||||
|
||||
#define WIN_TYPE_NORMAL 0x00 /* Literal value */
|
||||
#define WIN_TYPE_ANY 0x01 /* Wildcard (p0f.fp sigs only) */
|
||||
#define WIN_TYPE_MOD 0x02 /* Modulo check (p0f.fp sigs only) */
|
||||
#define WIN_TYPE_MSS 0x03 /* Window size MSS multiplier */
|
||||
#define WIN_TYPE_MTU 0x04 /* Window size MTU multiplier */
|
||||
|
||||
/* Record for a TCP signature read from p0f.fp: */
|
||||
|
||||
struct tcp_sig_record {
|
||||
|
||||
u8 generic; /* Generic entry? */
|
||||
s32 class_id; /* OS class ID (-1 = user) */
|
||||
s32 name_id; /* OS name ID */
|
||||
u8* flavor; /* Human-readable flavor string */
|
||||
|
||||
u32 label_id; /* Signature label ID */
|
||||
|
||||
u32* sys; /* OS class / name IDs for user apps */
|
||||
u32 sys_cnt; /* Length of sys */
|
||||
|
||||
u32 line_no; /* Line number in p0f.fp */
|
||||
|
||||
u8 bad_ttl; /* TTL is generated randomly */
|
||||
|
||||
struct tcp_sig* sig; /* Actual signature data */
|
||||
|
||||
};
|
||||
|
||||
#include "process.h"
|
||||
|
||||
struct packet_data;
|
||||
struct packet_flow;
|
||||
|
||||
void tcp_register_sig(u8 to_srv, u8 generic, s32 sig_class, u32 sig_name,
|
||||
u8* sig_flavor, u32 label_id, u32* sys, u32 sys_cnt,
|
||||
u8* val, u32 line_no);
|
||||
|
||||
struct tcp_sig* fingerprint_tcp(u8 to_srv, struct packet_data* pk,
|
||||
struct packet_flow* f);
|
||||
|
||||
void fingerprint_sendsyn(struct packet_data* pk);
|
||||
|
||||
void check_ts_tcp(u8 to_srv, struct packet_data* pk, struct packet_flow* f);
|
||||
|
||||
#endif /* _HAVE_FP_TCP_H */
|
98
docker/p0f/hash.h
Normal file
98
docker/p0f/hash.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
p0f - a port of lookup3
|
||||
-----------------------
|
||||
|
||||
The hash32() function is a modified copy of lookup3, a good non-cryptosafe
|
||||
seeded hashing function developed by Bob Jenkins.
|
||||
|
||||
Bob's original code is public domain; so is this variant.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_HASH_H
|
||||
#define _HAVE_HASH_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define ROL32(_x, _r) (((_x) << (_r)) | ((_x) >> (32 - (_r))))
|
||||
|
||||
static inline u32 hash32(const void* key, u32 len, u32 seed) {
|
||||
|
||||
u32 a, b, c;
|
||||
const u8* k = key;
|
||||
|
||||
a = b = c = 0xdeadbeef + len + seed;
|
||||
|
||||
while (len > 12) {
|
||||
|
||||
a += RD32p(k);
|
||||
b += RD32p(k + 4);
|
||||
c += RD32p(k + 8);
|
||||
|
||||
a -= c; a ^= ROL32(c, 4); c += b;
|
||||
b -= a; b ^= ROL32(a, 6); a += c;
|
||||
c -= b; c ^= ROL32(b, 8); b += a;
|
||||
a -= c; a ^= ROL32(c, 16); c += b;
|
||||
b -= a; b ^= ROL32(a, 19); a += c;
|
||||
c -= b; c ^= ROL32(b, 4); b += a;
|
||||
|
||||
len -= 12;
|
||||
k += 12;
|
||||
|
||||
}
|
||||
|
||||
switch (len) {
|
||||
|
||||
case 12: c += RD32p(k + 8);
|
||||
b += RD32p(k+ 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 11: c += (RD16p(k + 8) << 8) | k[10];
|
||||
b += RD32p(k + 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 10: c += RD16p(k + 8);
|
||||
b += RD32p(k + 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 9: c += k[8];
|
||||
b += RD32p(k + 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 8: b += RD32p(k + 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 7: b += (RD16p(k + 4) << 8) | k[6] ;
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 6: b += RD16p(k + 4);
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 5: b += k[4];
|
||||
a += RD32p(k); break;
|
||||
|
||||
case 4: a += RD32p(k); break;
|
||||
|
||||
case 3: a += (RD16p(k) << 8) | k[2]; break;
|
||||
|
||||
case 2: a += RD16p(k); break;
|
||||
|
||||
case 1: a += k[0]; break;
|
||||
|
||||
case 0: return c;
|
||||
|
||||
}
|
||||
|
||||
c ^= b; c -= ROL32(b, 14);
|
||||
a ^= c; a -= ROL32(c, 11);
|
||||
b ^= a; b -= ROL32(a, 25);
|
||||
c ^= b; c -= ROL32(b, 16);
|
||||
a ^= c; a -= ROL32(c, 4);
|
||||
b ^= a; b -= ROL32(a, 14);
|
||||
c ^= b; c -= ROL32(b, 24);
|
||||
|
||||
return c;
|
||||
|
||||
}
|
||||
|
||||
#endif /* !_HAVE_HASH_H */
|
282
docker/p0f/languages.h
Normal file
282
docker/p0f/languages.h
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
p0f - ISO 639-1 languages
|
||||
-------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_LANGUAGES_H
|
||||
#define _HAVE_LANGUAGES_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define MAX_LANG 3
|
||||
|
||||
#define LANG_HASH(_b0, _b1) (((_b0) * (_b1) ^ (_b1)) & 0xff)
|
||||
|
||||
static char* languages[256][MAX_LANG * 2 + 1] = {
|
||||
|
||||
/* 0x00 */ { 0 },
|
||||
/* 0x01 */ { "ro", "Romanian", 0 },
|
||||
/* 0x02 */ { "sw", "Swahili", 0 },
|
||||
/* 0x03 */ { "ne", "Nepali", 0 },
|
||||
/* 0x04 */ { "nl", "Dutch", "sn", "Shona", 0 },
|
||||
/* 0x05 */ { 0 },
|
||||
/* 0x06 */ { "ln", "Lingala", 0 },
|
||||
/* 0x07 */ { 0 },
|
||||
/* 0x08 */ { "en", "English", "ie", "Interlingue", 0 },
|
||||
/* 0x09 */ { "bg", "Bulgarian", "ha", "Hausa", 0 },
|
||||
/* 0x0a */ { "cs", "Czech", "ko", "Korean", 0 },
|
||||
/* 0x0b */ { 0 },
|
||||
/* 0x0c */ { "gv", "Manx", 0 },
|
||||
/* 0x0d */ { 0 },
|
||||
/* 0x0e */ { 0 },
|
||||
/* 0x0f */ { "vi", "Vietnamese", 0 },
|
||||
/* 0x10 */ { "mt", "Maltese", 0 },
|
||||
/* 0x11 */ { "bo", "Tibetan", "de", "German", "pa", "Panjabi", 0 },
|
||||
/* 0x12 */ { 0 },
|
||||
/* 0x13 */ { "lg", "Ganda", 0 },
|
||||
/* 0x14 */ { 0 },
|
||||
/* 0x15 */ { 0 },
|
||||
/* 0x16 */ { 0 },
|
||||
/* 0x17 */ { "tk", "Turkmen", 0 },
|
||||
/* 0x18 */ { "gl", "Galician", "yo", "Yoruba", 0 },
|
||||
/* 0x19 */ { 0 },
|
||||
/* 0x1a */ { "sc", "Sardinian", 0 },
|
||||
/* 0x1b */ { 0 },
|
||||
/* 0x1c */ { "or", "Oriya", 0 },
|
||||
/* 0x1d */ { 0 },
|
||||
/* 0x1e */ { "fr", "French", 0 },
|
||||
/* 0x1f */ { 0 },
|
||||
/* 0x20 */ { "ae", "Avestan", "am", "Amharic", "mh", "Marshallese", 0 },
|
||||
/* 0x21 */ { 0 },
|
||||
/* 0x22 */ { "hr", "Croatian", "sg", "Sango", 0 },
|
||||
/* 0x23 */ { "ps", "Pushto", "to", "Tonga", 0 },
|
||||
/* 0x24 */ { "kj", "Kuanyama", "kv", "Komi", 0 },
|
||||
/* 0x25 */ { "li", "Limburgan", "ng", "Ndonga", 0 },
|
||||
/* 0x26 */ { 0 },
|
||||
/* 0x27 */ { 0 },
|
||||
/* 0x28 */ { 0 },
|
||||
/* 0x29 */ { "lu", "Luba-Katanga", 0 },
|
||||
/* 0x2a */ { "nn", "Norwegian Nynorsk", 0 },
|
||||
/* 0x2b */ { 0 },
|
||||
/* 0x2c */ { "es", "Spanish", "gn", "Guarani", "pl", "Polish", 0 },
|
||||
/* 0x2d */ { 0 },
|
||||
/* 0x2e */ { "om", "Oromo", 0 },
|
||||
/* 0x2f */ { 0 },
|
||||
/* 0x30 */ { 0 },
|
||||
/* 0x31 */ { 0 },
|
||||
/* 0x32 */ { 0 },
|
||||
/* 0x33 */ { 0 },
|
||||
/* 0x34 */ { 0 },
|
||||
/* 0x35 */ { 0 },
|
||||
/* 0x36 */ { 0 },
|
||||
/* 0x37 */ { 0 },
|
||||
/* 0x38 */ { 0 },
|
||||
/* 0x39 */ { 0 },
|
||||
/* 0x3a */ { "lb", "Luxembourgish", "se", "Northern Sami", 0 },
|
||||
/* 0x3b */ { 0 },
|
||||
/* 0x3c */ { 0 },
|
||||
/* 0x3d */ { 0 },
|
||||
/* 0x3e */ { 0 },
|
||||
/* 0x3f */ { 0 },
|
||||
/* 0x40 */ { "ab", "Abkhazian", "ar", "Arabic", "az", "Azerbaijani", 0 },
|
||||
/* 0x41 */ { 0 },
|
||||
/* 0x42 */ { "si", "Sinhala", 0 },
|
||||
/* 0x43 */ { "ba", "Bashkir", 0 },
|
||||
/* 0x44 */ { "sr", "Serbian", 0 },
|
||||
/* 0x45 */ { "vo", "Volapuk", 0 },
|
||||
/* 0x46 */ { 0 },
|
||||
/* 0x47 */ { 0 },
|
||||
/* 0x48 */ { "kl", "Kalaallisut", "th", "Thai", 0 },
|
||||
/* 0x49 */ { 0 },
|
||||
/* 0x4a */ { "cu", "Church Slavic", 0 },
|
||||
/* 0x4b */ { "ja", "Japanese", 0 },
|
||||
/* 0x4c */ { 0 },
|
||||
/* 0x4d */ { 0 },
|
||||
/* 0x4e */ { 0 },
|
||||
/* 0x4f */ { "fy", "Western Frisian", 0 },
|
||||
/* 0x50 */ { "ch", "Chamorro", 0 },
|
||||
/* 0x51 */ { "hy", "Armenian", 0 },
|
||||
/* 0x52 */ { 0 },
|
||||
/* 0x53 */ { 0 },
|
||||
/* 0x54 */ { "ht", "Haitian", 0 },
|
||||
/* 0x55 */ { "fo", "Faroese", 0 },
|
||||
/* 0x56 */ { "fj", "Fijian", 0 },
|
||||
/* 0x57 */ { 0 },
|
||||
/* 0x58 */ { "gd", "Scottish Gaelic", "ig", "Igbo", "is", "Icelandic", 0 },
|
||||
/* 0x59 */ { 0 },
|
||||
/* 0x5a */ { 0 },
|
||||
/* 0x5b */ { "bi", "Bislama", "za", "Zhuang", 0 },
|
||||
/* 0x5c */ { "eu", "Basque", 0 },
|
||||
/* 0x5d */ { 0 },
|
||||
/* 0x5e */ { 0 },
|
||||
/* 0x5f */ { 0 },
|
||||
/* 0x60 */ { "id", "Indonesian", 0 },
|
||||
/* 0x61 */ { 0 },
|
||||
/* 0x62 */ { "ks", "Kashmiri", 0 },
|
||||
/* 0x63 */ { 0 },
|
||||
/* 0x64 */ { "cr", "Cree", 0 },
|
||||
/* 0x65 */ { 0 },
|
||||
/* 0x66 */ { "ga", "Irish", "gu", "Gujarati", 0 },
|
||||
/* 0x67 */ { 0 },
|
||||
/* 0x68 */ { "st", "Southern Sotho", "ur", "Urdu", 0 },
|
||||
/* 0x69 */ { 0 },
|
||||
/* 0x6a */ { "ce", "Chechen", "kg", "Kongo", 0 },
|
||||
/* 0x6b */ { 0 },
|
||||
/* 0x6c */ { 0 },
|
||||
/* 0x6d */ { "he", "Hebrew", 0 },
|
||||
/* 0x6e */ { "dv", "Dhivehi", 0 },
|
||||
/* 0x6f */ { "ru", "Russian", "ts", "Tsonga", 0 },
|
||||
/* 0x70 */ { 0 },
|
||||
/* 0x71 */ { 0 },
|
||||
/* 0x72 */ { "bn", "Bengali", 0 },
|
||||
/* 0x73 */ { 0 },
|
||||
/* 0x74 */ { "sv", "Swedish", "ug", "Uighur", 0 },
|
||||
/* 0x75 */ { "bs", "Bosnian", 0 },
|
||||
/* 0x76 */ { "wa", "Walloon", 0 },
|
||||
/* 0x77 */ { "ho", "Hiri Motu", 0 },
|
||||
/* 0x78 */ { "ii", "Sichuan Yi", 0 },
|
||||
/* 0x79 */ { 0 },
|
||||
/* 0x7a */ { "sk", "Slovak", 0 },
|
||||
/* 0x7b */ { 0 },
|
||||
/* 0x7c */ { 0 },
|
||||
/* 0x7d */ { 0 },
|
||||
/* 0x7e */ { "nb", "Norwegian Bokmal", 0 },
|
||||
/* 0x7f */ { 0 },
|
||||
/* 0x80 */ { 0 },
|
||||
/* 0x81 */ { 0 },
|
||||
/* 0x82 */ { "co", "Corsican", 0 },
|
||||
/* 0x83 */ { 0 },
|
||||
/* 0x84 */ { "lt", "Lithuanian", "ms", "Malay", 0 },
|
||||
/* 0x85 */ { "da", "Danish", 0 },
|
||||
/* 0x86 */ { 0 },
|
||||
/* 0x87 */ { "ny", "Nyanja", 0 },
|
||||
/* 0x88 */ { "ik", "Inupiaq", "iu", "Inuktitut", "sd", "Sindhi", 0 },
|
||||
/* 0x89 */ { "rw", "Kinyarwanda", 0 },
|
||||
/* 0x8a */ { "ki", "Kikuyu", 0 },
|
||||
/* 0x8b */ { 0 },
|
||||
/* 0x8c */ { "uk", "Ukrainian", 0 },
|
||||
/* 0x8d */ { "la", "Latin", 0 },
|
||||
/* 0x8e */ { "nr", "South Ndebele", "oc", "Occitan", 0 },
|
||||
/* 0x8f */ { 0 },
|
||||
/* 0x90 */ { "ml", "Malayalam", 0 },
|
||||
/* 0x91 */ { 0 },
|
||||
/* 0x92 */ { "ku", "Kurdish", "rn", "Rundi", 0 },
|
||||
/* 0x93 */ { 0 },
|
||||
/* 0x94 */ { "kn", "Kannada", 0 },
|
||||
/* 0x95 */ { "ta", "Tamil", 0 },
|
||||
/* 0x96 */ { 0 },
|
||||
/* 0x97 */ { 0 },
|
||||
/* 0x98 */ { 0 },
|
||||
/* 0x99 */ { "pi", "Pali", 0 },
|
||||
/* 0x9a */ { "sm", "Samoan", 0 },
|
||||
/* 0x9b */ { "tw", "Twi", 0 },
|
||||
/* 0x9c */ { "nd", "North Ndebele", "oj", "Ojibwa", "tl", "Tagalog", 0 },
|
||||
/* 0x9d */ { 0 },
|
||||
/* 0x9e */ { 0 },
|
||||
/* 0x9f */ { 0 },
|
||||
/* 0xa0 */ { "aa", "Afar", "ay", "Aymara", 0 },
|
||||
/* 0xa1 */ { "te", "Telugu", 0 },
|
||||
/* 0xa2 */ { 0 },
|
||||
/* 0xa3 */ { 0 },
|
||||
/* 0xa4 */ { "eo", "Esperanto", 0 },
|
||||
/* 0xa5 */ { 0 },
|
||||
/* 0xa6 */ { 0 },
|
||||
/* 0xa7 */ { 0 },
|
||||
/* 0xa8 */ { "ia", "Interlingua", "xh", "Xhosa", 0 },
|
||||
/* 0xa9 */ { 0 },
|
||||
/* 0xaa */ { "jv", "Javanese", 0 },
|
||||
/* 0xab */ { 0 },
|
||||
/* 0xac */ { 0 },
|
||||
/* 0xad */ { "ty", "Tahitian", 0 },
|
||||
/* 0xae */ { "os", "Ossetian", 0 },
|
||||
/* 0xaf */ { 0 },
|
||||
/* 0xb0 */ { "et", "Estonian", 0 },
|
||||
/* 0xb1 */ { 0 },
|
||||
/* 0xb2 */ { "cy", "Welsh", "so", "Somali", "sq", "Albanian", 0 },
|
||||
/* 0xb3 */ { 0 },
|
||||
/* 0xb4 */ { "pt", "Portuguese", 0 },
|
||||
/* 0xb5 */ { 0 },
|
||||
/* 0xb6 */ { "tn", "Tswana", 0 },
|
||||
/* 0xb7 */ { "zu", "Zulu", 0 },
|
||||
/* 0xb8 */ { "bh", "Bihari", "mn", "Mongolian", "uz", "Uzbek", 0 },
|
||||
/* 0xb9 */ { 0 },
|
||||
/* 0xba */ { 0 },
|
||||
/* 0xbb */ { "lo", "Lao", 0 },
|
||||
/* 0xbc */ { "ee", "Ewe", "mg", "Malagasy", 0 },
|
||||
/* 0xbd */ { 0 },
|
||||
/* 0xbe */ { "lv", "Latvian", 0 },
|
||||
/* 0xbf */ { "fi", "Finnish", 0 },
|
||||
/* 0xc0 */ { "af", "Afrikaans", "an", "Aragonese", "av", "Avaric", 0 },
|
||||
/* 0xc1 */ { "hi", "Hindi", 0 },
|
||||
/* 0xc2 */ { "ff", "Fulah", "nv", "Navajo", 0 },
|
||||
/* 0xc3 */ { 0 },
|
||||
/* 0xc4 */ { 0 },
|
||||
/* 0xc5 */ { 0 },
|
||||
/* 0xc6 */ { 0 },
|
||||
/* 0xc7 */ { "fa", "Persian", 0 },
|
||||
/* 0xc8 */ { "yi", "Yiddish", 0 },
|
||||
/* 0xc9 */ { 0 },
|
||||
/* 0xca */ { "kw", "Cornish", 0 },
|
||||
/* 0xcb */ { "tg", "Tajik", 0 },
|
||||
/* 0xcc */ { 0 },
|
||||
/* 0xcd */ { 0 },
|
||||
/* 0xce */ { 0 },
|
||||
/* 0xcf */ { "be", "Belarusian", "na", "Nauru", 0 },
|
||||
/* 0xd0 */ { "qu", "Quechua", "sh", "Serbo-Croatian", 0 },
|
||||
/* 0xd1 */ { 0 },
|
||||
/* 0xd2 */ { "dz", "Dzongkha", "kk", "Kazakh", 0 },
|
||||
/* 0xd3 */ { 0 },
|
||||
/* 0xd4 */ { "cv", "Chuvash", "kr", "Kanuri", 0 },
|
||||
/* 0xd5 */ { 0 },
|
||||
/* 0xd6 */ { "br", "Breton", 0 },
|
||||
/* 0xd7 */ { "bm", "Bambara", 0 },
|
||||
/* 0xd8 */ { 0 },
|
||||
/* 0xd9 */ { 0 },
|
||||
/* 0xda */ { "ss", "Swati", "tr", "Turkish", 0 },
|
||||
/* 0xdb */ { 0 },
|
||||
/* 0xdc */ { "mi", "Maori", 0 },
|
||||
/* 0xdd */ { "no", "Norwegian", 0 },
|
||||
/* 0xde */ { 0 },
|
||||
/* 0xdf */ { 0 },
|
||||
/* 0xe0 */ { "ak", "Akan", "as", "Assamese", "it", "Italian", 0 },
|
||||
/* 0xe1 */ { 0 },
|
||||
/* 0xe2 */ { "ca", "Catalan", "km", "Central Khmer", 0 },
|
||||
/* 0xe3 */ { 0 },
|
||||
/* 0xe4 */ { "mk", "Macedonian", "tt", "Tatar", 0 },
|
||||
/* 0xe5 */ { 0 },
|
||||
/* 0xe6 */ { 0 },
|
||||
/* 0xe7 */ { "rm", "Romansh", 0 },
|
||||
/* 0xe8 */ { "io", "Ido", "sl", "Slovenian", 0 },
|
||||
/* 0xe9 */ { 0 },
|
||||
/* 0xea */ { "hz", "Herero", "ka", "Georgian", "ky", "Kirghiz", 0 },
|
||||
/* 0xeb */ { "ve", "Venda", 0 },
|
||||
/* 0xec */ { 0 },
|
||||
/* 0xed */ { 0 },
|
||||
/* 0xee */ { 0 },
|
||||
/* 0xef */ { 0 },
|
||||
/* 0xf0 */ { "el", "Modern Greek", 0 },
|
||||
/* 0xf1 */ { 0 },
|
||||
/* 0xf2 */ { "sa", "Sanskrit", 0 },
|
||||
/* 0xf3 */ { 0 },
|
||||
/* 0xf4 */ { 0 },
|
||||
/* 0xf5 */ { 0 },
|
||||
/* 0xf6 */ { "wo", "Wolof", 0 },
|
||||
/* 0xf7 */ { 0 },
|
||||
/* 0xf8 */ { "mr", "Marathi", "zh", "Chinese", 0 },
|
||||
/* 0xf9 */ { 0 },
|
||||
/* 0xfa */ { "su", "Sundanese", 0 },
|
||||
/* 0xfb */ { 0 },
|
||||
/* 0xfc */ { "my", "Burmese", 0 },
|
||||
/* 0xfd */ { "hu", "Hungarian", "ti", "Tigrinya", 0 },
|
||||
/* 0xfe */ { 0 },
|
||||
/* 0xff */ { 0 }
|
||||
|
||||
};
|
||||
|
||||
#endif /* !_HAVE_LANGUAGES_H */
|
||||
|
1289
docker/p0f/p0f.c
Normal file
1289
docker/p0f/p0f.c
Normal file
File diff suppressed because it is too large
Load Diff
938
docker/p0f/p0f.fp
Normal file
938
docker/p0f/p0f.fp
Normal file
@ -0,0 +1,938 @@
|
||||
;
|
||||
; p0f - fingerprint database
|
||||
; --------------------------
|
||||
;
|
||||
; See section 5 in the README for a detailed discussion of the format used here.
|
||||
;
|
||||
; Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
;
|
||||
; Distributed under the terms and conditions of GNU LGPL.
|
||||
;
|
||||
|
||||
classes = win,unix,other
|
||||
|
||||
; ==============
|
||||
; MTU signatures
|
||||
; ==============
|
||||
|
||||
[mtu]
|
||||
|
||||
; The most common values, used by Ethernet-homed systems, PPP over POTS, PPPoA
|
||||
; DSL, etc:
|
||||
|
||||
label = Ethernet or modem
|
||||
sig = 576
|
||||
sig = 1500
|
||||
|
||||
; Common DSL-specific values (1492 is canonical for PPPoE, but ISPs tend to
|
||||
; horse around a bit):
|
||||
|
||||
label = DSL
|
||||
sig = 1452
|
||||
sig = 1454
|
||||
sig = 1492
|
||||
|
||||
; Miscellanous tunnels (including VPNs, IPv6 tunneling, etc):
|
||||
|
||||
label = GIF
|
||||
sig = 1240
|
||||
sig = 1280
|
||||
|
||||
label = generic tunnel or VPN
|
||||
sig = 1300
|
||||
sig = 1400
|
||||
sig = 1420
|
||||
sig = 1440
|
||||
sig = 1450
|
||||
sig = 1460
|
||||
|
||||
label = IPSec or GRE
|
||||
sig = 1476
|
||||
|
||||
label = IPIP or SIT
|
||||
sig = 1480
|
||||
|
||||
label = PPTP
|
||||
sig = 1490
|
||||
|
||||
; Really exotic stuff:
|
||||
|
||||
label = AX.25 radio modem
|
||||
sig = 256
|
||||
|
||||
label = SLIP
|
||||
sig = 552
|
||||
|
||||
label = Google
|
||||
sig = 1470
|
||||
|
||||
label = VLAN
|
||||
sig = 1496
|
||||
|
||||
label = Ericsson HIS modem
|
||||
sig = 1656
|
||||
|
||||
label = jumbo Ethernet
|
||||
sig = 9000
|
||||
|
||||
; Loopback interfaces on Linux and other systems:
|
||||
|
||||
label = loopback
|
||||
sig = 3924
|
||||
sig = 16384
|
||||
sig = 16436
|
||||
|
||||
; ==================
|
||||
; TCP SYN signatures
|
||||
; ==================
|
||||
|
||||
[tcp:request]
|
||||
|
||||
; -----
|
||||
; Linux
|
||||
; -----
|
||||
|
||||
label = s:unix:Linux:3.11 and newer
|
||||
sig = *:64:0:*:mss*20,10:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*20,7:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:3.1-3.10
|
||||
sig = *:64:0:*:mss*10,4:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*10,5:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*10,6:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*10,7:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
; Fun fact: 2.6 with ws=7 seems to be really common for Amazon EC2, while 8 is
|
||||
; common for Yahoo and Twitter. There seem to be some other (rare) uses, though,
|
||||
; so not I'm not flagging these signatures in a special way.
|
||||
|
||||
label = s:unix:Linux:2.6.x
|
||||
sig = *:64:0:*:mss*4,6:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*4,7:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*4,8:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:2.4.x
|
||||
sig = *:64:0:*:mss*4,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*4,1:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*4,2:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
; No real traffic seen for 2.2 & 2.0, signatures extrapolated from p0f2 data:
|
||||
|
||||
label = s:unix:Linux:2.2.x
|
||||
sig = *:64:0:*:mss*11,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*20,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*22,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:2.0
|
||||
sig = *:64:0:*:mss*12,0:mss::0
|
||||
sig = *:64:0:*:16384,0:mss::0
|
||||
|
||||
; Just to keep people testing locally happy (IPv4 & IPv6):
|
||||
|
||||
label = s:unix:Linux:3.x (loopback)
|
||||
sig = *:64:0:16396:mss*2,4:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:16376:mss*2,4:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:2.6.x (loopback)
|
||||
sig = *:64:0:16396:mss*2,2:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:16376:mss*2,2:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:2.4.x (loopback)
|
||||
sig = *:64:0:16396:mss*2,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = s:unix:Linux:2.2.x (loopback)
|
||||
sig = *:64:0:3884:mss*8,0:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
; Various distinctive flavors of Linux:
|
||||
|
||||
label = s:unix:Linux:2.6.x (Google crawler)
|
||||
sig = 4:64:0:1430:mss*4,6:mss,sok,ts,nop,ws::0
|
||||
|
||||
label = s:unix:Linux:(Android)
|
||||
sig = *:64:0:*:mss*44,1:mss,sok,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*44,3:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
; Catch-all rules:
|
||||
|
||||
label = g:unix:Linux:3.x
|
||||
sig = *:64:0:*:mss*10,*:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = g:unix:Linux:2.4.x-2.6.x
|
||||
sig = *:64:0:*:mss*4,*:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = g:unix:Linux:2.2.x-3.x
|
||||
sig = *:64:0:*:*,*:mss,sok,ts,nop,ws:df,id+:0
|
||||
|
||||
label = g:unix:Linux:2.2.x-3.x (no timestamps)
|
||||
sig = *:64:0:*:*,*:mss,nop,nop,sok,nop,ws:df,id+:0
|
||||
|
||||
label = g:unix:Linux:2.2.x-3.x (barebone)
|
||||
sig = *:64:0:*:*,0:mss:df,id+:0
|
||||
|
||||
; -------
|
||||
; Windows
|
||||
; -------
|
||||
|
||||
label = s:win:Windows:XP
|
||||
sig = *:128:0:*:16384,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,1:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,2:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
label = s:win:Windows:7 or 8
|
||||
sig = *:128:0:*:8192,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:8192,2:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:8192,8:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:8192,2:mss,nop,ws,sok,ts:df,id+:0
|
||||
|
||||
; Robots with distinctive fingerprints:
|
||||
|
||||
label = s:win:Windows:7 (Websense crawler)
|
||||
sig = *:64:0:1380:mss*4,6:mss,nop,nop,ts,nop,ws:df,id+:0
|
||||
sig = *:64:0:1380:mss*4,7:mss,nop,nop,ts,nop,ws:df,id+:0
|
||||
|
||||
; Catch-all:
|
||||
|
||||
label = g:win:Windows:NT kernel 5.x
|
||||
sig = *:128:0:*:16384,*:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,*:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:16384,*:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,*:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
label = g:win:Windows:NT kernel 6.x
|
||||
sig = *:128:0:*:8192,*:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:8192,*:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
label = g:win:Windows:NT kernel
|
||||
sig = *:128:0:*:*,*:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:*,*:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
; ------
|
||||
; Mac OS
|
||||
; ------
|
||||
|
||||
label = s:unix:Mac OS X:10.x
|
||||
sig = *:64:0:*:65535,1:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
|
||||
label = s:unix:MacOS X:10.9 or newer (sometimes iPhone or iPad)
|
||||
sig = *:64:0:*:65535,4:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
|
||||
label = s:unix:iOS:iPhone or iPad
|
||||
sig = *:64:0:*:65535,2:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
|
||||
; Catch-all rules:
|
||||
|
||||
label = g:unix:Mac OS X:
|
||||
sig = *:64:0:*:65535,*:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
|
||||
; -------
|
||||
; FreeBSD
|
||||
; -------
|
||||
|
||||
label = s:unix:FreeBSD:9.x or newer
|
||||
sig = *:64:0:*:65535,6:mss,nop,ws,sok,ts:df,id+:0
|
||||
|
||||
label = s:unix:FreeBSD:8.x
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws,sok,ts:df,id+:0
|
||||
|
||||
; Catch-all rules:
|
||||
|
||||
label = g:unix:FreeBSD:
|
||||
sig = *:64:0:*:65535,*:mss,nop,ws,sok,ts:df,id+:0
|
||||
|
||||
; -------
|
||||
; OpenBSD
|
||||
; -------
|
||||
|
||||
label = s:unix:OpenBSD:3.x
|
||||
sig = *:64:0:*:16384,0:mss,nop,nop,sok,nop,ws,nop,nop,ts:df,id+:0
|
||||
|
||||
label = s:unix:OpenBSD:4.x-5.x
|
||||
sig = *:64:0:*:16384,3:mss,nop,nop,sok,nop,ws,nop,nop,ts:df,id+:0
|
||||
|
||||
; -------
|
||||
; Solaris
|
||||
; -------
|
||||
|
||||
label = s:unix:Solaris:8
|
||||
sig = *:64:0:*:32850,1:nop,ws,nop,nop,ts,nop,nop,sok,mss:df,id+:0
|
||||
|
||||
label = s:unix:Solaris:10
|
||||
sig = *:64:0:*:mss*34,0:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
; -------
|
||||
; OpenVMS
|
||||
; -------
|
||||
|
||||
label = s:unix:OpenVMS:8.x
|
||||
sig = 4:128:0:1460:mtu*2,0:mss,nop,ws::0
|
||||
|
||||
label = s:unix:OpenVMS:7.x
|
||||
sig = 4:64:0:1460:61440,0:mss,nop,ws::0
|
||||
|
||||
; --------
|
||||
; NeXTSTEP
|
||||
; --------
|
||||
|
||||
label = s:other:NeXTSTEP:
|
||||
sig = 4:64:0:1024:mss*4,0:mss::0
|
||||
|
||||
; -----
|
||||
; Tru64
|
||||
; -----
|
||||
|
||||
label = s:unix:Tru64:4.x
|
||||
sig = 4:64:0:1460:32768,0:mss,nop,ws:df,id+:0
|
||||
|
||||
; ----
|
||||
; NMap
|
||||
; ----
|
||||
|
||||
label = s:!:NMap:SYN scan
|
||||
sys = @unix,@win
|
||||
sig = *:64-:0:1460:1024,0:mss::0
|
||||
sig = *:64-:0:1460:2048,0:mss::0
|
||||
sig = *:64-:0:1460:3072,0:mss::0
|
||||
sig = *:64-:0:1460:4096,0:mss::0
|
||||
|
||||
label = s:!:NMap:OS detection
|
||||
sys = @unix,@win
|
||||
sig = *:64-:0:265:512,0:mss,sok,ts:ack+:0
|
||||
sig = *:64-:0:0:4,10:sok,ts,ws,eol+0:ack+:0
|
||||
sig = *:64-:0:1460:1,10:ws,nop,mss,ts,sok:ack+:0
|
||||
sig = *:64-:0:536:16,10:mss,sok,ts,ws,eol+0:ack+:0
|
||||
sig = *:64-:0:640:4,5:ts,nop,nop,ws,nop,mss:ack+:0
|
||||
sig = *:64-:0:1400:63,0:mss,ws,sok,ts,eol+0:ack+:0
|
||||
sig = *:64-:0:265:31337,10:ws,nop,mss,ts,sok:ack+:0
|
||||
sig = *:64-:0:1460:3,10:ws,nop,mss,sok,nop,nop:ecn,uptr+:0
|
||||
|
||||
; -----------
|
||||
; p0f-sendsyn
|
||||
; -----------
|
||||
|
||||
; These are intentionally goofy, to avoid colliding with any sensible real-world
|
||||
; stacks. Do not tag these signatures as userspace, unless you want p0f to hide
|
||||
; the responses!
|
||||
|
||||
label = s:unix:p0f:sendsyn utility
|
||||
sig = *:192:0:1331:1337,0:mss,nop,eol+18::0
|
||||
sig = *:192:0:1331:1337,0:mss,ts,nop,eol+8::0
|
||||
sig = *:192:0:1331:1337,5:mss,ws,nop,eol+15::0
|
||||
sig = *:192:0:1331:1337,0:mss,sok,nop,eol+16::0
|
||||
sig = *:192:0:1331:1337,5:mss,ws,ts,nop,eol+5::0
|
||||
sig = *:192:0:1331:1337,0:mss,sok,ts,nop,eol+6::0
|
||||
sig = *:192:0:1331:1337,5:mss,ws,sok,nop,eol+13::0
|
||||
sig = *:192:0:1331:1337,5:mss,ws,sok,ts,nop,eol+3::0
|
||||
|
||||
; -------------
|
||||
; Odds and ends
|
||||
; -------------
|
||||
|
||||
label = s:other:Blackberry:
|
||||
sig = *:128:0:1452:65535,0:mss,nop,nop,sok,nop,nop,ts::0
|
||||
|
||||
label = s:other:Nintendo:3DS
|
||||
sig = *:64:0:1360:32768,0:mss,nop,nop,sok:df,id+:0
|
||||
|
||||
label = s:other:Nintendo:Wii
|
||||
sig = 4:64:0:1460:32768,0:mss,nop,nop,sok:df,id+:0
|
||||
|
||||
label = s:unix:BaiduSpider:
|
||||
sig = *:64:0:1460:mss*4,7:mss,sok,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,ws:df,id+:0
|
||||
sig = *:64:0:1460:mss*4,2:mss,sok,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,ws:df,id+:0
|
||||
|
||||
; ======================
|
||||
; TCP SYN+ACK signatures
|
||||
; ======================
|
||||
|
||||
[tcp:response]
|
||||
|
||||
; -----
|
||||
; Linux
|
||||
; -----
|
||||
|
||||
; The variation here is due to ws, sok, or ts being adaptively removed if the
|
||||
; client initiating the connection doesn't support them. Use tools/p0f-sendsyn
|
||||
; to get a full set of up to 8 signatures.
|
||||
|
||||
|
||||
label = s:unix:Linux:3.x
|
||||
sig = *:64:0:*:mss*10,0:mss:df:0
|
||||
sig = *:64:0:*:mss*10,0:mss,sok,ts:df:0
|
||||
sig = *:64:0:*:mss*10,0:mss,nop,nop,ts:df:0
|
||||
sig = *:64:0:*:mss*10,0:mss,nop,nop,sok:df:0
|
||||
sig = *:64:0:*:mss*10,*:mss,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*10,*:mss,sok,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*10,*:mss,nop,nop,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*10,*:mss,nop,nop,sok,nop,ws:df:0
|
||||
|
||||
label = s:unix:Linux:2.4-2.6
|
||||
sig = *:64:0:*:mss*4,0:mss:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,sok,ts:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,nop,nop,ts:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,nop,nop,sok:df:0
|
||||
|
||||
label = s:unix:Linux:2.4.x
|
||||
sig = *:64:0:*:mss*4,0:mss,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,sok,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,nop,nop,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,0:mss,nop,nop,sok,nop,ws:df:0
|
||||
|
||||
label = s:unix:Linux:2.6.x
|
||||
sig = *:64:0:*:mss*4,*:mss,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,*:mss,sok,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,*:mss,nop,nop,ts,nop,ws:df:0
|
||||
sig = *:64:0:*:mss*4,*:mss,nop,nop,sok,nop,ws:df:0
|
||||
|
||||
; -------
|
||||
; Windows
|
||||
; -------
|
||||
|
||||
label = s:win:Windows:XP
|
||||
sig = *:128:0:*:65535,0:mss:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,ws:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,nop,ts:df,id+,ts1-:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,ws,nop,nop,ts:df,id+,ts1-:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,nop,ts,nop,nop,sok:df,id+,ts1-:0
|
||||
sig = *:128:0:*:65535,0:mss,nop,ws,nop,nop,ts,nop,nop,sok:df,id+,ts1-:0
|
||||
|
||||
sig = *:128:0:*:16384,0:mss:df,id+:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,ws:df,id+:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,nop,ts:df,id+,ts1-:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,ws,nop,nop,ts:df,id+,ts1-:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,nop,ts,nop,nop,sok:df,id+,ts1-:0
|
||||
sig = *:128:0:*:16384,0:mss,nop,ws,nop,nop,ts,nop,nop,sok:df,id+,ts1-:0
|
||||
|
||||
label = s:win:Windows:7 or 8
|
||||
sig = *:128:0:*:8192,0:mss:df,id+:0
|
||||
sig = *:128:0:*:8192,0:mss,sok,ts:df,id+:0
|
||||
sig = *:128:0:*:8192,8:mss,nop,ws:df,id+:0
|
||||
sig = *:128:0:*:8192,0:mss,nop,nop,ts:df,id+:0
|
||||
sig = *:128:0:*:8192,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:128:0:*:8192,8:mss,nop,ws,sok,ts:df,id+:0
|
||||
sig = *:128:0:*:8192,8:mss,nop,ws,nop,nop,ts:df,id+:0
|
||||
sig = *:128:0:*:8192,8:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
; -------
|
||||
; FreeBSD
|
||||
; -------
|
||||
|
||||
label = s:unix:FreeBSD:9.x
|
||||
sig = *:64:0:*:65535,6:mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:65535,6:mss,nop,ws,sok,ts:df,id+:0
|
||||
sig = *:64:0:*:65535,6:mss,nop,ws,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,6:mss,nop,ws,nop,nop,ts:df,id+:0
|
||||
|
||||
label = s:unix:FreeBSD:8.x
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws,sok,ts:df,id+:0
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,3:mss,nop,ws,nop,nop,ts:df,id+:0
|
||||
|
||||
label = s:unix:FreeBSD:8.x-9.x
|
||||
sig = *:64:0:*:65535,0:mss,sok,ts:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,nop,ts:df,id+:0
|
||||
|
||||
; -------
|
||||
; OpenBSD
|
||||
; -------
|
||||
|
||||
label = s:unix:OpenBSD:5.x
|
||||
sig = *:64:0:1460:16384,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:64:0:1460:16384,3:mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:1460:16384,3:mss,nop,nop,sok,nop,ws:df,id+:0
|
||||
sig = *:64:0:1460:16384,0:mss,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:1460:16384,0:mss,nop,nop,sok,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:1460:16384,3:mss,nop,ws,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:1460:16384,3:mss,nop,nop,sok,nop,ws,nop,nop,ts:df,id+:0
|
||||
|
||||
; This one resembles Windows, but almost nobody will be seeing it:
|
||||
; sig = *:64:0:1460:16384,0:mss:df,id+:0
|
||||
|
||||
; --------
|
||||
; Mac OS X
|
||||
; --------
|
||||
|
||||
label = s:unix:Mac OS X:10.x
|
||||
sig = *:64:0:*:65535,0:mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,ws,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,ws,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
sig = *:64:0:*:65535,0:mss,nop,ws,nop,nop,ts,sok,eol+1:df,id+:0
|
||||
|
||||
; Ditto:
|
||||
; sig = *:64:0:*:65535,0:mss:df,id+:0
|
||||
|
||||
; -------
|
||||
; Solaris
|
||||
; -------
|
||||
|
||||
label = s:unix:Solaris:6
|
||||
sig = 4:255:0:*:mss*7,0:mss:df,id+:0
|
||||
sig = 4:255:0:*:mss*7,0:nop,ws,mss:df,id+:0
|
||||
sig = 4:255:0:*:mss*7,0:nop,nop,ts,mss:df,id+:0
|
||||
sig = 4:255:0:*:mss*7,0:nop,nop,ts,nop,ws,mss:df,id+:0
|
||||
|
||||
label = s:unix:Solaris:8
|
||||
sig = *:64:0:*:mss*19,0:mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,ws,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,nop,ts,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,nop,sok,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,nop,ts,nop,ws,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,ws,nop,nop,sok,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,nop,ts,nop,nop,sok,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*19,0:nop,nop,ts,nop,ws,nop,nop,sok,mss:df,id+:0
|
||||
|
||||
label = s:unix:Solaris:10
|
||||
sig = *:64:0:*:mss*37,0:mss:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:nop,nop,ts,mss:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:nop,nop,ts,mss,nop,ws:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:nop,nop,ts,mss,nop,nop,sok:df,id+:0
|
||||
sig = *:64:0:*:mss*37,0:nop,nop,ts,mss,nop,ws,nop,nop,sok:df,id+:0
|
||||
|
||||
; -----
|
||||
; HP-UX
|
||||
; -----
|
||||
|
||||
label = s:unix:HP-UX:11.x
|
||||
sig = *:64:0:*:32768,0:mss:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,ws,nop:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,nop,nop,sok:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,ws,nop,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,nop,nop,sok,ws,nop:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,nop,nop,sok,nop,nop,ts:df,id+:0
|
||||
sig = *:64:0:*:32768,0:mss,nop,nop,sok,ws,nop,nop,nop,ts:df,id+:0
|
||||
|
||||
; -------
|
||||
; OpenVMS
|
||||
; -------
|
||||
|
||||
label = s:other:OpenVMS:7.x
|
||||
sig = 4:64:0:1460:3993,0:mss::0
|
||||
sig = 4:64:0:1460:3993,0:mss,nop,ws::0
|
||||
|
||||
; -----
|
||||
; Tru64
|
||||
; -----
|
||||
|
||||
label = s:unix:Tru64:4.x
|
||||
sig = 4:64:0:1460:mss*25,0:mss,nop,ws:df,id+:0
|
||||
sig = 4:64:0:1460:mss*25,0:mss:df,id+:0
|
||||
|
||||
; ======================
|
||||
; HTTP client signatures
|
||||
; ======================
|
||||
|
||||
; Safari and Firefox are frequently seen using HTTP/1.0 when going through
|
||||
; proxies; this is far less common for MSIE, Chrome, etc. I wildcarded some of
|
||||
; the signatures accordingly.
|
||||
;
|
||||
; Also note that there are several proxies that mess with HTTP headers for no
|
||||
; reason. For example, BlueCoat proxy appears to change 'keep-alive' to
|
||||
; 'Keep-Alive' for a tiny percentage of users (why?!).
|
||||
|
||||
[http:request]
|
||||
|
||||
ua_os = Linux,Windows,iOS=[iPad],iOS=[iPhone],Mac OS X,FreeBSD,OpenBSD,NetBSD,Solaris=[SunOS]
|
||||
|
||||
; -------
|
||||
; Firefox
|
||||
; -------
|
||||
|
||||
label = s:!:Firefox:2.x
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip,deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],Keep-Alive=[300],Connection=[keep-alive]::Firefox/
|
||||
|
||||
label = s:!:Firefox:3.x
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip,deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],Keep-Alive=[115],Connection=[keep-alive],?Referer::Firefox/
|
||||
|
||||
label = s:!:Firefox:4.x
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],Keep-Alive=[115],Connection=[keep-alive],?Referer::Firefox/
|
||||
|
||||
; I have no idea where this 'UTF-8' variant comes from, but it happens on *BSD.
|
||||
; Likewise, no clue why Referer is in a different place for some users.
|
||||
|
||||
label = s:!:Firefox:5.x-9.x
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],?DNT=[1],Connection=[keep-alive],?Referer:Keep-Alive:Firefox/
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[UTF-8,*],?DNT=[1],Connection=[keep-alive],?Referer:Keep-Alive:Firefox/
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[UTF-8,*],?DNT=[1],?Referer,Connection=[keep-alive]:Keep-Alive:Firefox/
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],?DNT=[1],?Referer,Connection=[keep-alive]:Keep-Alive:Firefox/
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language,Accept-Encoding=[gzip, deflate],Accept-Charset=[utf-8;q=0.7,*;q=0.7],?Referer,?DNT=[1],Connection=[keep-alive]:Keep-Alive:Firefox/
|
||||
|
||||
label = s:!:Firefox:10.x or newer
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language=[;q=],Accept-Encoding=[gzip, deflate],?DNT=[1],Connection=[keep-alive],?Referer:Accept-Charset,Keep-Alive:Firefox/
|
||||
sig = *:Host,User-Agent,Accept=[,*/*;q=],?Accept-Language=[;q=],Accept-Encoding=[gzip, deflate],?DNT=[1],?Referer,Connection=[keep-alive]:Accept-Charset,Keep-Alive:Firefox/
|
||||
|
||||
; There is this one weird case where Firefox 10.x is indistinguishable
|
||||
; from Safari 5.1:
|
||||
|
||||
label = s:!:Firefox:10.x or Safari 5.x
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[xml;q=0.9,*/*;q=0.8],Accept-Language,Accept-Encoding=[gzip, deflate],Connection=[keep-alive]:Keep-Alive,Accept-Charset,DNT,Referer:Gecko
|
||||
|
||||
; ----
|
||||
; MSIE
|
||||
; ----
|
||||
|
||||
; MSIE 11 no longer sends the 'MSIE' part in U-A, but we don't consider
|
||||
; U-A to be a robust signal for fingerprinting, so no dice.
|
||||
|
||||
label = s:!:MSIE:8 or newer
|
||||
sys = Windows
|
||||
sig = 1:Accept=[*/*],?Referer,?Accept-Language,User-Agent,Accept-Encoding=[gzip, deflate],Host,Connection=[Keep-Alive]:Keep-Alive,Accept-Charset,UA-CPU:Trident/
|
||||
sig = 1:Accept=[*/*],?Referer,?Accept-Language,Accept-Encoding=[gzip, deflate],User-Agent,Host,Connection=[Keep-Alive]:Keep-Alive,Accept-Charset:(compatible; MSIE
|
||||
|
||||
label = s:!:MSIE:7
|
||||
sys = Windows
|
||||
sig = 1:Accept=[*/*],?Referer,?Accept-Language,UA-CPU,User-Agent,Accept-Encoding=[gzip, deflate],Host,Connection=[Keep-Alive]:Keep-Alive,Accept-Charset:(compatible; MSIE
|
||||
|
||||
; TODO: Check if this one ever uses Accept-Language, etc. Also try to find MSIE 5.
|
||||
|
||||
label = s:!:MSIE:6
|
||||
sys = Windows
|
||||
sig = 0:Accept=[*/*],?Referer,User-Agent,Host:Keep-Alive,Connection,Accept-Encoding,Accept-Language,Accept-Charset:(compatible; MSIE
|
||||
sig = 1:Accept=[*/*],Connection=[Keep-Alive],Host,?Pragma=[no-cache],?Range,?Referer,User-Agent:Keep-Alive,Accept-Encoding,Accept-Language,Accept-Charset:(compatible; MSIE
|
||||
|
||||
; ------
|
||||
; Chrome
|
||||
; ------
|
||||
|
||||
label = s:!:Chrome:11.x to 26.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],User-Agent,Accept=[*/*],?Referer,Accept-Encoding=[gzip,deflate,sdch],Accept-Language,Accept-Charset=[utf-8;q=0.7,*;q=0.3]:: Chrom
|
||||
sig = 1:Host,Connection=[keep-alive],User-Agent,Accept=[*/*],?Referer,Accept-Encoding=[gzip,deflate,sdch],Accept-Language,Accept-Charset=[UTF-8,*;q=0.5]:: Chrom
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],?Referer,Accept-Encoding=[gzip,deflate,sdch],Accept-Language,Accept-Charset=[utf-8;q=0.7,*;q=0.3],Connection=[keep-alive]::Chrom
|
||||
|
||||
label = s:!:Chrome:27.x to 42.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],Accept=[*/*],User-Agent,?Referer,Accept-Encoding=[gzip,deflate,sdch],Accept-Language:Accept-Charset,Keep-Alive: Chrom
|
||||
|
||||
label = s:!:Chrome:43.x or 50.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],Accept=[*/*],User-Agent,?Referer,Accept-Encoding=[gzip, deflate, sdch],Accept-Language:Accept-Charset,Keep-Alive: Chrom
|
||||
|
||||
label = s:!:Chrome:51.x or newer
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],Upgrade-Insecure-Requests=[1],User-Agent,Accept=[*/*],Accept-Encoding=[gzip, deflate, sdch],Accept-Language:Accept-Charset,Keep-Alive: Chrom
|
||||
|
||||
; -----
|
||||
; Opera
|
||||
; -----
|
||||
|
||||
label = s:!:Opera:19.x or newer
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],Accept=[*/*;q=0.8],User-Agent,Accept-Encoding=[gzip,deflate,lzma,sdch],Accept-Language=[;q=0.]:Accept-Charset,Keep-Alive:OPR/
|
||||
|
||||
label = s:!:Opera:15.x-18.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:Host,Connection=[keep-alive],Accept=[*/*;q=0.8],User-Agent,Accept-Encoding=[gzip, deflate],Accept-Language=[;q=0.]:Accept-Charset,Keep-Alive:OPR/
|
||||
|
||||
label = s:!:Opera:11.x-14.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:User-Agent,Host,Accept=[*/*;q=0.1],?Accept-Language=[;q=0.],Accept-Encoding=[gzip, deflate],Connection=[Keep-Alive]:Accept-Charset,X-OperaMini-Phone-UA:) Presto/
|
||||
|
||||
label = s:!:Opera:10.x
|
||||
sys = Windows,@unix
|
||||
sig = 1:User-Agent,Host,Accept=[*/*;q=0.1],Accept-Language=[;q=0.],Accept-Charset=[utf-8, utf-16, *;q=0.1],Accept-Encoding=[deflate, gzip, x-gzip, identity, *;q=0],Connection=[Keep-Alive]::Presto/
|
||||
sig = 1:User-Agent,Host,Accept=[*/*;q=0.1],Accept-Language=[en],Accept-Encoding=[gzip, deflate],Connection=[Keep-Alive]:Accept-Charset:Opera/
|
||||
|
||||
label = s:!:Opera:Mini
|
||||
sys = Linux
|
||||
sig = 1:User-Agent,Host,Accept=[*/*;q=0.1],Accept-Language=[;q=0.],Accept-Encoding=[gzip, deflate],Connection=[Keep-Alive],X-OperaMini-Phone-UA,X-OperaMini-Features,X-OperaMini-Phone,x-forwarded-for:Accept-Charset:Opera Mini/
|
||||
|
||||
label = s:!:Opera:on Nintendo Wii
|
||||
sys = Nintendo
|
||||
sig = 1:User-Agent,Host,Accept=[*/*;q=0.1],Accept-Language=[en],Accept-Charset=[iso-8859-1, utf-8, utf-16, *;q=0.1],Accept-Encoding=[deflate, gzip, x-gzip, identity, *;q=0],Connection=[Keep-Alive]::Nintendo
|
||||
|
||||
; ---------------
|
||||
; Android browser
|
||||
; ---------------
|
||||
|
||||
label = s:!:Android:2.x
|
||||
sys = Linux
|
||||
sig = 1:Host,Accept-Encoding=[gzip],Accept-Language,User-Agent,Accept=[,*/*;q=0.5],Accept-Charset=[utf-16, *;q=0.7]:Connection:Android
|
||||
sig = 1:Host,Connection=[keep-alive],Accept-Encoding=[gzip],Accept-Language,User-Agent,Accept=[,*/*;q=0.5],Accept-Charset=[utf-16, *;q=0.7]::Android
|
||||
sig = 1:Host,Accept-Encoding=[gzip],Accept-Language=[en-US],Accept=[*/*;q=0.5],User-Agent,Accept-Charset=[utf-16, *;q=0.7]:Connection:Android
|
||||
|
||||
label = s:!:Android:4.x
|
||||
sys = Linux
|
||||
sig = 1:Host,Connection=[keep-alive],Accept=[,*/*;q=0.8],User-Agent,Accept-Encoding=[gzip,deflate],Accept-Language,Accept-Charset=[utf-16, *;q=0.7]::Android
|
||||
|
||||
; ------
|
||||
; Safari
|
||||
; ------
|
||||
|
||||
label = s:!:Safari:7 or newer
|
||||
sys = @unix
|
||||
sig = *:Host,Accept-Encoding=[gzip, deflate],Connection=[keep-alive],Accept=[*/*],User-Agent,Accept-Language,?Referer,?DNT:Accept-Charset,Keep-Alive:KHTML, like Gecko)
|
||||
|
||||
label = s:!:Safari:5.1-6
|
||||
sys = Windows,@unix
|
||||
sig = *:Host,User-Agent,Accept=[*/*],?Referer,Accept-Language,Accept-Encoding=[gzip, deflate],Connection=[keep-alive]:Accept-Charset:KHTML, like Gecko)
|
||||
sig = *:Host,User-Agent,Accept=[*/*],?Referer,Accept-Encoding=[gzip, deflate],Accept-Language,Connection=[keep-alive]:Accept-Charset:KHTML, like Gecko)
|
||||
|
||||
label = s:!:Safari:5.0 or earlier
|
||||
sys = Mac OS X
|
||||
sig = 0:Host,User-Agent,Connection=[close]:Accept,Accept-Encoding,Accept-Language,Accept-Charset:CFNetwork/
|
||||
|
||||
; ---------
|
||||
; Konqueror
|
||||
; ---------
|
||||
|
||||
label = s:!:Konqueror:4.6 or earlier
|
||||
sys = Linux,FreeBSD,OpenBSD
|
||||
sig = 1:Host,Connection=[Keep-Alive],User-Agent,?Pragma,?Cache-control,Accept=[*/*],Accept-Encoding=[x-gzip, x-deflate, gzip, deflate],Accept-Charset=[;q=0.5, *;q=0.5],Accept-Language::Konqueror/
|
||||
|
||||
label = s:!:Konqueror:4.7 or newer
|
||||
sys = Linux,FreeBSD,OpenBSD
|
||||
sig = 1:Host,Connection=[keep-alive],User-Agent,Accept=[*/*],Accept-Encoding=[gzip, deflate, x-gzip, x-deflate],Accept-Charset=[,*;q=0.5],Accept-Language::Konqueror/
|
||||
|
||||
; -------------------
|
||||
; Major search robots
|
||||
; -------------------
|
||||
|
||||
label = s:!:BaiduSpider:
|
||||
sys = BaiduSpider
|
||||
sig = 1:Host,Connection=[close],User-Agent,Accept=[*/*]:Accept-Encoding,Accept-Language,Accept-Charset:Baiduspider-image
|
||||
sig = 1:Host,Accept-Language=[zh-cn],Connection=[close],User-Agent:Accept,Accept-Encoding,Accept-Charset:Baiduspider
|
||||
sig = 1:Host,Connection=[close],User-Agent,Accept-Language=[zh-cn,zh-tw],Accept-Encoding=[gzip],Accept=[*/*]:Accept-Charset:Baiduspider
|
||||
sig = 1:Host,Connection=[close],User-Agent,Accept-Language=[tr-TR],Accept-Encoding=[gzip],Accept=[*/*]:Accept-Charset:Baiduspider
|
||||
sig = 1:Host,Connection=[close],User-Agent,Accept-Encoding=[gzip],?Accept-Language=[zh-cn,zh-tw],Accept=[*/*]:Accept-Charset:Baiduspider
|
||||
sig = 1:Host,Connection=[close],User-Agent,Accept-Encoding=[gzip],Accept-Language=[tr-TR],Accept=[*/*]:Accept-Charset:Baiduspider
|
||||
|
||||
label = s:!:Googlebot:
|
||||
sys = Linux
|
||||
sig = 1:Host,Connection=[Keep-alive],Accept=[*/*],From=[googlebot(at)googlebot.com],User-Agent,Accept-Encoding=[gzip,deflate],?If-Modified-Since:Accept-Language,Accept-Charset:Googlebot
|
||||
sig = 1:Host,Connection=[Keep-alive],Accept=[text/plain],Accept=[text/html],From=[googlebot(at)googlebot.com],User-Agent,Accept-Encoding=[gzip,deflate]:Accept-Language,Accept-Charset:Googlebot
|
||||
|
||||
label = s:!:Googlebot:feed fetcher
|
||||
sys = Linux
|
||||
sig = 1:Host,Connection=[Keep-alive],Accept=[*/*],User-Agent,Accept-Encoding=[gzip,deflate],?If-Modified-Since:Accept-Language,Accept-Charset:-Google
|
||||
sig = 1:User-Agent,?X-shindig-dos=[on],Cache-Control,Host,?X-Forwarded-For,Accept-Encoding=[gzip],?Accept-Language:Connection,Accept,Accept-Charset:Feedfetcher-Google
|
||||
|
||||
label = s:!:Bingbot:
|
||||
sys = Windows
|
||||
sig = 1:Cache-Control,Connection=[Keep-Alive],Pragma=[no-cache],Accept=[*/*],Accept-Encoding,Host,User-Agent:Accept-Language,Accept-Charset:bingbot/
|
||||
|
||||
; MSNbot has a really silly Accept header, only a tiny part of which is preserved here:
|
||||
|
||||
label = s:!:MSNbot:
|
||||
sys = Windows
|
||||
sig = 1:Connection=[Close],Accept,Accept-Encoding=[gzip, deflate],From=[msnbot(at)microsoft.com],Host,User-Agent:Accept-Language,Accept-Charset:msnbot
|
||||
|
||||
label = s:!:Yandex:crawler
|
||||
sys = FreeBSD
|
||||
sig = 1:Host,Connection=[Keep-Alive],Accept=[*/*],Accept-Encoding=[gzip,deflate],Accept-Language=[en-us, en;q=0.7, *;q=0.01],User-Agent,From=[support@search.yandex.ru]:Accept-Charset:YandexBot/
|
||||
sig = 1:Host,Connection=[Keep-Alive],Accept=[image/jpeg, image/pjpeg, image/png, image/gif],User-Agent,From=[support@search.yandex.ru]:Accept-Encoding,Accept-Language,Accept-Charset:YandexImages/
|
||||
sig = 1:Host,Connection=[Keep-Alive],User-Agent,From=[support@search.yandex.ru]:Accept,Accept-Encoding,Accept-Language,Accept-Charset:YandexBot/
|
||||
|
||||
label = s:!:Yahoo:crawler
|
||||
sys = Linux
|
||||
sig = 0:Host,User-Agent,Accept=[,image/png,*/*;q=0.5],Accept-Language=[en-us,en;q=0.5],Accept-Encoding=[gzip],Accept-Charset=[,utf-8;q=0.7,*;q=0.7]:Connection:Slurp
|
||||
|
||||
; -----------------
|
||||
; Misc other robots
|
||||
; -----------------
|
||||
|
||||
label = s:!:Flipboard:crawler
|
||||
sys = Linux
|
||||
sig = 1:User-Agent,Accept-Language=[en-us,en;q=0.5],Accept-Charset=[;q=0.7,*;q=0.5],Accept-Encoding=[gzip],Host,Accept=[*; q=.2, */*; q=.2],Connection=[keep-alive]::FlipboardProxy
|
||||
sig = 1:Accept-language=[en-us,en;q=0.5],Accept-encoding=[gzip],Accept=[;q=0.9,*/*;q=0.8],User-agent,Host:User-Agent,Connection,Accept-Encoding,Accept-Language,Accept-Charset:FlipboardProxy
|
||||
|
||||
label = s:!:Spinn3r:crawler
|
||||
sys = Linux
|
||||
sig = 1:User-Agent,Accept-Encoding=[gzip],Host,Accept=[*; q=.2, */*; q=.2],Connection=[close]:Accept-Language,Accept-Charset:Spinn3r
|
||||
|
||||
label = s:!:Facebook:crawler
|
||||
sys = Linux
|
||||
sig = 1:User-Agent,Host,Accept=[*/*],Accept-Encoding=[deflate, gzip],Connection=[close]:Accept-Language,Accept-Charset:facebookexternalhit/
|
||||
sig = 1:User-Agent,Host,Accept=[*/*],Connection=[close]:Accept-Encoding,Accept-Language,Accept-Charset:facebookexternalhit/
|
||||
|
||||
label = s:!:paper.li:crawler
|
||||
sys = Linux
|
||||
sig = 1:Accept-Language=[en-us,en;q=0.5],Accept=[*/*],User-Agent,Connection=[close],Accept-Encoding=[gzip,identity],?Referer,Host,Accept-Charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7]::PaperLiBot/
|
||||
|
||||
label = s:!:Twitter:crawler
|
||||
sys = Linux
|
||||
sig = 1:User-Agent=[Twitterbot/],Host,Accept=[*; q=.2, */*; q=.2],Cache-Control,Connection=[keep-alive]:Accept-Encoding,Accept-Language,Accept-Charset:Twitterbot/
|
||||
|
||||
label = s:!:linkdex:crawler
|
||||
sys = Linux
|
||||
sig = 0:Host,Connection=[Keep-Alive],User-Agent,Accept-Encoding=[gzip,deflate]:Accept,Accept-Language,Accept-Charset:linkdex.com/
|
||||
|
||||
label = s:!:Yodaobot:
|
||||
sys = Linux
|
||||
sig = 1:Accept-Encoding=[identity;q=0.5, *;q=0.1],User-Agent,Host:Connection,Accept,Accept-Language,Accept-Charset:YodaoBot/
|
||||
|
||||
label = s:!:Tweetmeme:crawler
|
||||
sys = Linux
|
||||
sig = 1:Host,User-Agent,Accept=[,image/png,*/*;q=0.5],Accept-Language=[en-gb,en;q=0.5],Accept-Charset=[ISO-8859-1,utf-8;q=0.7,*;q=0.7]:Connection,Accept-Encoding:TweetmemeBot/
|
||||
|
||||
label = s:!:Archive.org:crawler
|
||||
sys = Linux
|
||||
sig = 0:User-Agent,Connection=[close],Accept=[application/xml;q=0.9,*/*;q=0.8],Host:Accept-Encoding,Accept-Language,Accept-Charset:archive.org
|
||||
|
||||
label = s:!:Yahoo Pipes:
|
||||
sys = Linux
|
||||
sig = 0:Client-IP,X-Forwarded-For,X-YQL-Depth,User-Agent,Host,Connection=[keep-alive],Via:Accept,Accept-Encoding,Accept-Language,Accept-Charset:Yahoo Pipes
|
||||
sig = 1:Client-IP,X-Forwarded-For,X-YQL-Depth,User-Agent,Host,Via:Connection,Accept,Accept-Encoding,Accept-Language,Accept-Charset:Yahoo Pipes
|
||||
|
||||
label = s:!:Google Web Preview:
|
||||
sys = Linux
|
||||
sig = 1:Referer,User-Agent,Accept-Encoding=[gzip,deflate],Host,X-Forwarded-For:Connection,Accept,Accept-Language,Accept-Charset:Web Preview
|
||||
|
||||
; --------------------------------
|
||||
; Command-line tools and libraries
|
||||
; --------------------------------
|
||||
|
||||
label = s:!:wget:
|
||||
sys = @unix,Windows
|
||||
sig = *:User-Agent,Accept=[*/*],Host,Connection=[Keep-Alive]:Accept-Encoding,Accept-Language,Accept-Charset:Wget/
|
||||
|
||||
label = s:!:Lynx:
|
||||
sys = @unix,Windows
|
||||
sig = 0:Host,Accept=[text/sgml, */*;q=0.01],Accept-Encoding=[gzip, compress],Accept-Language,User-Agent:Connection,Accept-Charset:Lynx/
|
||||
|
||||
label = s:!:curl:
|
||||
sys = @unix,Windows
|
||||
sig = 1:User-Agent,Host,Accept=[*/*]:Connection,Accept-Encoding,Accept-Language,Accept-Charset:curl/
|
||||
|
||||
label = s:!:links:
|
||||
sys = @unix,Windows
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[gzip, deflate, bzip2],Accept-Charset=[us-ascii],Accept-Language=[;q=0.1],Connection=[Keep-Alive]::Links
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[gzip,deflate,bzip2],Accept-Charset=[us-ascii],Accept-Language=[;q=0.1],Connection=[keep-alive]::Links
|
||||
|
||||
label = s:!:elinks:
|
||||
sys = @unix,Windows
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[bzip2, deflate, gzip],Accept-Language:Connection,Accept-Charset:ELinks/
|
||||
|
||||
label = s:!:Java:JRE
|
||||
sys = @unix,@win
|
||||
sig = 1:User-Agent,Host,Accept=[*; q=.2, */*; q=.2],Connection=[keep-alive]:Accept-Encoding,Accept-Language,Accept-Charset:Java/
|
||||
|
||||
label = s:!:Python:urllib
|
||||
sys = @unix,Windows
|
||||
sig = 1:Accept-Encoding=[identity],Host,Connection=[close],User-Agent:Accept,Accept-Language,Accept-Charset:Python-urllib/
|
||||
|
||||
label = s:!:w3m:
|
||||
sys = @unix,Windows
|
||||
sig = 0:User-Agent,Accept=[image/*],Accept-Encoding=[gzip, compress, bzip, bzip2, deflate],Accept-Language=[;q=1.0],Host:Connection,Accept-Charset:w3m/
|
||||
|
||||
label = s:!:libfetch:
|
||||
sys = @unix
|
||||
sig = 1:Host,User-Agent,Connection=[close]:Accept,Accept-Encoding,Accept-Language,Accept-Charset:libfetch/
|
||||
|
||||
; -------------
|
||||
; Odds and ends
|
||||
; -------------
|
||||
|
||||
label = s:!:Google AppEngine:
|
||||
sys = Linux
|
||||
sig = 1:User-Agent,Host,Accept-Encoding=[gzip]:Connection,Accept,Accept-Language,Accept-Charset:AppEngine-Google
|
||||
|
||||
label = s:!:WebOS:
|
||||
sys = Linux
|
||||
sig = 1:Host,Accept-Encoding=[gzip, deflate],User-Agent,Accept=[,*/*;q=0.5],Accept-Language,Accept-Charset=[utf-8;q=0.7,*;q=0.3]:Connection:wOSBrowser
|
||||
|
||||
label = s:!:xxxterm:
|
||||
sys = @unix
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[gzip]:Connection,Accept-Language,Accept-Charset:xxxterm
|
||||
|
||||
label = s:!:Google Desktop:
|
||||
sys = Windows
|
||||
sig = 1:Accept=[*/*],Accept-Encoding=[gzip],User-Agent,Host,Connection=[Keep-Alive]:Accept-Language,Accept-Charset:Google Desktop/
|
||||
|
||||
label = s:!:luakit:
|
||||
sys = @unix
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[gzip],Connection=[Keep-Alive]:Accept-Language,Accept-Charset:luakit
|
||||
|
||||
label = s:!:Epiphany:
|
||||
sys = @unix
|
||||
sig = 1:Host,User-Agent,Accept=[*/*],Accept-Encoding=[gzip],Accept-Language:Connection,Accept-Charset,Keep-Alive:Epiphany/
|
||||
|
||||
; ======================
|
||||
; HTTP server signatures
|
||||
; ======================
|
||||
|
||||
[http:response]
|
||||
|
||||
; ------
|
||||
; Apache
|
||||
; ------
|
||||
|
||||
label = s:!:Apache:2.x
|
||||
sys = @unix,Windows
|
||||
sig = 1:Date,Server,?Last-Modified,?Accept-Ranges=[bytes],?Content-Length,?Content-Range,Keep-Alive=[timeout],Connection=[Keep-Alive],?Transfer-Encoding=[chunked],Content-Type::Apache
|
||||
sig = 1:Date,Server,?Last-Modified,?Accept-Ranges=[bytes],?Content-Length,?Connection=[close],?Transfer-Encoding=[chunked],Content-Type:Keep-Alive:Apache
|
||||
sig = 1:Date,Server,Connection=[Keep-Alive],Keep-Alive=[timeout]:Content-Type,Accept-Ranges:Apache
|
||||
sig = 1:Date,Server,?Last-Modified,?Accept-Ranges=[bytes],?Content-Length,Content-Type,Keep-Alive=[timeout],Connection=[Keep-Alive]::Apache
|
||||
|
||||
label = s:!:Apache:1.x
|
||||
sys = @unix,Windows
|
||||
sig = 1:Server,Content-Type,?Content-Length,Date,Connection=[keep-alive]:Keep-Alive,Accept-Ranges:Apache
|
||||
sig = 1:Server,Content-Type,?Content-Length,Date,Connection=[close]:Keep-Alive,Accept-Ranges:Apache
|
||||
|
||||
; ---
|
||||
; IIS
|
||||
; ---
|
||||
|
||||
label = s:!:IIS:7.x
|
||||
sys = Windows
|
||||
sig = 1:?Content-Length,Content-Type,?Etag,Server,Date:Connection,Keep-Alive,Accept-Ranges:Microsoft-IIS/
|
||||
sig = 1:?Content-Length,Content-Type,?Etag,Server,Date,Connection=[close]:Keep-Alive,Accept-Ranges:Microsoft-IIS/
|
||||
|
||||
; --------
|
||||
; lighttpd
|
||||
; --------
|
||||
|
||||
label = s:!:lighttpd:2.x
|
||||
sys = @unix
|
||||
sig = 1:?ETag,?Last-Modified,Accept-Ranges=[bytes],Content-Type,?Vary,?Content-Length,Date,Server:Connection,Keep-Alive:lighttpd/
|
||||
sig = 1:?ETag,?Last-Modified,Transfer-Encoding=[chunked],Content-Type,?Vary,?Content-Length,Date,Server:Connection,Keep-Alive:lighttpd/
|
||||
|
||||
label = s:!:lighttpd:1.x
|
||||
sys = @unix
|
||||
sig = 1:Content-Type,Accept-Ranges=[bytes],?ETag,?Last-Modified,Date,Server:Connection,Keep-Alive:lighttpd/
|
||||
sig = 1:Content-Type,Transfer-Encoding=[chunked],?ETag,?Last-Modified,Date,Server:Connection,Keep-Alive:lighttpd/
|
||||
sig = 0:Content-Type,Content-Length,Connection=[close],Date,Server:Keep-Alive,Accept-Ranges:lighttpd/
|
||||
|
||||
; -----
|
||||
; nginx
|
||||
; -----
|
||||
|
||||
label = s:!:nginx:1.x
|
||||
sys = @unix
|
||||
sig = 1:Server,Date,Content-Type,?Content-Length,?Last-Modified,Connection=[keep-alive],Keep-Alive=[timeout],Accept-Ranges=[bytes]::nginx/
|
||||
sig = 1:Server,Date,Content-Type,?Content-Length,?Last-Modified,Connection=[close]:Keep-Alive,Accept-Ranges:nginx/
|
||||
|
||||
label = s:!:nginx:0.x
|
||||
sys = @unix
|
||||
sig = 1:Server,Date,Content-Type,?Content-Length,Connection=[keep-alive],?Last-Modified:Keep-Alive,Accept-Ranges:nginx/
|
||||
sig = 1:Server,Date,Content-Type,?Content-Length,Connection=[close],?Last-Modified:Keep-Alive,Accept-Ranges:nginx/
|
||||
|
||||
; -------------
|
||||
; Odds and ends
|
||||
; -------------
|
||||
|
||||
label = s:!:Google Web Server:
|
||||
sys = Linux
|
||||
sig = *:Content-Type,X-Content-Type-Options=[nosniff],Date,Server=[sffe]:Connection,Accept-Ranges,Keep-Alive,Connection:
|
||||
sig = *:Date,Content-Type,Server=[gws]:Connection,Accept-Ranges,Keep-Alive:
|
||||
sig = *:Content-Type,X-Content-Type-Options=[nosniff],Server=[GSE]:Connection,Accept-Ranges,Keep-Alive:
|
48
docker/p0f/p0f.h
Normal file
48
docker/p0f/p0f.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
p0f - exports from the main routine
|
||||
-----------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_P0F_H
|
||||
#define _HAVE_P0F_H
|
||||
|
||||
#include "types.h"
|
||||
#include "process.h"
|
||||
|
||||
extern u8 daemon_mode;
|
||||
extern s32 link_type;
|
||||
extern u32 max_conn, max_hosts, conn_max_age, host_idle_limit, hash_seed;
|
||||
extern u8* read_file;
|
||||
|
||||
void start_observation(char* keyword, u8 field_cnt, u8 to_srv,
|
||||
struct packet_flow* pf);
|
||||
|
||||
void add_observation_field(char* key, u8* value);
|
||||
|
||||
#define OBSERVF(_key, _fmt...) do { \
|
||||
u8* _val; \
|
||||
_val = alloc_printf(_fmt); \
|
||||
add_observation_field(_key, _val); \
|
||||
ck_free(_val); \
|
||||
} while (0)
|
||||
|
||||
#include "api.h"
|
||||
|
||||
struct api_client {
|
||||
|
||||
s32 fd; /* -1 if slot free */
|
||||
|
||||
struct p0f_api_query in_data; /* Query recv buffer */
|
||||
u32 in_off; /* Query buffer offset */
|
||||
|
||||
struct p0f_api_response out_data; /* Response transmit buffer */
|
||||
u32 out_off; /* Response buffer offset */
|
||||
|
||||
};
|
||||
|
||||
#endif /* !_HAVE_P0F_H */
|
1548
docker/p0f/process.c
Normal file
1548
docker/p0f/process.c
Normal file
File diff suppressed because it is too large
Load Diff
216
docker/p0f/process.h
Normal file
216
docker/p0f/process.h
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
p0f - packet capture and overall host / flow bookkeeping
|
||||
--------------------------------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_PROCESS_H
|
||||
#define _HAVE_PROCESS_H
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "fp_tcp.h"
|
||||
#include "fp_http.h"
|
||||
|
||||
/* Parsed information handed over by the pcap callback: */
|
||||
|
||||
struct packet_data {
|
||||
|
||||
u8 ip_ver; /* IP_VER4, IP_VER6 */
|
||||
u8 tcp_type; /* TCP_SYN, ACK, FIN, RST */
|
||||
|
||||
u8 src[16]; /* Source address (left-aligned) */
|
||||
u8 dst[16]; /* Destination address (left-aligned */
|
||||
|
||||
u16 sport; /* Source port */
|
||||
u16 dport; /* Destination port */
|
||||
|
||||
u8 ttl; /* Observed TTL */
|
||||
u8 tos; /* IP ToS value */
|
||||
|
||||
u16 mss; /* Maximum segment size */
|
||||
u16 win; /* Window size */
|
||||
u8 wscale; /* Window scaling */
|
||||
u16 tot_hdr; /* Total headers (for MTU calc) */
|
||||
|
||||
u8 opt_layout[MAX_TCP_OPT]; /* Ordering of TCP options */
|
||||
u8 opt_cnt; /* Count of TCP options */
|
||||
u8 opt_eol_pad; /* Amount of padding past EOL */
|
||||
|
||||
u32 ts1; /* Own timestamp */
|
||||
|
||||
u32 quirks; /* QUIRK_* */
|
||||
|
||||
u8 ip_opt_len; /* Length of IP options */
|
||||
|
||||
u8* payload; /* TCP payload */
|
||||
u16 pay_len; /* Length of TCP payload */
|
||||
|
||||
u32 seq; /* seq value seen */
|
||||
|
||||
};
|
||||
|
||||
/* IP-level quirks: */
|
||||
|
||||
#define QUIRK_ECN 0x00000001 /* ECN supported */
|
||||
#define QUIRK_DF 0x00000002 /* DF used (probably PMTUD) */
|
||||
#define QUIRK_NZ_ID 0x00000004 /* Non-zero IDs when DF set */
|
||||
#define QUIRK_ZERO_ID 0x00000008 /* Zero IDs when DF not set */
|
||||
#define QUIRK_NZ_MBZ 0x00000010 /* IP "must be zero" field isn't */
|
||||
#define QUIRK_FLOW 0x00000020 /* IPv6 flows used */
|
||||
|
||||
/* Core TCP quirks: */
|
||||
|
||||
#define QUIRK_ZERO_SEQ 0x00001000 /* SEQ is zero */
|
||||
#define QUIRK_NZ_ACK 0x00002000 /* ACK non-zero when ACK flag not set */
|
||||
#define QUIRK_ZERO_ACK 0x00004000 /* ACK is zero when ACK flag set */
|
||||
#define QUIRK_NZ_URG 0x00008000 /* URG non-zero when URG flag not set */
|
||||
#define QUIRK_URG 0x00010000 /* URG flag set */
|
||||
#define QUIRK_PUSH 0x00020000 /* PUSH flag on a control packet */
|
||||
|
||||
/* TCP option quirks: */
|
||||
|
||||
#define QUIRK_OPT_ZERO_TS1 0x01000000 /* Own timestamp set to zero */
|
||||
#define QUIRK_OPT_NZ_TS2 0x02000000 /* Peer timestamp non-zero on SYN */
|
||||
#define QUIRK_OPT_EOL_NZ 0x04000000 /* Non-zero padding past EOL */
|
||||
#define QUIRK_OPT_EXWS 0x08000000 /* Excessive window scaling */
|
||||
#define QUIRK_OPT_BAD 0x10000000 /* Problem parsing TCP options */
|
||||
|
||||
/* Host record with persistent fingerprinting data: */
|
||||
|
||||
struct host_data {
|
||||
|
||||
struct host_data *prev, *next; /* Linked lists */
|
||||
struct host_data *older, *newer;
|
||||
u32 use_cnt; /* Number of packet_flows attached */
|
||||
|
||||
u32 first_seen; /* Record created (unix time) */
|
||||
u32 last_seen; /* Host last seen (unix time) */
|
||||
u32 total_conn; /* Total number of connections ever */
|
||||
|
||||
u8 ip_ver; /* Address type */
|
||||
u8 addr[16]; /* Host address data */
|
||||
|
||||
struct tcp_sig* last_syn; /* Sig of the most recent SYN */
|
||||
struct tcp_sig* last_synack; /* Sig of the most recent SYN+ACK */
|
||||
|
||||
s32 last_class_id; /* OS class ID (-1 = not found) */
|
||||
s32 last_name_id; /* OS name ID (-1 = not found) */
|
||||
u8* last_flavor; /* Last OS flavor */
|
||||
|
||||
u8 last_quality; /* Generic or fuzzy match? */
|
||||
|
||||
u8* link_type; /* MTU-derived link type */
|
||||
|
||||
u8 cli_scores[NAT_SCORES]; /* Scoreboard for client NAT */
|
||||
u8 srv_scores[NAT_SCORES]; /* Scoreboard for server NAT */
|
||||
u16 nat_reasons; /* NAT complaints */
|
||||
|
||||
u32 last_nat; /* Last NAT detection time */
|
||||
u32 last_chg; /* Last OS change detection time */
|
||||
|
||||
u16 last_port; /* Source port on last SYN */
|
||||
|
||||
u8 distance; /* Last measured distance */
|
||||
|
||||
s32 last_up_min; /* Last computed uptime (-1 = none) */
|
||||
u32 up_mod_days; /* Uptime modulo (days) */
|
||||
|
||||
/* HTTP business: */
|
||||
|
||||
struct http_sig* http_req_os; /* Last request, if class != -1 */
|
||||
struct http_sig* http_resp; /* Last response */
|
||||
|
||||
s32 http_name_id; /* Client name ID (-1 = not found) */
|
||||
u8* http_flavor; /* Client flavor */
|
||||
|
||||
u8* language; /* Detected language */
|
||||
|
||||
u8 bad_sw; /* Used dishonest U-A or Server? */
|
||||
|
||||
u16 http_resp_port; /* Port on which response seen */
|
||||
|
||||
};
|
||||
|
||||
/* Reasons for NAT detection: */
|
||||
|
||||
#define NAT_APP_SIG 0x0001 /* App signature <-> OS mismatch */
|
||||
#define NAT_OS_SIG 0x0002 /* OS detection mismatch */
|
||||
#define NAT_UNK_DIFF 0x0004 /* Current sig unknown, but different */
|
||||
#define NAT_TO_UNK 0x0008 /* Sig changed from known to unknown */
|
||||
#define NAT_TS 0x0010 /* Timestamp goes back */
|
||||
#define NAT_PORT 0x0020 /* Source port goes back */
|
||||
#define NAT_TTL 0x0040 /* TTL changes unexpectedly */
|
||||
#define NAT_FUZZY 0x0080 /* Signature fuzziness changes */
|
||||
#define NAT_MSS 0x0100 /* MSS changes */
|
||||
|
||||
#define NAT_APP_LB 0x0200 /* Server signature changes */
|
||||
#define NAT_APP_VIA 0x0400 /* Via / X-Forwarded-For seen */
|
||||
#define NAT_APP_DATE 0x0800 /* Date changes in a weird way */
|
||||
#define NAT_APP_UA 0x1000 /* User-Agent OS inconsistency */
|
||||
|
||||
/* TCP flow record, maintained until all fingerprinting modules are happy: */
|
||||
|
||||
struct packet_flow {
|
||||
|
||||
struct packet_flow *prev, *next; /* Linked lists */
|
||||
struct packet_flow *older, *newer;
|
||||
u32 bucket; /* Bucket this flow belongs to */
|
||||
|
||||
struct host_data* client; /* Requesting client */
|
||||
struct host_data* server; /* Target server */
|
||||
|
||||
u16 cli_port; /* Client port */
|
||||
u16 srv_port; /* Server port */
|
||||
|
||||
u8 acked; /* SYN+ACK received? */
|
||||
u8 sendsyn; /* Created by p0f-sendsyn? */
|
||||
|
||||
s16 srv_tps; /* Computed TS divisor (-1 = bad) */
|
||||
s16 cli_tps;
|
||||
|
||||
u8* request; /* Client-originating data */
|
||||
u32 req_len; /* Captured data length */
|
||||
u32 next_cli_seq; /* Next seq on cli -> srv packet */
|
||||
|
||||
u8* response; /* Server-originating data */
|
||||
u32 resp_len; /* Captured data length */
|
||||
u32 next_srv_seq; /* Next seq on srv -> cli packet */
|
||||
u16 syn_mss; /* MSS on SYN packet */
|
||||
|
||||
u32 created; /* Flow creation date (unix time) */
|
||||
|
||||
/* Application-level fingerprinting: */
|
||||
|
||||
s8 in_http; /* 0 = tbd, 1 = yes, -1 = no */
|
||||
|
||||
u8 http_req_done; /* Done collecting req headers? */
|
||||
u32 http_pos; /* Current parsing offset */
|
||||
u8 http_gotresp1; /* Got initial line of a response? */
|
||||
|
||||
struct http_sig http_tmp; /* Temporary signature */
|
||||
|
||||
};
|
||||
|
||||
extern u64 packet_cnt;
|
||||
|
||||
void parse_packet(void* junk, const struct pcap_pkthdr* hdr, const u8* data);
|
||||
|
||||
u8* addr_to_str(u8* data, u8 ip_ver);
|
||||
|
||||
u64 get_unix_time_ms(void);
|
||||
u32 get_unix_time(void);
|
||||
|
||||
void add_nat_score(u8 to_srv, struct packet_flow* f, u16 reason, u8 score);
|
||||
void verify_tool_class(u8 to_srv, struct packet_flow* f, u32* sys, u32 sys_cnt);
|
||||
|
||||
struct host_data* lookup_host(u8* addr, u8 ip_ver);
|
||||
|
||||
void destroy_all_hosts(void);
|
||||
|
||||
#endif /* !_HAVE_PROCESS_H */
|
450
docker/p0f/readfp.c
Normal file
450
docker/p0f/readfp.c
Normal file
@ -0,0 +1,450 @@
|
||||
/*
|
||||
p0f - p0f.fp file parser
|
||||
------------------------
|
||||
|
||||
Every project has this one really ugly C file. This is ours.
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "alloc-inl.h"
|
||||
#include "fp_tcp.h"
|
||||
#include "fp_mtu.h"
|
||||
#include "fp_http.h"
|
||||
#include "readfp.h"
|
||||
|
||||
static u32 sig_cnt; /* Total number of p0f.fp sigs */
|
||||
|
||||
static u8 state = CF_NEED_SECT, /* Parser state (CF_NEED_*) */
|
||||
mod_type, /* Current module (CF_MOD_*) */
|
||||
mod_to_srv, /* Traffic direction */
|
||||
generic; /* Generic signature? */
|
||||
|
||||
static s32 sig_class; /* Signature class ID (-1 = userland) */
|
||||
static u32 sig_name; /* Signature name */
|
||||
static u8* sig_flavor; /* Signature flavor */
|
||||
|
||||
static u32* cur_sys; /* Current 'sys' values */
|
||||
static u32 cur_sys_cnt; /* Number of 'sys' entries */
|
||||
|
||||
u8 **fp_os_classes, /* Map of OS classes */
|
||||
**fp_os_names; /* Map of OS names */
|
||||
|
||||
static u32 class_cnt, /* Sizes for maps */
|
||||
name_cnt,
|
||||
label_id, /* Current label ID */
|
||||
line_no; /* Current line number */
|
||||
|
||||
|
||||
/* Parse 'classes' parameter by populating fp_os_classes. */
|
||||
|
||||
static void config_parse_classes(u8* val) {
|
||||
|
||||
while (*val) {
|
||||
|
||||
u8* nxt;
|
||||
|
||||
while (isblank(*val) || *val == ',') val++;
|
||||
|
||||
nxt = val;
|
||||
|
||||
while (isalnum(*nxt)) nxt++;
|
||||
|
||||
if (nxt == val || (*nxt && *nxt != ','))
|
||||
FATAL("Malformed class entry in line %u.", line_no);
|
||||
|
||||
fp_os_classes = DFL_ck_realloc(fp_os_classes, (class_cnt + 1) * sizeof(u8*));
|
||||
|
||||
fp_os_classes[class_cnt++] = DFL_ck_memdup_str(val, nxt - val);
|
||||
|
||||
val = nxt;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Look up or create OS or application id. */
|
||||
|
||||
u32 lookup_name_id(u8* name, u8 len) {
|
||||
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < name_cnt; i++)
|
||||
if (!strncasecmp((char*)name, (char*)fp_os_names[i], len)
|
||||
&& !fp_os_names[i][len]) break;
|
||||
|
||||
if (i == name_cnt) {
|
||||
|
||||
sig_name = name_cnt;
|
||||
|
||||
fp_os_names = DFL_ck_realloc(fp_os_names, (name_cnt + 1) * sizeof(u8*));
|
||||
fp_os_names[name_cnt++] = DFL_ck_memdup_str(name, len);
|
||||
|
||||
}
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Parse 'label' parameter by looking up ID and recording name / flavor. */
|
||||
|
||||
static void config_parse_label(u8* val) {
|
||||
|
||||
u8* nxt;
|
||||
u32 i;
|
||||
|
||||
/* Simplified handling for [mtu] signatures. */
|
||||
|
||||
if (mod_type == CF_MOD_MTU) {
|
||||
|
||||
if (!*val) FATAL("Empty MTU label in line %u.\n", line_no);
|
||||
|
||||
sig_flavor = DFL_ck_strdup(val);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (*val == 'g') generic = 1;
|
||||
else if (*val == 's') generic = 0;
|
||||
else FATAL("Malformed class entry in line %u.", line_no);
|
||||
|
||||
if (val[1] != ':') FATAL("Malformed class entry in line %u.", line_no);
|
||||
|
||||
val += 2;
|
||||
|
||||
nxt = val;
|
||||
while (isalnum(*nxt) || *nxt == '!') nxt++;
|
||||
|
||||
if (nxt == val || *nxt != ':') FATAL("Malformed class entry in line %u.", line_no);
|
||||
|
||||
if (*val == '!' && val[1] == ':') {
|
||||
|
||||
sig_class = -1;
|
||||
|
||||
} else {
|
||||
|
||||
*nxt = 0;
|
||||
|
||||
for (i = 0; i < class_cnt; i++)
|
||||
if (!strcasecmp((char*)val, (char*)fp_os_classes[i])) break;
|
||||
|
||||
if (i == class_cnt) FATAL("Unknown class '%s' in line %u.", val, line_no);
|
||||
|
||||
sig_class = i;
|
||||
|
||||
}
|
||||
|
||||
nxt++;
|
||||
val = nxt;
|
||||
while (isalnum(*nxt) || (*nxt && strchr(NAME_CHARS, *nxt))) nxt++;
|
||||
|
||||
if (nxt == val || *nxt != ':') FATAL("Malformed name in line %u.", line_no);
|
||||
|
||||
sig_name = lookup_name_id(val, nxt - val);
|
||||
|
||||
if (nxt[1]) sig_flavor = DFL_ck_strdup(nxt + 1);
|
||||
else sig_flavor = NULL;
|
||||
|
||||
label_id++;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Parse 'sys' parameter into cur_sys[]. */
|
||||
|
||||
static void config_parse_sys(u8* val) {
|
||||
|
||||
if (cur_sys) {
|
||||
cur_sys = NULL;
|
||||
cur_sys_cnt = 0;
|
||||
}
|
||||
|
||||
while (*val) {
|
||||
|
||||
u8* nxt;
|
||||
u8 is_cl = 0, orig;
|
||||
u32 i;
|
||||
|
||||
while (isblank(*val) || *val == ',') val++;
|
||||
|
||||
if (*val == '@') { is_cl = 1; val++; }
|
||||
|
||||
nxt = val;
|
||||
|
||||
while (isalnum(*nxt) || (*nxt && strchr(NAME_CHARS, *nxt))) nxt++;
|
||||
|
||||
if (nxt == val || (*nxt && *nxt != ','))
|
||||
FATAL("Malformed sys entry in line %u.", line_no);
|
||||
|
||||
orig = *nxt;
|
||||
*nxt = 0;
|
||||
|
||||
if (is_cl) {
|
||||
|
||||
for (i = 0; i < class_cnt; i++)
|
||||
if (!strcasecmp((char*)val, (char*)fp_os_classes[i])) break;
|
||||
|
||||
if (i == class_cnt)
|
||||
FATAL("Unknown class '%s' in line %u.", val, line_no);
|
||||
|
||||
i |= SYS_CLASS_FLAG;
|
||||
|
||||
} else {
|
||||
|
||||
for (i = 0; i < name_cnt; i++)
|
||||
if (!strcasecmp((char*)val, (char*)fp_os_names[i])) break;
|
||||
|
||||
if (i == name_cnt) {
|
||||
fp_os_names = DFL_ck_realloc(fp_os_names, (name_cnt + 1) * sizeof(u8*));
|
||||
fp_os_names[name_cnt++] = DFL_ck_memdup_str(val, nxt - val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cur_sys = DFL_ck_realloc(cur_sys, (cur_sys_cnt + 1) * 4);
|
||||
cur_sys[cur_sys_cnt++] = i;
|
||||
|
||||
*nxt = orig;
|
||||
val = nxt;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Read p0f.fp line, dispatching it to fingerprinting modules as necessary. */
|
||||
|
||||
static void config_parse_line(u8* line) {
|
||||
|
||||
u8 *val,*eon;
|
||||
|
||||
/* Special handling for [module:direction]... */
|
||||
|
||||
if (*line == '[') {
|
||||
|
||||
u8* dir;
|
||||
|
||||
line++;
|
||||
|
||||
/* Simplified case for [mtu]. */
|
||||
|
||||
if (!strcmp((char*)line, "mtu]")) {
|
||||
|
||||
mod_type = CF_MOD_MTU;
|
||||
state = CF_NEED_LABEL;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
dir = (u8*)strchr((char*)line, ':');
|
||||
|
||||
if (!dir) FATAL("Malformed section identifier in line %u.", line_no);
|
||||
|
||||
*dir = 0; dir++;
|
||||
|
||||
if (!strcmp((char*)line, "tcp")) {
|
||||
|
||||
mod_type = CF_MOD_TCP;
|
||||
|
||||
} else if (!strcmp((char*)line, "http")) {
|
||||
|
||||
mod_type = CF_MOD_HTTP;
|
||||
|
||||
} else {
|
||||
|
||||
FATAL("Unrecognized fingerprinting module '%s' in line %u.", line, line_no);
|
||||
|
||||
}
|
||||
|
||||
if (!strcmp((char*)dir, "request]")) {
|
||||
|
||||
mod_to_srv = 1;
|
||||
|
||||
} else if (!strcmp((char*)dir, "response]")) {
|
||||
|
||||
mod_to_srv = 0;
|
||||
|
||||
} else {
|
||||
|
||||
FATAL("Unrecognized traffic direction in line %u.", line_no);
|
||||
|
||||
}
|
||||
|
||||
state = CF_NEED_LABEL;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Everything else follows the 'name = value' approach. */
|
||||
|
||||
val = line;
|
||||
|
||||
while (isalpha(*val) || *val == '_') val++;
|
||||
eon = val;
|
||||
|
||||
while (isblank(*val)) val++;
|
||||
|
||||
if (line == val || *val != '=')
|
||||
FATAL("Unexpected statement in line %u.", line_no);
|
||||
|
||||
while (isblank(*++val));
|
||||
|
||||
*eon = 0;
|
||||
|
||||
if (!strcmp((char*)line, "classes")) {
|
||||
|
||||
if (state != CF_NEED_SECT)
|
||||
FATAL("misplaced 'classes' in line %u.", line_no);
|
||||
|
||||
config_parse_classes(val);
|
||||
|
||||
} else if (!strcmp((char*)line, "ua_os")) {
|
||||
|
||||
if (state != CF_NEED_LABEL || mod_to_srv != 1 || mod_type != CF_MOD_HTTP)
|
||||
FATAL("misplaced 'us_os' in line %u.", line_no);
|
||||
|
||||
http_parse_ua(val, line_no);
|
||||
|
||||
} else if (!strcmp((char*)line, "label")) {
|
||||
|
||||
/* We will drop sig_sys / sig_flavor on the floor if no signatures
|
||||
actually created, but it's not worth tracking that. */
|
||||
|
||||
if (state != CF_NEED_LABEL && state != CF_NEED_SIG)
|
||||
FATAL("misplaced 'label' in line %u.", line_no);
|
||||
|
||||
config_parse_label(val);
|
||||
|
||||
if (mod_type != CF_MOD_MTU && sig_class < 0) state = CF_NEED_SYS;
|
||||
else state = CF_NEED_SIG;
|
||||
|
||||
} else if (!strcmp((char*)line, "sys")) {
|
||||
|
||||
if (state != CF_NEED_SYS)
|
||||
FATAL("Misplaced 'sys' in line %u.", line_no);
|
||||
|
||||
config_parse_sys(val);
|
||||
|
||||
state = CF_NEED_SIG;
|
||||
|
||||
} else if (!strcmp((char*)line, "sig")) {
|
||||
|
||||
if (state != CF_NEED_SIG) FATAL("Misplaced 'sig' in line %u.", line_no);
|
||||
|
||||
switch (mod_type) {
|
||||
|
||||
case CF_MOD_TCP:
|
||||
tcp_register_sig(mod_to_srv, generic, sig_class, sig_name, sig_flavor,
|
||||
label_id, cur_sys, cur_sys_cnt, val, line_no);
|
||||
break;
|
||||
|
||||
case CF_MOD_MTU:
|
||||
mtu_register_sig(sig_flavor, val, line_no);
|
||||
break;
|
||||
|
||||
case CF_MOD_HTTP:
|
||||
http_register_sig(mod_to_srv, generic, sig_class, sig_name, sig_flavor,
|
||||
label_id, cur_sys, cur_sys_cnt, val, line_no);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
sig_cnt++;
|
||||
|
||||
} else {
|
||||
|
||||
FATAL("Unrecognized field '%s' in line %u.", line, line_no);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Top-level file parsing. */
|
||||
|
||||
void read_config(u8* fname) {
|
||||
|
||||
s32 f;
|
||||
struct stat st;
|
||||
u8 *data, *cur;
|
||||
|
||||
f = open((char*)fname, O_RDONLY);
|
||||
if (f < 0) PFATAL("Cannot open '%s' for reading.", fname);
|
||||
|
||||
if (fstat(f, &st)) PFATAL("fstat() on '%s' failed.", fname);
|
||||
|
||||
if (!st.st_size) {
|
||||
close(f);
|
||||
goto end_fp_read;
|
||||
}
|
||||
|
||||
cur = data = ck_alloc(st.st_size + 1);
|
||||
|
||||
if (read(f, data, st.st_size) != st.st_size)
|
||||
FATAL("Short read from '%s'.", fname);
|
||||
|
||||
data[st.st_size] = 0;
|
||||
|
||||
close(f);
|
||||
|
||||
/* If you put NUL in your p0f.fp... Well, sucks to be you. */
|
||||
|
||||
while (1) {
|
||||
|
||||
u8 *eol;
|
||||
|
||||
line_no++;
|
||||
|
||||
while (isblank(*cur)) cur++;
|
||||
|
||||
eol = cur;
|
||||
while (*eol && *eol != '\n') eol++;
|
||||
|
||||
if (*cur != ';' && cur != eol) {
|
||||
|
||||
u8* line = ck_memdup_str(cur, eol - cur);
|
||||
|
||||
config_parse_line(line);
|
||||
|
||||
ck_free(line);
|
||||
|
||||
}
|
||||
|
||||
if (!*eol) break;
|
||||
|
||||
cur = eol + 1;
|
||||
|
||||
}
|
||||
|
||||
ck_free(data);
|
||||
|
||||
end_fp_read:
|
||||
|
||||
if (!sig_cnt)
|
||||
SAYF("[!] No signatures found in '%s'.\n", fname);
|
||||
else
|
||||
SAYF("[+] Loaded %u signature%s from '%s'.\n", sig_cnt,
|
||||
sig_cnt == 1 ? "" : "s", fname);
|
||||
|
||||
}
|
||||
|
41
docker/p0f/readfp.h
Normal file
41
docker/p0f/readfp.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
p0f - p0f.fp file parser
|
||||
------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_READFP_H
|
||||
#define _HAVE_READFP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* List of fingerprinting modules: */
|
||||
|
||||
#define CF_MOD_TCP 0x00 /* fp_tcp.c */
|
||||
#define CF_MOD_MTU 0x01 /* fp_mtu.c */
|
||||
#define CF_MOD_HTTP 0x02 /* fp_http.c */
|
||||
|
||||
/* Parser states: */
|
||||
|
||||
#define CF_NEED_SECT 0x00 /* Waiting for [...] or 'classes' */
|
||||
#define CF_NEED_LABEL 0x01 /* Waiting for 'label' */
|
||||
#define CF_NEED_SYS 0x02 /* Waiting for 'sys' */
|
||||
#define CF_NEED_SIG 0x03 /* Waiting for signatures, if any. */
|
||||
|
||||
/* Flag to distinguish OS class and name IDs */
|
||||
|
||||
#define SYS_CLASS_FLAG (1<<31)
|
||||
#define SYS_NF(_x) ((_x) & ~SYS_CLASS_FLAG)
|
||||
|
||||
extern u8** fp_os_classes;
|
||||
extern u8** fp_os_names;
|
||||
|
||||
void read_config(u8* fname);
|
||||
|
||||
u32 lookup_name_id(u8* name, u8 len);
|
||||
|
||||
#endif /* !_HAVE_READFP_H */
|
141
docker/p0f/tcp.h
Normal file
141
docker/p0f/tcp.h
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
p0f - portable IP and TCP headers
|
||||
---------------------------------
|
||||
|
||||
Note that all multi-byte fields are in network (i.e., big) endian, and may
|
||||
need to be converted before use.
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_TCP_H
|
||||
#define _HAVE_TCP_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*************
|
||||
* IP common *
|
||||
*************/
|
||||
|
||||
/* Protocol versions: */
|
||||
|
||||
#define IP_VER4 0x04
|
||||
#define IP_VER6 0x06
|
||||
|
||||
/* IP-level ECN: */
|
||||
|
||||
#define IP_TOS_CE 0x01 /* Congestion encountered */
|
||||
#define IP_TOS_ECT 0x02 /* ECN supported */
|
||||
|
||||
/* Encapsulated protocols we care about: */
|
||||
|
||||
#define PROTO_TCP 0x06
|
||||
|
||||
|
||||
/********
|
||||
* IPv4 *
|
||||
********/
|
||||
|
||||
struct ipv4_hdr {
|
||||
|
||||
u8 ver_hlen; /* IP version (4), IP hdr len in dwords (4) */
|
||||
u8 tos_ecn; /* ToS field (6), ECN flags (2) */
|
||||
u16 tot_len; /* Total packet length, in bytes */
|
||||
u16 id; /* IP ID */
|
||||
u16 flags_off; /* Flags (3), fragment offset (13) */
|
||||
u8 ttl; /* Time to live */
|
||||
u8 proto; /* Next protocol */
|
||||
u16 cksum; /* Header checksum */
|
||||
u8 src[4]; /* Source IP */
|
||||
u8 dst[4]; /* Destination IP */
|
||||
|
||||
/* Dword-aligned options may follow. */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
/* IP flags: */
|
||||
|
||||
#define IP4_MBZ 0x8000 /* "Must be zero" */
|
||||
#define IP4_DF 0x4000 /* Don't fragment (usually PMTUD) */
|
||||
#define IP4_MF 0x2000 /* More fragments coming */
|
||||
|
||||
|
||||
/********
|
||||
* IPv6 *
|
||||
********/
|
||||
|
||||
struct ipv6_hdr {
|
||||
|
||||
u32 ver_tos; /* Version (4), ToS (6), ECN (2), flow (20) */
|
||||
u16 pay_len; /* Total payload length, in bytes */
|
||||
u8 proto; /* Next protocol */
|
||||
u8 ttl; /* Time to live */
|
||||
u8 src[16]; /* Source IP */
|
||||
u8 dst[16]; /* Destination IP */
|
||||
|
||||
/* Dword-aligned options may follow if proto != PROTO_TCP and are
|
||||
included in total_length; but we won't be seeing such traffic due
|
||||
to BPF rules. */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
|
||||
/*******
|
||||
* TCP *
|
||||
*******/
|
||||
|
||||
struct tcp_hdr {
|
||||
|
||||
u16 sport; /* Source port */
|
||||
u16 dport; /* Destination port */
|
||||
u32 seq; /* Sequence number */
|
||||
u32 ack; /* Acknowledgment number */
|
||||
u8 doff_rsvd; /* Data off dwords (4), rsvd (3), ECN (1) */
|
||||
u8 flags; /* Flags, including ECN */
|
||||
u16 win; /* Window size */
|
||||
u16 cksum; /* Header and payload checksum */
|
||||
u16 urg; /* "Urgent" pointer */
|
||||
|
||||
/* Dword-aligned options may follow. */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
/* Normal flags: */
|
||||
|
||||
#define TCP_FIN 0x01
|
||||
#define TCP_SYN 0x02
|
||||
#define TCP_RST 0x04
|
||||
#define TCP_PUSH 0x08
|
||||
#define TCP_ACK 0x10
|
||||
#define TCP_URG 0x20
|
||||
|
||||
/* ECN stuff: */
|
||||
|
||||
#define TCP_ECE 0x40 /* ECN supported (SYN) or detected */
|
||||
#define TCP_CWR 0x80 /* ECE acknowledgment */
|
||||
#define TCP_NS_RES 0x01 /* ECE notification via TCP */
|
||||
|
||||
/* Notable options: */
|
||||
|
||||
#define TCPOPT_EOL 0 /* End of options (1) */
|
||||
#define TCPOPT_NOP 1 /* No-op (1) */
|
||||
#define TCPOPT_MAXSEG 2 /* Maximum segment size (4) */
|
||||
#define TCPOPT_WSCALE 3 /* Window scaling (3) */
|
||||
#define TCPOPT_SACKOK 4 /* Selective ACK permitted (2) */
|
||||
#define TCPOPT_SACK 5 /* Actual selective ACK (10-34) */
|
||||
#define TCPOPT_TSTAMP 8 /* Timestamp (10) */
|
||||
|
||||
|
||||
/***************
|
||||
* Other stuff *
|
||||
***************/
|
||||
|
||||
#define MIN_TCP4 (sizeof(struct ipv4_hdr) + sizeof(struct tcp_hdr))
|
||||
#define MIN_TCP6 (sizeof(struct ipv6_hdr) + sizeof(struct tcp_hdr))
|
||||
|
||||
#endif /* !_HAVE_TCP_H */
|
18
docker/p0f/tools/Makefile
Normal file
18
docker/p0f/tools/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# p0f - Makefile for tools
|
||||
# ------------------------
|
||||
#
|
||||
# Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
#
|
||||
# Distributed under the terms and conditions of GNU LGPL.
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -ggdb -Wall -Wno-format -funsigned-char
|
||||
LDFLAGS =
|
||||
TARGETS = p0f-client p0f-sendsyn p0f-sendsyn6
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f -- $(TARGETS) *.exe *.o a.out *~ core core.[1-9][0-9]* *.stackdump 2>/dev/null
|
16
docker/p0f/tools/README-TOOLS
Normal file
16
docker/p0f/tools/README-TOOLS
Normal file
@ -0,0 +1,16 @@
|
||||
This directory contains several helper tools mentioned in ../README:
|
||||
|
||||
p0f-sendsyn.c - a tool for gathering new SYN+ACK signatures
|
||||
|
||||
p0f-sendsyn6.c - the same, for IPv6 destinations
|
||||
|
||||
p0f-client.c - simple API client tool for p0f -s mode
|
||||
|
||||
Note that IPv6 addresses need to be passed to the utilities in a fully-expanded
|
||||
form (i.e., no ::).
|
||||
|
||||
To build any of these programs, simply type 'make progname', e.g.:
|
||||
|
||||
make p0f-sendsyn
|
||||
|
||||
If that fails, you can drop me a mail at lcamtuf@coredump.cx.
|
215
docker/p0f/tools/p0f-client.c
Normal file
215
docker/p0f/tools/p0f-client.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
p0f-client - simple API client
|
||||
------------------------------
|
||||
|
||||
Can be used to query p0f API sockets.
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "../types.h"
|
||||
#include "../config.h"
|
||||
#include "../alloc-inl.h"
|
||||
#include "../debug.h"
|
||||
#include "../api.h"
|
||||
|
||||
/* Parse IPv4 address into a buffer. */
|
||||
|
||||
static void parse_addr4(char* str, u8* ret) {
|
||||
|
||||
u32 a1, a2, a3, a4;
|
||||
|
||||
if (sscanf(str, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4)
|
||||
FATAL("Malformed IPv4 address.");
|
||||
|
||||
if (a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255)
|
||||
FATAL("Malformed IPv4 address.");
|
||||
|
||||
ret[0] = a1;
|
||||
ret[1] = a2;
|
||||
ret[2] = a3;
|
||||
ret[3] = a4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Parse IPv6 address into a buffer. */
|
||||
|
||||
static void parse_addr6(char* str, u8* ret) {
|
||||
|
||||
u32 seg = 0;
|
||||
u32 val;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if (seg == 8) FATAL("Malformed IPv6 address (too many segments).");
|
||||
|
||||
if (sscanf((char*)str, "%x", &val) != 1 ||
|
||||
val > 65535) FATAL("Malformed IPv6 address (bad octet value).");
|
||||
|
||||
ret[seg * 2] = val >> 8;
|
||||
ret[seg * 2 + 1] = val;
|
||||
|
||||
seg++;
|
||||
|
||||
while (isxdigit(*str)) str++;
|
||||
if (*str) str++;
|
||||
|
||||
}
|
||||
|
||||
if (seg != 8) FATAL("Malformed IPv6 address (don't abbreviate).");
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
u8 tmp[128];
|
||||
struct tm* t;
|
||||
|
||||
static struct p0f_api_query q;
|
||||
static struct p0f_api_response r;
|
||||
|
||||
static struct sockaddr_un sun;
|
||||
|
||||
s32 sock;
|
||||
time_t ut;
|
||||
|
||||
if (argc != 3) {
|
||||
ERRORF("Usage: p0f-client /path/to/socket host_ip\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
q.magic = P0F_QUERY_MAGIC;
|
||||
|
||||
if (strchr(argv[2], ':')) {
|
||||
|
||||
parse_addr6(argv[2], q.addr);
|
||||
q.addr_type = P0F_ADDR_IPV6;
|
||||
|
||||
} else {
|
||||
|
||||
parse_addr4(argv[2], q.addr);
|
||||
q.addr_type = P0F_ADDR_IPV4;
|
||||
|
||||
}
|
||||
|
||||
sock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (sock < 0) PFATAL("Call to socket() failed.");
|
||||
|
||||
sun.sun_family = AF_UNIX;
|
||||
|
||||
if (strlen(argv[1]) >= sizeof(sun.sun_path))
|
||||
FATAL("API socket filename is too long for sockaddr_un (blame Unix).");
|
||||
|
||||
strcpy(sun.sun_path, argv[1]);
|
||||
|
||||
if (connect(sock, (struct sockaddr*)&sun, sizeof(sun)))
|
||||
PFATAL("Can't connect to API socket.");
|
||||
|
||||
if (write(sock, &q, sizeof(struct p0f_api_query)) !=
|
||||
sizeof(struct p0f_api_query)) FATAL("Short write to API socket.");
|
||||
|
||||
if (read(sock, &r, sizeof(struct p0f_api_response)) !=
|
||||
sizeof(struct p0f_api_response)) FATAL("Short read from API socket.");
|
||||
|
||||
close(sock);
|
||||
|
||||
if (r.magic != P0F_RESP_MAGIC)
|
||||
FATAL("Bad response magic (0x%08x).\n", r.magic);
|
||||
|
||||
if (r.status == P0F_STATUS_BADQUERY)
|
||||
FATAL("P0f did not understand the query.\n");
|
||||
|
||||
if (r.status == P0F_STATUS_NOMATCH) {
|
||||
SAYF("No matching host in p0f cache. That's all we know.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ut = r.first_seen;
|
||||
t = localtime(&ut);
|
||||
strftime((char*)tmp, 128, "%Y/%m/%d %H:%M:%S", t);
|
||||
|
||||
SAYF("First seen = %s\n", tmp);
|
||||
|
||||
ut = r.last_seen;
|
||||
t = localtime(&ut);
|
||||
strftime((char*)tmp, 128, "%Y/%m/%d %H:%M:%S", t);
|
||||
|
||||
SAYF("Last update = %s\n", tmp);
|
||||
|
||||
SAYF("Total flows = %u\n", r.total_conn);
|
||||
|
||||
if (!r.os_name[0])
|
||||
SAYF("Detected OS = ???\n");
|
||||
else
|
||||
SAYF("Detected OS = %s %s%s%s\n", r.os_name, r.os_flavor,
|
||||
(r.os_match_q & P0F_MATCH_GENERIC) ? " [generic]" : "",
|
||||
(r.os_match_q & P0F_MATCH_FUZZY) ? " [fuzzy]" : "");
|
||||
|
||||
if (!r.http_name[0])
|
||||
SAYF("HTTP software = ???\n");
|
||||
else
|
||||
SAYF("HTTP software = %s %s (ID %s)\n", r.http_name, r.http_flavor,
|
||||
(r.bad_sw == 2) ? "is fake" : (r.bad_sw ? "OS mismatch" : "seems legit"));
|
||||
|
||||
if (!r.link_type[0])
|
||||
SAYF("Network link = ???\n");
|
||||
else
|
||||
SAYF("Network link = %s\n", r.link_type);
|
||||
|
||||
if (!r.language[0])
|
||||
SAYF("Language = ???\n");
|
||||
else
|
||||
SAYF("Language = %s\n", r.language);
|
||||
|
||||
|
||||
if (r.distance == -1)
|
||||
SAYF("Distance = ???\n");
|
||||
else
|
||||
SAYF("Distance = %u\n", r.distance);
|
||||
|
||||
if (r.last_nat) {
|
||||
ut = r.last_nat;
|
||||
t = localtime(&ut);
|
||||
strftime((char*)tmp, 128, "%Y/%m/%d %H:%M:%S", t);
|
||||
SAYF("IP sharing = %s\n", tmp);
|
||||
}
|
||||
|
||||
if (r.last_chg) {
|
||||
ut = r.last_chg;
|
||||
t = localtime(&ut);
|
||||
strftime((char*)tmp, 128, "%Y/%m/%d %H:%M:%S", t);
|
||||
SAYF("Sys change = %s\n", tmp);
|
||||
}
|
||||
|
||||
if (r.uptime_min) {
|
||||
SAYF("Uptime = %u days %u hrs %u min (modulo %u days)\n",
|
||||
r.uptime_min / 60 / 24, (r.uptime_min / 60) % 24, r.uptime_min % 60,
|
||||
r.up_mod_days);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
185
docker/p0f/tools/p0f-sendsyn.c
Normal file
185
docker/p0f/tools/p0f-sendsyn.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
p0f-sendsyn - SYN sender
|
||||
------------------------
|
||||
|
||||
This trivial utility sends 8 SYN packets to open ports on destination hosts,
|
||||
and lets you capture SYN+ACK signatures. The problem with SYN+ACK
|
||||
fingerprinting is that on some systems, the response varies depending on the
|
||||
use of window scaling, timestamps, or selective ACK in the initial SYN - so
|
||||
this utility is necessary to exercise all the code paths.
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../types.h"
|
||||
#include "../config.h"
|
||||
#include "../alloc-inl.h"
|
||||
#include "../debug.h"
|
||||
#include "../tcp.h"
|
||||
|
||||
|
||||
/* Do a basic IPv4 TCP checksum. */
|
||||
|
||||
static void tcp_cksum(u8* src, u8* dst, struct tcp_hdr* t, u8 opt_len) {
|
||||
|
||||
u32 sum, i;
|
||||
u8* p;
|
||||
|
||||
if (opt_len % 4) FATAL("Packet size not aligned to 4.");
|
||||
|
||||
t->cksum = 0;
|
||||
|
||||
sum = PROTO_TCP + sizeof(struct tcp_hdr) + opt_len;
|
||||
|
||||
p = (u8*)t;
|
||||
|
||||
for (i = 0; i < sizeof(struct tcp_hdr) + opt_len; i += 2, p += 2)
|
||||
sum += (*p << 8) + p[1];
|
||||
|
||||
p = src;
|
||||
|
||||
for (i = 0; i < 4; i += 2, p += 2) sum += (*p << 8) + p[1];
|
||||
|
||||
p = dst;
|
||||
|
||||
for (i = 0; i < 4; i += 2, p += 2) sum += (*p << 8) + p[1];
|
||||
|
||||
t->cksum = htons(~(sum + (sum >> 16)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Parse IPv4 address into a buffer. */
|
||||
|
||||
static void parse_addr(char* str, u8* ret) {
|
||||
|
||||
u32 a1, a2, a3, a4;
|
||||
|
||||
if (sscanf(str, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4)
|
||||
FATAL("Malformed IPv4 address.");
|
||||
|
||||
if (a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255)
|
||||
FATAL("Malformed IPv4 address.");
|
||||
|
||||
ret[0] = a1;
|
||||
ret[1] = a2;
|
||||
ret[2] = a3;
|
||||
ret[3] = a4;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define W(_x) (_x) >> 8, (_x) & 0xff
|
||||
#define D(_x) (_x) >> 24, ((_x) >> 16) & 0xff, ((_x) >> 8) & 0xff, (_x) & 0xff
|
||||
|
||||
#define EOL TCPOPT_EOL
|
||||
#define NOP TCPOPT_NOP
|
||||
#define MSS(_x) TCPOPT_MAXSEG, 4, W(_x)
|
||||
#define WS(_x) TCPOPT_WSCALE, 3, (_x)
|
||||
#define SOK TCPOPT_SACKOK, 2
|
||||
#define TS(_x,_y) TCPOPT_TSTAMP, 10, D(_x), D(_y)
|
||||
|
||||
/* There are virtually no OSes that do not send MSS. Support for RFC 1323
|
||||
and 2018 is not given, so we have to test various combinations here. */
|
||||
|
||||
static u8 opt_combos[8][24] = {
|
||||
|
||||
{ MSS(SPECIAL_MSS), NOP, EOL }, /* 6 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), SOK, NOP, EOL }, /* 8 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), NOP, EOL }, /* 9 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), SOK, NOP, EOL }, /* 12 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), TS(1337, 0), NOP, EOL }, /* 17 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), SOK, TS(1337, 0), NOP, EOL }, /* 19 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), TS(1337, 0), NOP, EOL }, /* 20 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), SOK, TS(1337, 0), NOP, EOL } /* 22 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
static struct sockaddr_in sin;
|
||||
char one = 1;
|
||||
s32 sock;
|
||||
u32 i;
|
||||
|
||||
static u8 work_buf[MIN_TCP4 + 24];
|
||||
|
||||
struct ipv4_hdr* ip4 = (struct ipv4_hdr*)work_buf;
|
||||
struct tcp_hdr* tcp = (struct tcp_hdr*)(ip4 + 1);
|
||||
u8 *opts = work_buf + MIN_TCP4;
|
||||
|
||||
|
||||
if (argc != 4) {
|
||||
ERRORF("Usage: p0f-sendsyn your_ip dst_ip port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parse_addr(argv[1], ip4->src);
|
||||
parse_addr(argv[2], ip4->dst);
|
||||
|
||||
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
|
||||
|
||||
if (sock < 0) PFATAL("Can't open raw socket (you need to be root).");
|
||||
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&one, sizeof(char)))
|
||||
PFATAL("setsockopt() on raw socket failed.");
|
||||
|
||||
sin.sin_family = PF_INET;
|
||||
|
||||
memcpy(&sin.sin_addr.s_addr, ip4->dst, 4);
|
||||
|
||||
ip4->ver_hlen = 0x45;
|
||||
ip4->tot_len = htons(MIN_TCP4 + 24);
|
||||
ip4->ttl = 192;
|
||||
ip4->proto = PROTO_TCP;
|
||||
|
||||
tcp->dport = htons(atoi(argv[3]));
|
||||
tcp->seq = htonl(0x12345678);
|
||||
tcp->doff_rsvd = ((sizeof(struct tcp_hdr) + 24) / 4) << 4;
|
||||
tcp->flags = TCP_SYN;
|
||||
tcp->win = htons(SPECIAL_WIN);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
tcp->sport = htons(65535 - i);
|
||||
|
||||
memcpy(opts, opt_combos[i], 24);
|
||||
tcp_cksum(ip4->src, ip4->dst, tcp, 24);
|
||||
|
||||
if (sendto(sock, work_buf, sizeof(work_buf), 0, (struct sockaddr*)&sin,
|
||||
sizeof(struct sockaddr_in)) < 0) PFATAL("sendto() fails.");
|
||||
|
||||
usleep(100000);
|
||||
|
||||
}
|
||||
|
||||
SAYF("Eight packets sent! Check p0f output to examine responses, if any.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
198
docker/p0f/tools/p0f-sendsyn6.c
Normal file
198
docker/p0f/tools/p0f-sendsyn6.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
p0f-sendsyn6 - IPv6 SYN sender
|
||||
------------------------------
|
||||
|
||||
This trivial utility sends 8 SYN packets to open ports on destination hosts,
|
||||
and lets you capture SYN+ACK signatures. The problem with SYN+ACK
|
||||
fingerprinting is that on some systems, the response varies depending on the
|
||||
use of window scaling, timestamps, or selective ACK in the initial SYN - so
|
||||
this utility is necessary to exercise all the code paths.
|
||||
|
||||
Note that the IPv6 variant will not compile properly if you don't have
|
||||
IPv6-enabled libc; and will not work unless your kernel actually supports
|
||||
IPv6.
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../types.h"
|
||||
#include "../config.h"
|
||||
#include "../alloc-inl.h"
|
||||
#include "../debug.h"
|
||||
#include "../tcp.h"
|
||||
|
||||
|
||||
/* Do a basic IPv6 TCP checksum. */
|
||||
|
||||
static void tcp_cksum(u8* src, u8* dst, struct tcp_hdr* t, u8 opt_len) {
|
||||
|
||||
u32 sum, i;
|
||||
u8* p;
|
||||
|
||||
if (opt_len % 4) FATAL("Packet size not aligned to 4.");
|
||||
|
||||
t->cksum = 0;
|
||||
|
||||
sum = PROTO_TCP + sizeof(struct tcp_hdr) + opt_len;
|
||||
|
||||
p = (u8*)t;
|
||||
|
||||
for (i = 0; i < sizeof(struct tcp_hdr) + opt_len; i += 2, p += 2)
|
||||
sum += (*p << 8) + p[1];
|
||||
|
||||
p = src;
|
||||
|
||||
for (i = 0; i < 16; i += 2, p += 2) sum += (*p << 8) + p[1];
|
||||
|
||||
p = dst;
|
||||
|
||||
for (i = 0; i < 16; i += 2, p += 2) sum += (*p << 8) + p[1];
|
||||
|
||||
t->cksum = htons(~(sum + (sum >> 16)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Parse IPv6 address into a buffer. */
|
||||
|
||||
static void parse_addr(char* str, u8* ret) {
|
||||
|
||||
u32 seg = 0;
|
||||
u32 val;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if (seg == 8) FATAL("Malformed IPv6 address (too many segments).");
|
||||
|
||||
if (sscanf((char*)str, "%x", &val) != 1 ||
|
||||
val > 65535) FATAL("Malformed IPv6 address (bad octet value).");
|
||||
|
||||
ret[seg * 2] = val >> 8;
|
||||
ret[seg * 2 + 1] = val;
|
||||
|
||||
seg++;
|
||||
|
||||
while (isxdigit(*str)) str++;
|
||||
if (*str) str++;
|
||||
|
||||
}
|
||||
|
||||
if (seg != 8) FATAL("Malformed IPv6 address (don't abbreviate).");
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define W(_x) (_x) >> 8, (_x) & 0xff
|
||||
#define D(_x) (_x) >> 24, ((_x) >> 16) & 0xff, ((_x) >> 8) & 0xff, (_x) & 0xff
|
||||
|
||||
#define EOL TCPOPT_EOL
|
||||
#define NOP TCPOPT_NOP
|
||||
#define MSS(_x) TCPOPT_MAXSEG, 4, W(_x)
|
||||
#define WS(_x) TCPOPT_WSCALE, 3, (_x)
|
||||
#define SOK TCPOPT_SACKOK, 2
|
||||
#define TS(_x,_y) TCPOPT_TSTAMP, 10, D(_x), D(_y)
|
||||
|
||||
/* There are virtually no OSes that do not send MSS. Support for RFC 1323
|
||||
and 2018 is not given, so we have to test various combinations here. */
|
||||
|
||||
static u8 opt_combos[8][24] = {
|
||||
|
||||
{ MSS(SPECIAL_MSS), NOP, EOL }, /* 6 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), SOK, NOP, EOL }, /* 8 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), NOP, EOL }, /* 9 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), SOK, NOP, EOL }, /* 12 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), TS(1337, 0), NOP, EOL }, /* 17 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), SOK, TS(1337, 0), NOP, EOL }, /* 19 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), TS(1337, 0), NOP, EOL }, /* 20 */
|
||||
|
||||
{ MSS(SPECIAL_MSS), WS(5), SOK, TS(1337, 0), NOP, EOL } /* 22 */
|
||||
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
static struct sockaddr_in6 sin;
|
||||
char one = 1;
|
||||
s32 sock;
|
||||
u32 i;
|
||||
|
||||
static u8 work_buf[MIN_TCP6 + 24];
|
||||
|
||||
struct ipv6_hdr* ip6 = (struct ipv6_hdr*)work_buf;
|
||||
struct tcp_hdr* tcp = (struct tcp_hdr*)(ip6 + 1);
|
||||
u8 *opts = work_buf + MIN_TCP6;
|
||||
|
||||
|
||||
if (argc != 4) {
|
||||
ERRORF("Usage: p0f-sendsyn your_ip dst_ip port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parse_addr(argv[1], ip6->src);
|
||||
parse_addr(argv[2], ip6->dst);
|
||||
|
||||
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6);
|
||||
|
||||
if (sock < 0) PFATAL("Can't open raw socket (you need to be root).");
|
||||
|
||||
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&one, sizeof(char)))
|
||||
PFATAL("setsockopt() on raw socket failed.");
|
||||
|
||||
sin.sin6_family = PF_INET6;
|
||||
|
||||
memcpy(&sin.sin6_addr, ip6->dst, 16);
|
||||
|
||||
ip6->ver_tos = ntohl(6 << 24);
|
||||
ip6->pay_len = ntohs(sizeof(struct tcp_hdr) + 24);
|
||||
ip6->proto = PROTO_TCP;
|
||||
ip6->ttl = 192;
|
||||
|
||||
tcp->dport = htons(atoi(argv[3]));
|
||||
tcp->seq = htonl(0x12345678);
|
||||
tcp->doff_rsvd = ((sizeof(struct tcp_hdr) + 24) / 4) << 4;
|
||||
tcp->flags = TCP_SYN;
|
||||
tcp->win = htons(SPECIAL_WIN);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
tcp->sport = htons(65535 - i);
|
||||
|
||||
memcpy(opts, opt_combos[i], 24);
|
||||
tcp_cksum(ip6->src, ip6->dst, tcp, 24);
|
||||
|
||||
if (sendto(sock, work_buf, sizeof(work_buf), 0, (struct sockaddr*)&sin,
|
||||
sizeof(struct sockaddr_in6)) < 0) PFATAL("sendto() fails.");
|
||||
|
||||
usleep(100000);
|
||||
|
||||
}
|
||||
|
||||
SAYF("Eight packets sent! Check p0f output to examine responses, if any.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
46
docker/p0f/types.h
Normal file
46
docker/p0f/types.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
p0f - type definitions and minor macros
|
||||
---------------------------------------
|
||||
|
||||
Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
|
||||
|
||||
Distributed under the terms and conditions of GNU LGPL.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _HAVE_TYPES_H
|
||||
#define _HAVE_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))
|
||||
# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))
|
||||
#endif /* !MIN */
|
||||
|
||||
/* Macros for non-aligned memory access. */
|
||||
|
||||
#ifdef ALIGN_ACCESS
|
||||
# include <string.h>
|
||||
# define RD16(_val) ({ u16 _ret; memcpy(&_ret, &(_val), 2); _ret; })
|
||||
# define RD32(_val) ({ u32 _ret; memcpy(&_ret, &(_val), 4); _ret; })
|
||||
# define RD16p(_ptr) ({ u16 _ret; memcpy(&_ret, _ptr, 2); _ret; })
|
||||
# define RD32p(_ptr) ({ u32 _ret; memcpy(&_ret, _ptr, 4); _ret; })
|
||||
#else
|
||||
# define RD16(_val) ((u16)_val)
|
||||
# define RD32(_val) ((u32)_val)
|
||||
# define RD16p(_ptr) (*((u16*)(_ptr)))
|
||||
# define RD32p(_ptr) (*((u32*)(_ptr)))
|
||||
#endif /* ^ALIGN_ACCESS */
|
||||
|
||||
#endif /* ! _HAVE_TYPES_H */
|
Reference in New Issue
Block a user