GraphStrike

릴리스 블로그: GraphStrike: Microsoft Graph API를 사용하여 비콘 트래픽 사라지게 만들기
개발자 블로그: GraphStrike: 공격적 도구 개발의 해부
소개
GraphStrike는 Cobalt Strike의 HTTPS 비콘이 C2 통신에 Microsoft Graph API를 사용할 수 있게 해주는 도구 모음입니다. 모든 비콘 트래픽은 공격자의 SharePoint 사이트에 생성된 두 개의 파일을 통해 전송되며, 비콘의 모든 통신은 https://graph.microsoft.com으로 라우팅됩니다:

GraphStrike에는 Graph API를 통한 Cobalt Strike HTTPS에 필요한 Azure 자산을 생성하는 프로비저너가 포함되어 있습니다:

GraphStrike는 Azure에서 유료 자산을 생성하지 않으므로 GraphStrike 또는 해당 프로비저너 사용으로 인한 추가 비용이 발생하지 않습니다.
이유?
여러 APT 그룹이 공격 캠페인에 Microsoft Graph API 및 기타 Microsoft 서비스를 활용하는 것에 대한 위협 인텔리전스가 공개되었습니다:
- BLUELIGHT - APT37/InkySquid/ScarCruft
- Graphite - APT28/Fancy Bear
- Graphican - APT15/Nickel/The Flea
- SiestaGraph - 알 수 없음
위협 행위자들은 계속해서 합법적인 서비스를 불법적인 목적으로 활용하고 있습니다. graph.microsoft.com과 같은 평판이 높은 도메인을 C2 통신에 사용하는 것은 매우 효과적이고 바람직하지만, 종종 복잡하고 시간과 노력 면에서 부담스럽습니다. 대부분의 C2 프레임워크는 액세스 토큰을 가져오거나 교체하는 방법을 지원하지 않아 Graph API를 사용할 수 없습니다. 이로 인해 레드 팀이 이러한 기술을 재현하기 어려워지고, 방어자가 이러한 활동을 관찰하고 시그니처를 개발할 기회를 잃게 됩니다. GraphStrike는 이러한 부담을 줄이고 Cobalt Strike 사용자 경험의 친숙함과 신뢰성을 유지하면서 Microsoft Graph API를 활용할 수 있는 신뢰할 수 있고 반복 가능한 프로세스를 제공하고자 합니다.
이것은 External C2인가요?
기술적으로는 아닙니다. 이전에 진정한 Graph API를 사용한 External C2 (비콘 트래픽을 Microsoft Teams 메시지로 전송)를 구축한 경험으로, External C2 사양을 충족하고 작업을 완료하는 맞춤형 임플란트를 개발, 유지 및 통합해야 하는 부담은 너무나 익숙합니다. GraphStrike는 대신 Kyle Avery가 개발한 오픈 소스 사용자 정의 반사 로더(UDRL)인 AceLdr를 활용합니다 (이 프로젝트에서는 'GraphLdr'로 수정됨). 이 로더는 비콘이 일반적으로 호출하는 WinINet 라이브러리 호출을 후킹하고 Graph API를 사용하기 위해 필요에 따라 조작합니다. 맞춤형 임플란트나 추가 프로세스는 없으며, 몇 가지 후킹된 Windows API가 있는 비콘 프로세스만 있습니다. 서버 측에는 Cobalt Strike 팀 서버 트래픽을 Graph API 트래픽으로 변환하고 그 반대로 변환하는 Python3 프로그램이 있습니다.
기능
GraphStrike는 거의 모든 일반적인 Cobalt Strike 활동을 지원합니다:
- Cobalt Strike SOCKS 프록시를 통한 프록시체인 사용 (매우 느리지만...)
- 대용량 파일 업로드/다운로드
- BOF, execute-assembly 등
또한 sleep, exit, remove 명령어의 GraphStrike 통합을 포함하여 GraphStrike 서버의 수면 시간을 비콘과 일치시키고, 비콘이 종료되거나 제거될 때 SharePoint의 파일을 삭제합니다.
GraphStrike는 또한 원래 AceLdr의 모든 기능과 기능을 통합하며, 콜 스택 스푸핑을 활용하기 위한 추가 API도 포함합니다.
요구 사항
GraphStrike를 시작하기 전에 다음이 필요합니다:
- SharePoint/O365 라이선스가 할당되고 사이트가 생성된 Microsoft Azure 테넌트. 기본 사이트면 충분합니다.
- 해당 테넌트에서 전역 관리자 권한이 있는 Azure 계정.
- Python 3.8-3.11참고 #4 (설치 과정에서 설치될 추가 종속성 포함)
방화벽 규칙
- Cobalt Strike 클라이언트가 실행되는 각 머신이 Cobalt Strike 팀 서버 머신의 포트 443 및 5000에 연결할 수 있는지 확인하십시오.
설정
설정 과정을 진행하기 전에 다음 사항을 숙지하십시오:
1. 일부 구성 요소는 다른 자산을 찾기 위해 상대 경로를 사용합니다. 아래 설명된 대로 디렉토리를 변경하십시오.
2. Cobalt Strike 프로필은 아래 설정 과정의 5단계 이전에만 편집할 수 있습니다참고 #1.
Cobalt Strike 팀 서버를 실행할 머신에서:
- 저장소를 클론합니다.
- 저장소 디렉토리에서
sudo setup/install_dependencies.sh를 실행하여 필요한 시스템 종속성을 설치합니다.
python3 -m venv virtual를 실행한 후 source virtual/bin/activate를 실행하여 가상 환경을 생성하고 활성화합니다.
- setup 디렉토리로 변경한 후
pip3 install -r requirements.txt를 실행합니다.
./provisioner.py new를 실행하고 설정 과정을 완료합니다.
- graphstrike.profile을 malleable C2 프로필로 사용하여 Cobalt Strike 팀 서버를 시작합니다.
- Cobalt Strike 클라이언트 인스턴스를 시작하고 (클라이언트 머신에서 수행하거나 TS 박스에서 수행한 후 종료 가능) HTTPS 호스트 및 HTTPS 호스트(스테이저) 필드에
graph.microsoft.com을 사용하여 포트 443에서 Cobalt Strike HTTPS 리스너를 생성합니다.
- 기본 저장소 디렉토리로 돌아가서
./GraphStrike.py를 사용하여 GraphStrike 서버를 실행합니다.
Cobalt Strike 클라이언트를 실행할 모든 머신에서:
- TS 머신에서 GraphStrike/client 디렉토리를 클라이언트 머신으로 복사합니다. 이는 프로비저닝을 완료한 후에만 수행해야 합니다!
- 스크립트 관리자를 사용하여 GraphStrike.cna를 Cobalt Strike에 가져옵니다.
- 원시 셸코드든 아티팩트 키트 또는 대체 페이로드 생성 프레임워크를 사용하여 컴파일된 아티팩트든 Cobalt Strike 페이로드를 생성합니다. 아티팩트 키트 사용자는 아래를 참조하십시오!
- 수익을 창출하십시오.
아티팩트 키트 사용자
GraphLdr의 크기로 인해 아티팩트 키트 사용자는 GraphStrike가 아티팩트 키트로 생성된 페이로드와 호환되도록 하려면 특정 옵션으로 다시 컴파일해야 합니다. 특히 'Stage Size' 및 'RDLL Size' 필드를 100K RDLL 크기를 사용하도록 지정해야 합니다. 작동하는 두 가지 예시 구문은 아래에 제공됩니다:
./build.sh pipe VirtualAlloc 505029 100 false false none /opt/cobaltstrike/artifacts
./build.sh peek HeapAlloc 492376 100 false true indirect /opt/cobaltstrike/artifacts
정리
TS + GraphStrike 서버를 실행하는 머신에서:
- GraphStrike 서버를 중지합니다.
- setup 디렉토리로 돌아가서
./provisioner.py delete를 실행하여 생성된 Azure 자산을 제거합니다.
참고 사항
특별한 순서 없이 GraphStrike를 최대한 활용하는 데 도움이 될 몇 가지 제안 및 관찰 사항입니다.
- GraphStrike에 포함된 프로필은 매우 최소화되어 있습니다. 이는 의도적인 설계입니다. 프로필의 기존 필드를 변경하면 GraphStrike가 손상될 수 있습니다! 이미 정의되지 않은 다른 섹션에 추가 프로필 언어/동작을 추가할 수 있습니다 (예: 파이프 이름 사용자 정의, 인젝션 동작 등). 프로필에 대한 모든 편집은 프로비저너를 실행하기 전에 이루어져야 합니다!
- 비콘과 GraphStrike 서버 모두에서 C2 통신에 사용되는 Azure 애플리케이션은 1200 요청/분으로 제한됩니다. GraphStrike 서버는 기준으로 120/분을 사용합니다. 비콘의 수면 시간이 낮을수록 더 많은 요청을 보냅니다. 또한 GraphStrike를 사용하여 생성된 각 비콘은 해당 1200/분 제한의 일부를 사용합니다. 비콘과 대화형 작업을 수행하는 것은 가능하지만, 여러 비콘과 동시에 대화형 작업을 수행하는 것은 어려울 수 있습니다. 속도 제한 문제가 발생하면 비콘의 수면 시간을 늘리거나 실행 중인 비콘 수를 줄이거나 둘 다 고려하십시오.
- GraphStrike 서버의 수면 시간은 발행된 sleep 명령에 따라 비콘별로 변경되지만, 이는 GraphStrike 서버가 TS에 작업을 요청하기 전에 지정된 시간 동안 대기한다는 것을 의미합니다. 비콘이 GraphStrike 서버에 의해 TS에서 작업을 검색하는 즉시 수신하여 처리한다는 의미는 아닙니다. 비콘은 TS 작업을 검색하기 위해 SharePoint에 연결하기 전에 지정된 시간 동안 대기하지만, 비동기 C2의 특성상 이는 GraphStrike 서버가 업로드하는 시점과 동기화되지 않습니다.
- 비콘이 정상적으로 종료되지 않고 사망한 경우 (AV, 충돌 등), 비콘은 여전히 TS에 호출하는 것처럼 보일 수 있으며, 명령을 내릴 때까지 사망한 사실이 드러나지 않습니다. 실제로 TS에 연결하여 비콘이 여전히 호출 중인 것처럼 보이게 하는 것은 GraphStrike 서버이므로 이는 비콘의 상태를 반영하지 않습니다. 이는 비동기 C2의 특성입니다.
- GraphStrike는 1:1:1 모델로 작동합니다. 하나의 SharePoint 사이트는 하나의 GraphStrike 서버와 연결되며, 이는 하나의 TS와 연결됩니다. 두 개의 TS/GraphStrike 서버를 단일 SharePoint 사이트에 연결하려고 하면 문제가 발생합니다. 여러 Cobalt Strike 클라이언트를 단일 TS/GraphStrike 서버에 연결할 수 있으며, 각 클라이언트는 프로비저닝 과정에서 생성된 'client' 폴더의 복사본만 있으면 됩니다.
- GraphStrike에서 사용하는 az 유틸리티와 Python 3.12 간의 호환성과 관련된 알려진 문제가 있습니다.
- AceLdr에 대한 문서를 검토하는 것을 권장합니다. 해당 프로젝트의 모든 참고 사항이 여기에도 적용됩니다.
제한 사항
GraphStrike에는 다음과 같은 제한 사항이 있습니다:
- x64 비콘만 지원됩니다.
- 스테이징된 비콘은 지원되지 않습니다.
- GraphStrike는 WinINet 라이브러리와만 호환됩니다. 비콘의 새로운 WinHTTP 라이브러리 옵션은 지원되지 않습니다.
- 비콘의 오른쪽 클릭 메뉴를 통한 sleep 명령 지원이 없습니다. 대신 명령줄 옵션을 사용하여 비콘을 절전 모드로 전환하십시오.
- GraphStrike는 Linux Cobalt Strike 인스턴스에서만 지원됩니다. Windows 지원도 확실히 구현 가능하며, Python 파일 및 Aggressor 스크립트 내에서 일부 경로를 변경하는 문제일 뿐입니다.
크레딧
GraphStrike는 다음 개인들의 기여 없이는 불가능했을 것입니다:
- AceLdr를 제공한 Kyle Avery
- cs-decrypt-metadata.py를 제공한 Didier Stevens
- GraphStrike를 베타 테스트하고 출시 전에 여러 문제를 식별하고 수정하는 데 도움을 준 Red Siege 팀의 Mike Saunders, Corey Overstreet, Chris Truncer, Justin Palk