github.com/castai/kvisor@v1.7.1-0.20240516114728-b3572a2607b5/pkg/ebpftracer/signature/socks5_detected_test.go (about) 1 package signature 2 3 import ( 4 "testing" 5 6 v1 "github.com/castai/kvisor/api/v1/runtime" 7 "github.com/castai/kvisor/pkg/containers" 8 "github.com/castai/kvisor/pkg/ebpftracer/events" 9 "github.com/castai/kvisor/pkg/ebpftracer/types" 10 "github.com/stretchr/testify/require" 11 ) 12 13 var socks5ClientRequestData = []byte{ 14 // IPv4 header 15 0x45, 0x00, 0x00, 0x38, 0x3c, 0x23, 0x40, 0x00, 16 0x40, 0x06, 0x00, 0x9b, 0x7f, 0x00, 0x00, 0x01, 17 0x7f, 0x00, 0x00, 0x01, 0xae, 0x20, 0x04, 0x38, 18 0xed, 0xbb, 0x47, 0xad, 0x77, 0x45, 0x5a, 0x21, 19 0x80, 0x18, 0x02, 0x00, 0xfe, 0x2c, 0x00, 0x00, 20 0x01, 0x01, 0x08, 0x0a, 0x3c, 0xfe, 0xe8, 0x88, 21 0x3c, 0xfe, 0xe8, 0x88, 0x05, 0x02, 22 23 // SOCKS5 start 24 0x00, 0x01, 25 } 26 27 var socks5ServerMethodSelectData = []byte{ 28 // IPv4 header 29 0x45, 0x00, 0x00, 0x36, 0x29, 0x67, 0x40, 0x00, 30 0x40, 0x06, 0x13, 0x59, 0x7f, 0x00, 0x00, 0x01, 31 0x7f, 0x00, 0x00, 0x01, 0x04, 0x38, 0xae, 0x20, 32 0x77, 0x45, 0x5a, 0x21, 0xed, 0xbb, 0x47, 0xb1, 33 0x80, 0x18, 0x02, 0x00, 0xfe, 0x2a, 0x00, 0x00, 34 0x01, 0x01, 0x08, 0x0a, 0x3c, 0xfe, 0xe8, 0x89, 35 0x3c, 0xfe, 0xe8, 0x88, 36 37 // SOCKS5 start 38 0x05, 0x00, 39 } 40 41 var socks5ClientConnectRequestData = []byte{ 42 // IPv4 header 43 0x45, 0x00, 0x00, 0x3e, 0x3c, 0x25, 0x40, 0x00, 44 0x40, 0x06, 0x00, 0x93, 0x7f, 0x00, 0x00, 0x01, 45 0x7f, 0x00, 0x00, 0x01, 0xae, 0x20, 0x04, 0x38, 46 0xed, 0xbb, 0x47, 0xb1, 0x77, 0x45, 0x5a, 0x23, 47 0x80, 0x18, 0x02, 0x00, 0xfe, 0x32, 0x00, 0x00, 48 0x01, 0x01, 0x08, 0x0a, 0x3c, 0xfe, 0xe8, 0x9b, 49 0x3c, 0xfe, 0xe8, 0x89, 50 51 // SOCKS5 start 52 0x05, 53 0x01, //connect 54 0x00, 55 0x01, // IPv4 56 // IP data of 142.250.185.99 57 0x8e, 0xfa, 0xb9, 0x63, 58 // Port 80 59 0x00, 0x50, 60 } 61 62 var socks5ServerConnectResponseData = []byte{ 63 // IPv4 header 64 0x45, 0x00, 0x00, 0x3e, 0x29, 0x69, 0x40, 0x00, 65 0x40, 0x06, 0x13, 0x4f, 0x7f, 0x00, 0x00, 0x01, 66 0x7f, 0x00, 0x00, 0x01, 0x04, 0x38, 0xae, 0x20, 67 0x77, 0x45, 0x5a, 0x23, 0xed, 0xbb, 0x47, 0xbb, 68 0x80, 0x18, 0x02, 0x00, 0xfe, 0x32, 0x00, 0x00, 69 0x01, 0x01, 0x08, 0x0a, 0x3c, 0xfe, 0xe8, 0xc9, 70 0x3c, 0xfe, 0xe8, 0x9b, 71 72 // SOCKS5 start 73 0x05, 74 0x00, // success 75 0x00, 76 0x01, // IPv4 77 // IP data of 10.244.0.22 78 0x0a, 0xf4, 0x00, 0x16, 79 // Port 52330 80 0xcc, 0x6a, 81 } 82 83 func TestSOCKS5DetectedSignature(t *testing.T) { 84 type eventWithFinding struct { 85 event types.Event 86 expectedFinding *v1.SignatureFinding 87 } 88 89 type testCase struct { 90 title string 91 events []eventWithFinding 92 } 93 94 testCases := []testCase{ 95 { 96 title: "should detect socks5 server", 97 events: []eventWithFinding{ 98 { 99 event: types.Event{ 100 Context: &types.EventContext{ 101 EventID: events.NetPacketSOCKS5Base, 102 Ts: 11, 103 CgroupID: 10, 104 Pid: 99, 105 Retval: types.FlagPacketIngress, 106 }, 107 Container: &containers.Container{ 108 ID: "123", 109 Name: "name-123", 110 CgroupID: 10, 111 }, 112 Args: types.NetPacketSOCKS5BaseArgs{ 113 Payload: socks5ClientRequestData, 114 }, 115 }, 116 }, 117 { 118 event: types.Event{ 119 Context: &types.EventContext{ 120 EventID: events.NetPacketSOCKS5Base, 121 Ts: 12, 122 CgroupID: 10, 123 Pid: 99, 124 Retval: types.FlagPacketEgress, 125 }, 126 Container: &containers.Container{ 127 ID: "123", 128 Name: "name-123", 129 CgroupID: 10, 130 }, 131 Args: types.NetPacketSOCKS5BaseArgs{ 132 Payload: socks5ServerMethodSelectData, 133 }, 134 }, 135 }, 136 { 137 event: types.Event{ 138 Context: &types.EventContext{ 139 EventID: events.NetPacketSOCKS5Base, 140 Ts: 13, 141 CgroupID: 10, 142 Pid: 99, 143 Retval: types.FlagPacketIngress, 144 }, 145 Container: &containers.Container{ 146 ID: "123", 147 Name: "name-123", 148 CgroupID: 10, 149 }, 150 Args: types.NetPacketSOCKS5BaseArgs{ 151 Payload: socks5ClientConnectRequestData, 152 }, 153 }, 154 expectedFinding: &v1.SignatureFinding{ 155 Data: &v1.SignatureFinding_Socks5Detected{ 156 Socks5Detected: &v1.SOCKS5DetectedFinding{ 157 Role: v1.SOCKS5Role_SOCKS5_ROLE_SERVER, 158 FlowDirection: v1.FlowDirection_FLOW_INGRESS, 159 CmdOrReply: 0x01, 160 AddressType: v1.SOCKS5AddressType_SOCKS5_ADDRESS_TYPE_IPv4, 161 Address: []byte{0x8e, 0xfa, 0xb9, 0x63}, 162 Port: 80, 163 }, 164 }, 165 }, 166 }, 167 { 168 event: types.Event{ 169 Context: &types.EventContext{ 170 EventID: events.NetPacketSOCKS5Base, 171 Ts: 13, 172 CgroupID: 10, 173 Pid: 99, 174 Retval: types.FlagPacketEgress, 175 }, 176 Container: &containers.Container{ 177 ID: "123", 178 Name: "name-123", 179 CgroupID: 10, 180 }, 181 Args: types.NetPacketSOCKS5BaseArgs{ 182 Payload: socks5ServerConnectResponseData, 183 }, 184 }, 185 expectedFinding: &v1.SignatureFinding{ 186 Data: &v1.SignatureFinding_Socks5Detected{ 187 Socks5Detected: &v1.SOCKS5DetectedFinding{ 188 Role: v1.SOCKS5Role_SOCKS5_ROLE_SERVER, 189 FlowDirection: v1.FlowDirection_FLOW_EGRESS, 190 CmdOrReply: 0x00, 191 AddressType: v1.SOCKS5AddressType_SOCKS5_ADDRESS_TYPE_IPv4, 192 Address: []byte{0x0a, 0xf4, 0x00, 0x16}, 193 Port: 52330, 194 }, 195 }, 196 }, 197 }, 198 }, 199 }, 200 { 201 title: "should detect socks5 client", 202 events: []eventWithFinding{ 203 { 204 event: types.Event{ 205 Context: &types.EventContext{ 206 EventID: events.NetPacketSOCKS5Base, 207 Ts: 11, 208 CgroupID: 10, 209 Pid: 99, 210 Retval: types.FlagPacketEgress, 211 }, 212 Container: &containers.Container{ 213 ID: "123", 214 Name: "name-123", 215 CgroupID: 10, 216 }, 217 Args: types.NetPacketSOCKS5BaseArgs{ 218 Payload: socks5ClientRequestData, 219 }, 220 }, 221 }, 222 { 223 event: types.Event{ 224 Context: &types.EventContext{ 225 EventID: events.NetPacketSOCKS5Base, 226 Ts: 12, 227 CgroupID: 10, 228 Pid: 99, 229 Retval: types.FlagPacketIngress, 230 }, 231 Container: &containers.Container{ 232 ID: "123", 233 Name: "name-123", 234 CgroupID: 10, 235 }, 236 Args: types.NetPacketSOCKS5BaseArgs{ 237 Payload: socks5ServerMethodSelectData, 238 }, 239 }, 240 }, 241 { 242 event: types.Event{ 243 Context: &types.EventContext{ 244 EventID: events.NetPacketSOCKS5Base, 245 Ts: 13, 246 CgroupID: 10, 247 Pid: 99, 248 Retval: types.FlagPacketEgress, 249 }, 250 Container: &containers.Container{ 251 ID: "123", 252 Name: "name-123", 253 CgroupID: 10, 254 }, 255 Args: types.NetPacketSOCKS5BaseArgs{ 256 Payload: socks5ClientConnectRequestData, 257 }, 258 }, 259 expectedFinding: &v1.SignatureFinding{ 260 Data: &v1.SignatureFinding_Socks5Detected{ 261 Socks5Detected: &v1.SOCKS5DetectedFinding{ 262 Role: v1.SOCKS5Role_SOCKS5_ROLE_CLIENT, 263 FlowDirection: v1.FlowDirection_FLOW_EGRESS, 264 CmdOrReply: 0x01, 265 AddressType: v1.SOCKS5AddressType_SOCKS5_ADDRESS_TYPE_IPv4, 266 Address: []byte{0x8e, 0xfa, 0xb9, 0x63}, 267 Port: 80, 268 }, 269 }, 270 }, 271 }, 272 { 273 event: types.Event{ 274 Context: &types.EventContext{ 275 EventID: events.NetPacketSOCKS5Base, 276 Ts: 13, 277 CgroupID: 10, 278 Pid: 99, 279 Retval: types.FlagPacketIngress, 280 }, 281 Container: &containers.Container{ 282 ID: "123", 283 Name: "name-123", 284 CgroupID: 10, 285 }, 286 Args: types.NetPacketSOCKS5BaseArgs{ 287 Payload: socks5ServerConnectResponseData, 288 }, 289 }, 290 expectedFinding: &v1.SignatureFinding{ 291 Data: &v1.SignatureFinding_Socks5Detected{ 292 Socks5Detected: &v1.SOCKS5DetectedFinding{ 293 Role: v1.SOCKS5Role_SOCKS5_ROLE_CLIENT, 294 FlowDirection: v1.FlowDirection_FLOW_INGRESS, 295 CmdOrReply: 0x00, 296 AddressType: v1.SOCKS5AddressType_SOCKS5_ADDRESS_TYPE_IPv4, 297 Address: []byte{0x0a, 0xf4, 0x00, 0x16}, 298 Port: 52330, 299 }, 300 }, 301 }, 302 }, 303 }, 304 }, 305 { 306 title: "should detect socks5 on only connect message", 307 events: []eventWithFinding{ 308 { 309 event: types.Event{ 310 Context: &types.EventContext{ 311 EventID: events.NetPacketSOCKS5Base, 312 Ts: 13, 313 CgroupID: 10, 314 Pid: 99, 315 Retval: types.FlagPacketEgress, 316 }, 317 Container: &containers.Container{ 318 ID: "123", 319 Name: "name-123", 320 CgroupID: 10, 321 }, 322 Args: types.NetPacketSOCKS5BaseArgs{ 323 Payload: socks5ClientConnectRequestData, 324 }, 325 }, 326 expectedFinding: &v1.SignatureFinding{ 327 Data: &v1.SignatureFinding_Socks5Detected{ 328 Socks5Detected: &v1.SOCKS5DetectedFinding{ 329 Role: v1.SOCKS5Role_SOCKS5_ROLE_UNKNOWN, 330 FlowDirection: v1.FlowDirection_FLOW_EGRESS, 331 CmdOrReply: 0x01, 332 AddressType: v1.SOCKS5AddressType_SOCKS5_ADDRESS_TYPE_IPv4, 333 Address: []byte{0x8e, 0xfa, 0xb9, 0x63}, 334 Port: 80, 335 }, 336 }, 337 }, 338 }, 339 }, 340 }, 341 } 342 343 for _, test := range testCases { 344 t.Run(test.title, func(t *testing.T) { 345 r := require.New(t) 346 347 signature, err := NewSOCKS5DetectedSignature(SOCKS5DetectionSignatureConfig{}) 348 r.NoError(err) 349 350 for i, e := range test.events { 351 result := signature.OnEvent(&e.event) 352 353 if e.expectedFinding == nil { 354 r.Nil(result) 355 continue 356 } 357 r.Equal(e.expectedFinding, result, "match finding for event nr. %d: %d", i, e.event.Context.EventID) 358 } 359 }) 360 } 361 }