diff options
Diffstat (limited to 'src/fnettrace-sni/main.c')
-rw-r--r-- | src/fnettrace-sni/main.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/src/fnettrace-sni/main.c b/src/fnettrace-sni/main.c index 571089e29..71793a560 100644 --- a/src/fnettrace-sni/main.c +++ b/src/fnettrace-sni/main.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <time.h> | 22 | #include <time.h> |
23 | #include <linux/filter.h> | 23 | #include <linux/filter.h> |
24 | #include <linux/if_ether.h> | 24 | #include <linux/if_ether.h> |
25 | #include <sys/prctl.h> | ||
26 | #include <signal.h> | ||
25 | #define MAX_BUF_SIZE (64 * 1024) | 27 | #define MAX_BUF_SIZE (64 * 1024) |
26 | 28 | ||
27 | static char last[512] = {'\0'}; | 29 | static char last[512] = {'\0'}; |
@@ -94,19 +96,22 @@ nosni: | |||
94 | // https://www.kernel.org/doc/html/latest/networking/filter.html | 96 | // https://www.kernel.org/doc/html/latest/networking/filter.html |
95 | static void custom_bpf(int sock) { | 97 | static void custom_bpf(int sock) { |
96 | struct sock_filter code[] = { | 98 | struct sock_filter code[] = { |
97 | // sudo tcpdump "tcp port 443 and (tcp[((tcp[12] & 0xf0) >>2)] = 0x16) && (tcp[((tcp[12] & 0xf0) >>2)+5] = 0x01)" -dd | 99 | // ports: 443 (regular TLS), 853 (DoT) |
100 | // sudo tcpdump "tcp port (443 or 853) and (tcp[((tcp[12] & 0xf0) >>2)] = 0x16) && (tcp[((tcp[12] & 0xf0) >>2)+5] = 0x01)" -dd | ||
98 | { 0x28, 0, 0, 0x0000000c }, | 101 | { 0x28, 0, 0, 0x0000000c }, |
99 | { 0x15, 27, 0, 0x000086dd }, | 102 | { 0x15, 29, 0, 0x000086dd }, |
100 | { 0x15, 0, 26, 0x00000800 }, | 103 | { 0x15, 0, 28, 0x00000800 }, |
101 | { 0x30, 0, 0, 0x00000017 }, | 104 | { 0x30, 0, 0, 0x00000017 }, |
102 | { 0x15, 0, 24, 0x00000006 }, | 105 | { 0x15, 0, 26, 0x00000006 }, |
103 | { 0x28, 0, 0, 0x00000014 }, | 106 | { 0x28, 0, 0, 0x00000014 }, |
104 | { 0x45, 22, 0, 0x00001fff }, | 107 | { 0x45, 24, 0, 0x00001fff }, |
105 | { 0xb1, 0, 0, 0x0000000e }, | 108 | { 0xb1, 0, 0, 0x0000000e }, |
106 | { 0x48, 0, 0, 0x0000000e }, | 109 | { 0x48, 0, 0, 0x0000000e }, |
107 | { 0x15, 2, 0, 0x000001bb }, | 110 | { 0x15, 4, 0, 0x000001bb }, |
111 | { 0x15, 3, 0, 0x00000355 }, | ||
108 | { 0x48, 0, 0, 0x00000010 }, | 112 | { 0x48, 0, 0, 0x00000010 }, |
109 | { 0x15, 0, 17, 0x000001bb }, | 113 | { 0x15, 1, 0, 0x000001bb }, |
114 | { 0x15, 0, 17, 0x00000355 }, | ||
110 | { 0x50, 0, 0, 0x0000001a }, | 115 | { 0x50, 0, 0, 0x0000001a }, |
111 | { 0x54, 0, 0, 0x000000f0 }, | 116 | { 0x54, 0, 0, 0x000000f0 }, |
112 | { 0x74, 0, 0, 0x00000002 }, | 117 | { 0x74, 0, 0, 0x00000002 }, |
@@ -139,6 +144,19 @@ static void custom_bpf(int sock) { | |||
139 | } | 144 | } |
140 | } | 145 | } |
141 | 146 | ||
147 | static void print_date(void) { | ||
148 | static int day = -1; | ||
149 | time_t now = time(NULL); | ||
150 | struct tm *t = localtime(&now); | ||
151 | |||
152 | if (day != t->tm_yday) { | ||
153 | printf("\nSNI trace for %s", ctime(&now)); | ||
154 | day = t->tm_yday; | ||
155 | } | ||
156 | |||
157 | fflush(0); | ||
158 | } | ||
159 | |||
142 | static void run_trace(void) { | 160 | static void run_trace(void) { |
143 | // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets | 161 | // grab all Ethernet packets and use a custom BPF filter to get TLS/SNI packets |
144 | int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); | 162 | int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); |
@@ -146,19 +164,24 @@ static void run_trace(void) { | |||
146 | errExit("socket"); | 164 | errExit("socket"); |
147 | custom_bpf(s); | 165 | custom_bpf(s); |
148 | 166 | ||
167 | struct timeval tv; | ||
168 | tv.tv_sec = 10; | ||
169 | tv.tv_usec = 0; | ||
149 | unsigned char buf[MAX_BUF_SIZE]; | 170 | unsigned char buf[MAX_BUF_SIZE]; |
150 | while (1) { | 171 | while (1) { |
151 | fd_set rfds; | 172 | fd_set rfds; |
152 | FD_ZERO(&rfds); | 173 | FD_ZERO(&rfds); |
153 | FD_SET(s, &rfds); | 174 | FD_SET(s, &rfds); |
154 | struct timeval tv; | ||
155 | tv.tv_sec = 1; | ||
156 | tv.tv_usec = 0; | ||
157 | int rv = select(s + 1, &rfds, NULL, NULL, &tv); | 175 | int rv = select(s + 1, &rfds, NULL, NULL, &tv); |
158 | if (rv < 0) | 176 | if (rv < 0) |
159 | errExit("select"); | 177 | errExit("select"); |
160 | else if (rv == 0) | 178 | else if (rv == 0) { |
179 | print_date(); | ||
180 | tv.tv_sec = 10; | ||
181 | tv.tv_usec = 0; | ||
161 | continue; | 182 | continue; |
183 | } | ||
184 | |||
162 | unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL); | 185 | unsigned bytes = recvfrom(s, buf, MAX_BUF_SIZE, 0, NULL, NULL); |
163 | 186 | ||
164 | if (bytes >= (14 + 20 + 20)) { // size of MAC + IP + TCP headers | 187 | if (bytes >= (14 + 20 + 20)) { // size of MAC + IP + TCP headers |
@@ -166,15 +189,13 @@ static void run_trace(void) { | |||
166 | uint16_t port_dest; | 189 | uint16_t port_dest; |
167 | memcpy(&port_dest, buf + 14 + ip_hlen + 2, 2); | 190 | memcpy(&port_dest, buf + 14 + ip_hlen + 2, 2); |
168 | port_dest = ntohs(port_dest); | 191 | port_dest = ntohs(port_dest); |
169 | uint8_t protocol = buf[14 + 9]; | ||
170 | uint32_t ip_dest; | 192 | uint32_t ip_dest; |
171 | memcpy(&ip_dest, buf + 14 + 16, 4); | 193 | memcpy(&ip_dest, buf + 14 + 16, 4); |
172 | ip_dest = ntohl(ip_dest); | 194 | ip_dest = ntohl(ip_dest); |
173 | uint8_t tcp_hlen = (buf[14 + ip_hlen + 12] & 0xf0) >> 2; | 195 | uint8_t tcp_hlen = (buf[14 + ip_hlen + 12] & 0xf0) >> 2; |
174 | 196 | ||
175 | // if TLS packet, extract SNI | 197 | // extract SNI |
176 | if (port_dest == 443 && protocol == 6) // TCP protocol | 198 | print_tls(ip_dest, buf + 14 + ip_hlen + tcp_hlen, bytes - 14 - ip_hlen - tcp_hlen); // IP and TCP header len |
177 | print_tls(ip_dest, buf + 14 + ip_hlen + tcp_hlen, bytes - 14 - ip_hlen - tcp_hlen); // IP and TCP header len | ||
178 | } | 199 | } |
179 | } | 200 | } |
180 | 201 | ||
@@ -208,8 +229,10 @@ int main(int argc, char **argv) { | |||
208 | return 1; | 229 | return 1; |
209 | } | 230 | } |
210 | 231 | ||
211 | time_t now = time(NULL); | 232 | // kill the process if the parent died |
212 | printf("SNI trace for %s\n", ctime(&now)); | 233 | prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); |
234 | |||
235 | print_date(); | ||
213 | run_trace(); | 236 | run_trace(); |
214 | 237 | ||
215 | return 0; | 238 | return 0; |