eCapture – przechwytywanie SSL/TLS bez CA przy użyciu eBPF
Napisał: Patryk Krawaczyński
25/05/2022 w Bezpieczeństwo, Pen Test Brak komentarzy. (artykuł nr 819, ilość słów: 2261)
W
yobraźmy sobie, że nasz system został zainfekowany przerobionym i trudnym do wykrycia implantem sieciowym. W swojej przeróbce został on uzbrojony w moduł inwigilacji oparty o eCapture. Jest to zwinne narzędzie napisane w języku Go, które również wykorzystuje technologię eBPF. Umożliwia ona uruchamianie programów zamkniętych w piaskownicy jądra systemu operacyjnego. Dzięki temu potrafi przechwycić zaszyfrowaną komunikację sieciową bez konieczności “podpinania” Urzędu Certyfikacji (ang. Certificate Authority), któremu należy zaufać. Zamiast tego wpina się w funkcje SSL_write
/ SSL_read
współdzielonej biblioteki SSL, aby uzyskać kontekst tekstowy i wysłać tak uzyskane wiadomości do przestrzeni użytkownika za pomocą map eBPF.
W celu uruchomienia eCapture musimy posiadać jądro systemu w wersji >= 4.18. Nie musimy za to kompilować kodu źródłowego, ponieważ projekt dostarcza już gotowe pliki binarne ELF:
wget 'https://github.com/ehids/ecapture/releases/download/v0.1.8/ecapture-v0.1.8.tar.gz' tar -xvf ecapture-v0.1.8.tar.gz
Sprawdzamy teraz z jakiej biblioteki współdzielonej SSL korzysta program curl, aby później wykorzystać to w konfiguracji eCapture:
root@darkstar:~# ldd `which curl` | grep -E "tls|ssl|nss" libssl.so.1.1 => /lib/x86_64-linux-gnu/libssl.so.1.1 (0x00007f64148dc000) libgnutls.so.30 => /lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f64141ea000)
W pierwszej konsoli uruchamiamy nasłuch:
root@darkstar:~# ./bin/ecapture tls --libssl="/lib/x86_64-linux-gnu/libssl.so.1.1" 2022/05/24 20:07:01 pid info :47441 2022/05/24 20:07:01 start to run EBPFProbeOPENSSL module 2022/05/24 20:07:01 start to run EBPFProbeGNUTLS module 2022/05/24 20:07:01 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libssl.so.1.1 2022/05/24 20:07:01 libPthread so Path:/lib/x86_64-linux-gnu/libpthread.so.0 2022/05/24 20:07:01 target all process. 2022/05/24 20:07:01 start to run EBPFProbeNSPR module 2022/05/24 20:07:01 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libgnutls.so.30 2022/05/24 20:07:01 target all process. 2022/05/24 20:07:01 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libnspr4.so 2022/05/24 20:07:01 target all process.
W drugiej konsoli uruchamiamy polecenie:
curl --http1.1 https://ipinfo.io/8.8.8.8?token=********
Jego wynik powinien pojawić się nam również na terminalu z włączonym nasłuchem:
2022/05/24 20:39:20 PID:47799, Comm:curl, TID:47799, Send 95 bytes to 34.117.59.81:443, Payload: GET /8.8.8.8?token=12345678 HTTP/1.1 Host: ipinfo.io User-Agent: curl/7.68.0 Accept: */* 2022/05/24 20:39:20 PID:47799, Comm:curl, TID:47799, Recived 799 bytes from 34.117.59.81:443, Payload: HTTP/1.1 200 OK access-control-allow-origin: * x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin content-type: application/json; charset=utf-8 content-length: 304 date: Tue, 24 May 2022 20:41:33 GMT x-envoy-upstream-service-time: 3 strict-transport-security: max-age=2592000; includeSubDomains vary: Accept-Encoding Via: 1.1 google Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 { "ip": "8.8.8.8", "hostname": "dns.google", "anycast": true, "city": "Mountain View", "region": "California", "country": "US", "loc": "37.4056,-122.0775", "org": "AS15169 Google LLC", "postal": "94043", "timezone": "America/Los_Angeles", "readme": "https://ipinfo.io/missingauth" }
Jak widzimy dla protokołu HTTP/1.1 rejestrowana jest cała komunikacja. Spójrzmy teraz jak wygląda ta operacja dla protokołu HTTP/2:
root@ubuntu:~# ./bin/darkstar tls --hex --libssl="/lib/x86_64-linux-gnu/libssl.so.1.1" 2022/05/25 18:30:32 pid info :1446 2022/05/25 18:30:32 start to run EBPFProbeOPENSSL module 2022/05/25 18:30:32 start to run EBPFProbeGNUTLS module 2022/05/25 18:30:32 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libssl.so.1.1 2022/05/25 18:30:32 libPthread so Path:/lib/x86_64-linux-gnu/libpthread.so.0 2022/05/25 18:30:32 target all process. 2022/05/25 18:30:32 start to run EBPFProbeNSPR module 2022/05/25 18:30:32 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libnspr4.so 2022/05/25 18:30:32 target all process. 2022/05/25 18:30:32 HOOK type:2, binrayPath:/lib/x86_64-linux-gnu/libgnutls.so.30 2022/05/25 18:30:32 target all process.
curl --http2 https://ipinfo.io/8.8.8.8
2022/05/25 18:34:24 PID:1513, Comm:curl, TID:1513, Recived 40 bytes from 34.117.59.81:443, Payload: 0000 00 00 12 04 00 00 00 00 00 00 03 00 00 00 64 00 ..............d. 0016 04 00 10 00 00 00 06 00 01 00 00 00 00 04 08 00 ................ 0032 00 00 00 00 00 0F 00 01 ........ 2022/05/25 18:34:24 PID:1513, Comm:curl, TID:1513, Send 9 bytes to 34.117.59.81:443, Payload: 0000 00 00 00 04 01 00 00 00 00 ......... 2022/05/25 18:34:24 PID:1513, Comm:curl, TID:1513, Recived 9 bytes from 34.117.59.81:443, Payload: 0000 00 00 00 04 01 00 00 00 00 ......... 2022/05/25 18:34:24 PID:1513, Comm:curl, TID:1513, Recived 293 bytes from 34.117.59.81:443, Payload: 0000 00 01 1C 01 04 00 00 00 01 88 54 01 2A 40 8B F2 ..........T.*@.. 0016 B4 B6 0E 92 AC 7A D2 63 D4 8F 89 DD 0E 8C 1A B6 .....z.c........ 0032 E4 C5 93 4F 40 8C F2 B7 94 21 6A EC 3A 4A 44 98 ...O@....!j.:JD. 0048 F5 7F 8A 0F DA 94 9E 42 C1 1D 07 27 5F 40 90 F2 .......B...'_@.. 0064 B1 0F 52 4B 52 56 4F AA CA B1 EB 49 8F 52 3F 85 ..RKRVO....I.R?. 0080 A8 E8 A8 D2 CB 40 8B B0 B2 96 CB 0B 62 D5 9E 83 .....@......b... 0096 13 D7 96 42 6C 31 12 B1 EC 34 C6 A9 6F 13 96 A5 ...Bl1...4..o... 0112 89 61 D0 85 8F 61 A6 35 5F 5F 96 1D 75 D0 62 0D .a...a.5__..u.b. 0128 26 3D 4C 74 41 EA FB 50 93 8E C4 15 30 5A 99 56 &=LtA..P....0Z.V 0144 7B 5C 03 33 30 34 0F 12 96 E4 59 3E 94 13 6A 68 {\.304....Y>..jh 0160 1F A5 04 01 09 40 BD 71 96 AE 09 A5 31 68 DF 40 .....@.q....1h.@ 0176 95 F2 B1 6A EE 7F 4B 5B 5A 13 61 47 4A C8 2D 9D ...j..K[Z.aGJ.-. 0192 CC 42 AC 93 52 5F 01 32 78 99 A4 7E 56 1C C5 80 .B..R_.2x..~V... 0208 4D BE 20 00 1F 6A 1A A2 51 6C 85 DD 6C 77 CF 48 M. ..j..Ql..lw.H 0224 CD 52 3F 7B 8B 84 84 2D 69 5B 05 44 3C 86 AA 6F .R?{...-i[.D<..o 0240 7C 87 0A E1 52 63 9E 6A 0B 40 85 1D 09 59 1D C9 |...Rc.j.@...Y.. 0256 A4 9D 98 3F 9B 8D 34 CF F3 F6 A5 23 80 4D BE 20 ...?..4....#.M. 0272 00 1F 53 B2 B0 9F 83 F9 B8 D3 4C FF 3F 6A 52 38 ..S.......L.?jR8 0288 04 DB E2 00 01 ..... 2022/05/25 18:34:24 PID:1513, Comm:curl, TID:1513, Recived 313 bytes from 34.117.59.81:443, Payload: 0000 00 01 30 00 00 00 00 00 01 7B 0A 20 20 22 69 70 ..0......{. "ip 0016 22 3A 20 22 38 2E 38 2E 38 2E 38 22 2C 0A 20 20 ": "8.8.8.8",. 0032 22 68 6F 73 74 6E 61 6D 65 22 3A 20 22 64 6E 73 "hostname": "dns 0048 2E 67 6F 6F 67 6C 65 22 2C 0A 20 20 22 61 6E 79 .google",. "any 0064 63 61 73 74 22 3A 20 74 72 75 65 2C 0A 20 20 22 cast": true,. " 0080 63 69 74 79 22 3A 20 22 4D 6F 75 6E 74 61 69 6E city": "Mountain 0096 20 56 69 65 77 22 2C 0A 20 20 22 72 65 67 69 6F View",. "regio 0112 6E 22 3A 20 22 43 61 6C 69 66 6F 72 6E 69 61 22 n": "California" 0128 2C 0A 20 20 22 63 6F 75 6E 74 72 79 22 3A 20 22 ,. "country": " 0144 55 53 22 2C 0A 20 20 22 6C 6F 63 22 3A 20 22 33 US",. "loc": "3 0160 37 2E 34 30 35 36 2C 2D 31 32 32 2E 30 37 37 35 7.4056,-122.0775 0176 22 2C 0A 20 20 22 6F 72 67 22 3A 20 22 41 53 31 ",. "org": "AS1 0192 35 31 36 39 20 47 6F 6F 67 6C 65 20 4C 4C 43 22 5169 Google LLC" 0208 2C 0A 20 20 22 70 6F 73 74 61 6C 22 3A 20 22 39 ,. "postal": "9 0224 34 30 34 33 22 2C 0A 20 20 22 74 69 6D 65 7A 6F 4043",. "timezo 0240 6E 65 22 3A 20 22 41 6D 65 72 69 63 61 2F 4C 6F ne": "America/Lo 0256 73 5F 41 6E 67 65 6C 65 73 22 2C 0A 20 20 22 72 s_Angeles",. "r 0272 65 61 64 6D 65 22 3A 20 22 68 74 74 70 73 3A 2F eadme": "https:/ 0288 2F 69 70 69 6E 66 6F 2E 69 6F 2F 6D 69 73 73 69 /ipinfo.io/missi 0304 6E 67 61 75 74 68 22 0A 7D ngauth".}
Dlaczego w przypadku HTTP/2 nie widzimy treści nagłówków? Ponieważ są one skompresowane algorytmem HPACK. Jeśli chcemy to możemy je "rozpakować" korzystając na przykład z modułu języka Python. Oprócz modułu tls eCapture dysponuje jeszcze modułami: mysql, postgres oraz bash:
root@darkstar:~# ./bin/ecapture bash 2022/05/25 19:35:20 start to run EBPFProbeBash module 2022/05/25 19:35:20 pid info :1641 2022/05/25 19:35:20 HOOK binrayPath:/bin/bash, FunctionName:readline 2022/05/25 19:35:20 HOOK binrayPath:/bin/bash, FunctionName:execute_command 2022/05/25 19:35:20 target all process. 2022/05/25 19:35:34 PID:1756, Comm:bash, Retvalue:0, Line: uname -a 2022/05/25 19:35:52 PID:1756, Comm:bash, Retvalue:0, Line: who 2022/05/25 19:36:35 PID:1756, Comm:bash, Retvalue:0, Line: curl -H 'Token: 12345678' https://stardust.nfsec.pl 2022/05/25 19:37:11 PID:1756, Comm:bash, Retvalue:127, Line: mysql -h localhost -u mysql -pr00tyTTY
Więcej informacji: eCapture, pspy – nieuprzywilejowany podgląd procesów Linuksa