-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathssl-snitch.bt
executable file
·125 lines (111 loc) · 3.05 KB
/
ssl-snitch.bt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env bpftrace
/*
* ssl-snitch
*
* Identify processes communicating using the TLS protocol
* with the OpenSSL library.
*
* usage: ./ssl-snitch [port]
*
* The tool works in two stages:
* 1. Intercept TCP connections and remember the
* destination IP and port
* 2. Intercept OpenSSL read and write functions
* and report the witnessed TLS connection
*
* 18-Nov-2021 Fabien Savy Initial version
*
*/
#include <linux/socket.h>
#include <net/sock.h>
BEGIN
{
printf("Tracing TLS connections... Press Ctrl-C to exit\n\n");
printf("%-8s ", "TIME");
printf("%-20s %-8s %-39s %-6s\n", "COMMAND", "PID", "DADDR", "DPORT");
}
/*
* Intercept tcp_connect event and save the `sock` structure.
*
* This is done to factorize both `connect` and `accept` events below.
*/
kprobe:tcp_connect
{
@connect[pid] = 1;
@sock[pid] = (struct sock *) arg0;
}
/*
* Intercept successfully established TCP connections
* and remember the PID - (destination port, address) association
*
* inspired from https://github.com/iovisor/bpftrace/blob/master/tools/tcpconnect.bt
*/
kretprobe:tcp_connect,
kretprobe:inet_csk_accept
{
// Retrieve data from the map if available
if (@connect[pid] == 1) {
$sock = @sock[pid];
} else {
$sock = ((struct sock *) retval);
}
$inet_family = $sock->__sk_common.skc_family;
if ($inet_family == AF_INET || $inet_family == AF_INET6) {
// extract destination address ($daddr)
if ($inet_family == AF_INET) {
$daddr = ntop($sock->__sk_common.skc_daddr);
} else {
$daddr = ntop($sock->__sk_common.skc_v6_daddr.in6_u.u6_addr8);
}
// extract destination port (mind the endianness!)
// we have to allocate the resulting variable beforehand,
// probably because of https://github.com/iovisor/bpftrace/issues/1332
$dport = 0;
$dport = bswap($sock->__sk_common.skc_dport);
// filter out uninteresting ports if specified
if ($1 == 0 || $1 == $dport) {
// remember the distant host
@data[pid] = ($daddr, $dport);
}
}
// Clear no longer needed data
if (@connect[pid] == 1) {
delete(@connect[pid]);
delete(@sock[pid]);
}
}
/*
* Intercept calls to SSL_read and SSL_write
* (which always happen after a connection has been established).
* Log the target process and clean up data.
*
* The commented probes target the Firefox cryptography library
*/
// uprobe:/usr/lib/firefox/libnspr4.so:PR_Write,
// uprobe:/usr/lib/firefox/libnspr4.so:PR_Read,
uprobe:/usr/lib/x86_64-linux-gnu/libssl.so:SSL_read,
uprobe:/usr/lib/x86_64-linux-gnu/libssl.so:SSL_write
{
if (@data[pid].1) {
time("%H:%M:%S ");
printf("%-20s %-8d %-39s %-6d\n", comm, pid, @data[pid].0, @data[pid].1);
// delete the association to avoid logging further calls
// on the same TCP connection
delete(@data[pid]);
}
}
/*
* Get rid of the data of exiting processes
* (this would otherwise be a memory leak)
*/
tracepoint:sched:sched_process_exit
{
delete(@data[pid]);
}
/*
* Clear all remaining data when the tool exits
*/
END
{
clear(@data);
}