ECapture – przechwytywanie SSL/TLS bez CA przy użyciu eBPF

nfsec.pl 2 lat temu

W

yobraźmy sobie, iż 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 dzięki 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 e1 c9 a4 cf f3 f6 a5 be ... b2 b0 f9 b8 d3 ff ..s.......l. db e2 ..... pid:1513 comm:curl tid:1513 recived bytes from payload: ..0...... .google cast true city view n us google llc ne s_angeles eadme ngauth>

Dlaczego w przypadku HTTP/2 nie widzimy treści nagłówków? Ponieważ są one skompresowane algorytmem HPACK. jeżeli 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

Idź do oryginalnego materiału