
리눅스 eBPF rootkit으로, 백도어, C2, 라이브러리 인젝션, 실행 하이재킹, 지속성 및 은닉 기능을 갖추고 있습니다.
TripleCross는 eBPF 기술의 공격적 기능을 보여주는 Linux eBPF 루트킷입니다.
TripleCross는 이 분야의 이전 임플란트 설계, 특히 DEFCON 27에서 Jeff Dileo1, DEFCON 29에서 Pat Hogan2, DEFCON 29에서 Guillaume Fournier와 Sylvain Afchain3, 그리고 Kris Nóva의 Boopkit4의 연구에서 영감을 받았습니다. 우리는 eBPF 기술의 공격적 기능에 대한 이전 탐구에서 개척된 기술 중 일부를 재사용하고 확장합니다.
이 루트킷은 UC3M에서의 학사 학위 논문을 위해 제작되었습니다. 설계에 대한 자세한 내용은 논문 문서에서 확인할 수 있습니다.
이 루트킷은 순전히 교육 및 학술 목적으로만 제공됩니다. 소프트웨어는 "있는 그대로" 제공되며, 저자는 사용 중 발생할 수 있는 손해나 사고에 대해 책임을 지지 않습니다.
법을 위반하기 위해 TripleCross를 사용하지 마십시오. 제공된 소프트웨어 및 정보의 오용은 형사 고발로 이어질 수 있습니다.
다음 그림은 TripleCross와 해당 모듈의 아키텍처를 보여줍니다.
루트킷 전송에 사용되는 원시 소켓 라이브러리 RawTCP_Lib는 저자가 작성하였으며 자체 저장소가 있습니다.
다음 표는 주요 소스 코드 파일과 디렉터리를 설명하여 탐색을 용이하게 합니다:
| 디렉터리 | 설명 |
|---|---|
| docs | 원본 논문 문서 |
| src/client | 루트킷 클라이언트의 소스 코드 |
| src/client/lib | RawTCP_Lib 공유 라이브러리 |
| src/common | 루트킷의 상수 및 구성. 또한 루트킷의 eBPF 및 사용자 공간 측면에 공통 요소(예: 링 버퍼)의 구현을 포함합니다 |
| src/ebpf | 루트킷에서 사용하는 eBPF 프로그램의 소스 코드 |
| src/helpers | 여러 루트킷 모듈의 기능을 테스트하기 위한 프로그램과 실행 하이재킹 및 라이브러리 주입 모듈에서 각각 사용되는 악성 프로그램 및 라이브러리를 포함합니다 |
| src/libbpf | 루트킷에 통합된 libbpf 라이브러리를 포함합니다 |
| src/user | 루트킷에서 사용하는 사용자 공간 프로그램의 소스 코드 |
| src/vmlinux | 커널 데이터 구조 정의를 포함하는 헤더(libbpf 사용 시 권장되는 방법) |
이 연구 프로젝트는 다음 환경에서 테스트되었습니다:
| 배포판 | 커널 | GCC | CLANG | GLIBC | |
|---|---|---|---|---|---|
| 버전 | Ubuntu 21.04 | 5.11.0 | 10.3.0 | 12.0.0 | 2.33 |
Ubuntu 21.04를 권장합니다. 기본적으로 여기에 표시된 소프트웨어 버전이 통합되어 있습니다. 그렇지 않은 경우 발생할 수 있는 몇 가지 문제는 여기에 설명되어 있습니다.
루트킷 소스 코드는 두 개의 Makefile을 사용하여 컴파일됩니다.```
cd src make all
cd client make
다음 표는 각 Makefile의 목적을 상세히 설명합니다:
| MAKEFILE | COMMAND | DESCRIPTION | RESULTING FILES |
| ------------- | ------------- | ------------- | ------------- |
| src/client/Makefile | make | 루트킷 클라이언트 컴파일 | src/client/injector |
| src/Makefile | make help | 루트킷 기능 테스트용 프로그램, 그리고 실행 하이재킹 및 라이브러리 인젝션 모듈의 악성 프로그램과 라이브러리 각각 컴파일 | src/helpers/simple_timer, src/helpers/simple_open, src/helpers/simple_execve, src/helpers/lib_injection.so, src/helpers/execve_hijack |
| src/Makefile | make kit | libbpf 라이브러리를 사용한 루트킷 컴파일 | src/bin/kit |
| src/Makefile | make tckit | 루트킷 TC egress 프로그램 컴파일 | src/bin/tc.o |
### 설치
루트킷 파일이 src/bin/ 아래에 생성된 후에는 *tc.o*와 *kit* 프로그램을 순서대로 로드해야 합니다. 다음 예제에서는 루트킷 백도어가 네트워크 인터페이스 *enp0s3*에서 작동합니다:```
// TC egress program
sudo tc qdisc add dev enp0s3 clsact
sudo tc filter add dev enp0s3 egress bpf direct-action obj bin/tc.o sec classifier/egress
// Libbpf-powered rootkit
sudo ./bin/kit -t enp0s3
공격자가 실제 공격 시나리오에서 할 것처럼 루트킷을 자동으로 컴파일하고 설치하는 두 개의 스크립트, packager.sh와 deployer.sh가 있습니다.
packager.sh를 실행하면 apps/ 디렉토리 아래에 모든 루트킷 파일이 생성됩니다.
deployer.sh를 실행하면 루트킷을 설치하고 지속성 파일을 생성합니다.
이 스크립트들은 지속성 모듈의 적절한 작동을 위해 먼저 다음 매개변수로 구성되어야 합니다:
| SCRIPT | CONSTANT | DESCRIPTION |
|---|---|---|
| src/helpers/deployer.sh | CRON_PERSIST | 재부팅 후 실행할 Cron 작업 |
| src/helpers/deployer.sh | SUDO_PERSIST | 비밀번호 없이 권한을 부여하는 Sudo 항목 |
루트킷은 sys_timerfd_settime 또는 sys_openat 시스템 호출을 호출하는 프로세스의 실행을 가로챌 수 있습니다. 이는 호출을 하는 프로세스의 가상 메모리에서 GOT(Global Offset Table) 섹션을 덮어씀으로써 달성됩니다. 이로 인해 악성 라이브러리(src/helpers/injection_lib.c)가 실행됩니다. 라이브러리는 공격자 머신에 리버스 셸을 생성한 후, 프로세스를 중단시키지 않고 실행 흐름을 원래 함수로 되돌립니다.
TripleCross는 다음과 같은 일반적인 ELF 보안 강화 기법을 우회할 준비가 되어 있습니다:
또한 인텔 CET 호환 코드와 함께 작동하도록 준비되어 있습니다.
모듈 기능은 두 개의 테스트 프로그램 src/helpers/simple_timer.c와 src/helpers/simple_open.c를 사용하여 확인할 수 있습니다. 또는 시스템 프로세스를 가로챌 수도 있습니다(systemd로 테스트 완료 및 작동 확인).
모듈 구성은 다음 상수를 통해 설정됩니다:
| FILENAME | CONSTANT | DESCRIPTION |
|---|---|---|
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_TIMERFD_SETTIME | sys_timerfd_settime 시스템 호출에서 가로챌 프로세스 이름 |
| src/common/constants.h | TASK_COMM_NAME_INJECTION_ TARGET_OPEN | sys_openat 시스템 호출에서 가로챌 프로세스 이름 |
| src/helpers/injection_lib.c | ATTACKER_IP & ATTACKER_PORT | 공격자 머신의 IP 주소와 포트 |
공격자 머신에서 리버스 셸을 수신하는 것은 netcat으로 할 수 있습니다:``` nc -nlvp <ATTACKER_PORT>
### GOT 하이재킹 기술을 통한 라이브러리 인젝션
TripleCross에 통합된 이 기술은 5단계로 구성됩니다:
#### GOT 및 리턴 주소 위치 찾기
루트킷은 트레이스포인트 프로그램을 사용하여 시스템 콜을 후킹합니다. 거기에서 PLT 스텁이 시스템 콜을 담당하는 glibc 함수를 호출하는 데 사용한 GOT 섹션의 주소를 찾습니다.
GOT 섹션에 도달하기 위해 eBPF 프로그램은 스택에 저장된 리턴 주소를 사용합니다. 참고:
* .text는 .plt를 *call* 하므로, *rip*가 스택에 *ret*로 저장됩니다.
* .plt는 .got를 사용하여 glibc로 *jump* 하므로 다른 *rip*는 저장되지 않습니다. 또한 *rbp* 값을 수정하거나 저장하지 않습니다.
* glibc는 *syscall*을 수행하며, 이는 *rip*를 스택에 저장하지 않고 *rcx*에 저장합니다.
<img src="https://assets.kitploit.com/production/public/readmes/5614/d216fa5b7b656bb52587027db28f3e3902fa8389d0b2944a1f7e870d6d2e6bee.jpg" float="left">
따라서 eBPF에서 스택의 주소가 올바른 GOT으로 이끄는 리턴 주소인지 확인하려면, 그것이 eBPF에서 후킹한 시스템 콜을 수행하는 glibc 함수로 점프하는 GOT 주소를 사용하는 PLT 스텁의 리턴 주소인지 확인해야 합니다.
리턴 주소를 찾기 위한 두 가지 기술이 통합되었습니다:
* sys_timerfd_settime을 사용하는 경우, eBPF 프로그램은 시스템 콜 인자를 사용하여 스캔을 앞으로 진행합니다.
* sys_openat을 사용하는 경우, eBPF 프로그램은 트레이스포인트의 *pt_regs* 구조체의 데이터를 사용하여 리턴 주소를 스캔합니다.
<img src="https://assets.kitploit.com/production/public/readmes/5614/61217fb3fd84bec65cbbee906dd27860e5e1c211912cfe450ea4cf9051fa480b.png" float="left">
#### 셸코드의 주요 함수 위치 찾기
셸코드는 프로그램 실행 시마다 dlopen()과 같은 함수의 주소를 변경하는 ASLR 및 PIE를 우회하기 위해 동적으로 생성되어야 합니다.
<img src="https://assets.kitploit.com/production/public/readmes/5614/6cbb620495d8cb9711e499fd5b1ae9ea845c03d0c33019cf008b456a95d5ddd6.png" float="left">
#### 코드 케이브에 셸코드 인젝션
ASLR 및 PIE가 꺼져 있으면 역공학을 통해 ELF에서 코드 케이브를 찾을 수 있지만, 일반적으로 그렇지 않습니다. eBPF 프로그램은 /proc 파일 시스템을 사용하여 .text (실행 가능) 섹션의 코드 케이브를 찾고 쓰기 위해 사용자 공간 루트킷 프로그램에 요청을 보냅니다.