/src/ndpi/src/lib/protocols/socks45.c
Line | Count | Source |
1 | | /* |
2 | | * socks4.c |
3 | | * |
4 | | * Copyright (C) 2016-22 - ntop.org |
5 | | * Copyright (C) 2014 Tomasz Bujlow <tomasz@skatnet.dk> |
6 | | * |
7 | | * The signature is based on the Libprotoident library. |
8 | | * |
9 | | * This file is part of nDPI, an open source deep packet inspection |
10 | | * library based on the OpenDPI and PACE technology by ipoque GmbH |
11 | | * |
12 | | * nDPI is free software: you can redistribute it and/or modify |
13 | | * it under the terms of the GNU Lesser General Public License as published by |
14 | | * the Free Software Foundation, either version 3 of the License, or |
15 | | * (at your option) any later version. |
16 | | * |
17 | | * nDPI is distributed in the hope that it will be useful, |
18 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | | * GNU Lesser General Public License for more details. |
21 | | * |
22 | | * You should have received a copy of the GNU Lesser General Public License |
23 | | * along with nDPI. If not, see <http://www.gnu.org/licenses/>. |
24 | | * |
25 | | */ |
26 | | #include "ndpi_protocol_ids.h" |
27 | | |
28 | | #define NDPI_CURRENT_PROTO NDPI_PROTOCOL_SOCKS |
29 | | |
30 | | #include "ndpi_api.h" |
31 | | #include "ndpi_private.h" |
32 | | |
33 | | static void ndpi_int_socks_add_connection(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) |
34 | 117 | { |
35 | 117 | ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SOCKS, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI); |
36 | 117 | } |
37 | | |
38 | | static void ndpi_check_socks4(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) |
39 | 3.47M | { |
40 | 3.47M | struct ndpi_packet_struct *packet = &ndpi_struct->packet; |
41 | 3.47M | u_int32_t payload_len = packet->payload_packet_len; |
42 | | |
43 | | /* Check if we so far detected the protocol in the request or not. */ |
44 | 3.47M | if(flow->l4.tcp.socks4_stage == 0) { |
45 | 3.47M | NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage 0: \n"); |
46 | | |
47 | 3.47M | if(payload_len >= 9 && packet->payload[0] == 0x04 && |
48 | 3.47M | (packet->payload[1] == 0x01 || packet->payload[1] == 0x02) && |
49 | 3.47M | packet->payload[payload_len - 1] == 0x00) { |
50 | 1.45k | NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS4 request detected, we will look further for the response\n"); |
51 | | /* TODO: check port and ip address is valid */ |
52 | | /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ |
53 | 1.45k | flow->l4.tcp.socks4_stage = packet->packet_direction + 1; |
54 | 1.45k | } |
55 | 3.47M | } else { |
56 | 1.72k | NDPI_LOG_DBG2(ndpi_struct, "SOCKS4 stage %u: \n", flow->l4.tcp.socks4_stage); |
57 | | |
58 | | /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ |
59 | 1.72k | if((flow->l4.tcp.socks4_stage - packet->packet_direction) == 1) { |
60 | 1.44k | return; |
61 | 1.44k | } |
62 | | /* This is a packet in another direction. Check if we find the proper response. */ |
63 | 283 | if(payload_len == 8 && packet->payload[0] == 0x00 && packet->payload[1] >= 0x5a && packet->payload[1] <= 0x5d) { |
64 | 47 | NDPI_LOG_INFO(ndpi_struct, "found SOCKS4\n"); |
65 | 47 | ndpi_int_socks_add_connection(ndpi_struct, flow); |
66 | 236 | } else { |
67 | 236 | NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS4, resetting the stage to 0\n"); |
68 | 236 | flow->l4.tcp.socks4_stage = 0; |
69 | 236 | } |
70 | 283 | } |
71 | 3.47M | } |
72 | | |
73 | | static void ndpi_check_socks5(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) |
74 | 3.47M | { |
75 | 3.47M | struct ndpi_packet_struct *packet = &ndpi_struct->packet; |
76 | 3.47M | u_int32_t payload_len = packet->payload_packet_len; |
77 | | |
78 | | /* Check if we so far detected the protocol in the request or not. */ |
79 | 3.47M | if(flow->l4.tcp.socks5_stage == 0) { |
80 | 3.47M | NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage 0: \n"); |
81 | | |
82 | 3.47M | if(((payload_len == 3) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x01) && (packet->payload[2] == 0x00)) || |
83 | 3.47M | ((payload_len == 4) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x02) && (packet->payload[2] == 0x00) && (packet->payload[3] == 0x01))) { |
84 | 799 | NDPI_LOG_DBG2(ndpi_struct, "Possible SOCKS5 request detected, we will look further for the response\n"); |
85 | | |
86 | | /* Encode the direction of the packet in the stage, so we will know when we need to look for the response packet. */ |
87 | 799 | flow->l4.tcp.socks5_stage = packet->packet_direction + 1; |
88 | 799 | } |
89 | | |
90 | 3.47M | } else { |
91 | 1.01k | NDPI_LOG_DBG2(ndpi_struct, "SOCKS5 stage %u: \n", flow->l4.tcp.socks5_stage); |
92 | | |
93 | | /* At first check, if this is for sure a response packet (in another direction. If not, do nothing now and return. */ |
94 | 1.01k | if((flow->l4.tcp.socks5_stage - packet->packet_direction) == 1) { |
95 | 729 | return; |
96 | 729 | } |
97 | | |
98 | | /* This is a packet in another direction. Check if we find the proper response. */ |
99 | 288 | if((payload_len == 0) || ((payload_len == 2) && (packet->payload[0] == 0x05) && (packet->payload[1] == 0x00))) { |
100 | 70 | NDPI_LOG_INFO(ndpi_struct, "found SOCKS5\n"); |
101 | 70 | ndpi_int_socks_add_connection(ndpi_struct, flow); |
102 | 218 | } else { |
103 | 218 | NDPI_LOG_DBG2(ndpi_struct, "The reply did not seem to belong to SOCKS5, resetting the stage to 0\n"); |
104 | 218 | flow->l4.tcp.socks5_stage = 0; |
105 | 218 | } |
106 | | |
107 | 288 | } |
108 | 3.47M | } |
109 | | |
110 | | static void ndpi_search_socks(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) |
111 | 3.49M | { |
112 | 3.49M | NDPI_LOG_DBG(ndpi_struct, "search SOCKS\n"); |
113 | | |
114 | 3.49M | if(flow->packet_counter >= 10) { |
115 | 24.9k | NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow); |
116 | 24.9k | return; |
117 | 24.9k | } |
118 | | |
119 | 3.47M | ndpi_check_socks4(ndpi_struct, flow); |
120 | | |
121 | 3.47M | if(flow->detected_protocol_stack[0] != NDPI_PROTOCOL_SOCKS) |
122 | 3.47M | ndpi_check_socks5(ndpi_struct, flow); |
123 | 3.47M | } |
124 | | |
125 | | void init_socks_dissector(struct ndpi_detection_module_struct *ndpi_struct) |
126 | 15.4k | { |
127 | 15.4k | register_dissector("SOCKS", ndpi_struct, |
128 | 15.4k | ndpi_search_socks, |
129 | 15.4k | NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION, |
130 | 15.4k | 1, NDPI_PROTOCOL_SOCKS); |
131 | 15.4k | } |
132 | | |