mirror of
https://github.com/telekom-security/tpotce.git
synced 2025-04-20 06:02:24 +00:00
216 lines
9.5 KiB
C
216 lines
9.5 KiB
C
/*
|
|
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 */
|