StopRansomware: Gunra 랜섬웨어 위협 분석
Detection stack
- AIDR
- Alert
- ETL
- Query
요약
Gunra는 데이터 암호화와 유출을 결합한 이중 협박 모델을 따르는 서비스형 랜섬웨어(RaaS) 작동 방식입니다. 위협 행위자들은 전 세계의 중요 인프라, 정부 기관, 그리고 다양한 상업 조직들을 표적으로 삼습니다. 이 랜섬웨어는 유출된 Conti 소스 코드를 기반으로 하며 Windows와 Linux 환경 모두를 지원하도록 발전했습니다.
조사
FBI와 국제 파트너들은 Gunra 행위자들이 인터넷에 노출된 취약점을 악용하고 도난당한 자격 증명을 남용하여 초기 접근을 시도하는 것을 관찰했습니다. 조사 결과 횡적 이동을 위한 Impacket 라이브러리의 사용과 데이터 유출을 위한 다수의 오픈 소스 도구 사용이 확인되었습니다. 이 그룹은 또한 희생자와 소통하기 위해 Tor 기반 협상 포털과 qTox를 사용합니다.
완화
조직은 인터넷에 노출된 시스템, 특히 VPN 게이트웨이 및 RDP 인프라에 대한 알려진 취약점의 패치를 우선시해야 합니다. 불변의 오프라인 백업을 유지하고 엄격한 네트워크 분할을 시행하여 횡적 이동을 제한하는 것이 중요합니다. 모든 원격 액세스 서비스에 다중 인증(MFA)을 활성화해야 합니다.
대응
Gunra 활동이 감지되면, 손상된 호스트는 즉시 격리하고 암호화된 파일과 시스템 로그를 포함한 관련 포렌식 아티팩트를 보존해야 합니다. 위협 사냥을 시작하여 침입의 범위를 파악하고 특권 계정 활동을 검토해야 합니다. 그런 다음 조직은 공식적인 퇴출 절차를 따라 환경에서 적을 완전히 차단하고 제거해야 합니다.
공격 흐름
탐지
Impacket 명령 줄 패턴 가능성 (cmdline 통해)
Proof of Value
Powershell, CMD 또는 WMI를 통한 그림자 복사본 만들기 또는 삭제 (cmdline 통해)
Proof of Value
대체 원격 액세스 / 관리 소프트웨어 (시스템 통해)
Proof of Value
Impacket 실행 행동 가능성 (감사 통해)
Proof of Value
대체 원격 액세스 / 관리 소프트웨어 (감사 통해)
Proof of Value
탐지 가능한 IOC (HashSha256): #StopRansomware: Gunra 랜섬웨어
Proof of Value
탐지 가능한 IOC (SourceIP): #StopRansomware: Gunra 랜섬웨어
Proof of Value
탐지 가능한 IOC (DestinationIP): #StopRansomware: Gunra 랜섬웨어
Proof of Value
Gunra 랜섬웨어 계정 조작 및 권한 상승 탐지 [Microsoft Windows Security Event Log]
Proof of Value
FortiOS 및 FortiProxy의 악용된 취약점 탐지 [방화벽]
Proof of Value
Gunra 랜섬웨어 횡적 이동 및 자격 증명 덤핑 탐지 [Windows 프로세스 생성]
Proof of Value
Gunra 랜섬웨어 파일 시스템 탐색 API 탐지 [Linux 프로세스 생성]
Proof of Value
시뮬레이션 실행
전제 조건: 텔레메트리 및 베이스라인 사전 검사 통과 필수.
근거: 이 섹션은 탐지 규칙을 유발하도록 설계된 적대자 기술(TTP)의 정확한 실행을 설명합니다. 명령 및 설명은 식별된 TTP를 직접 반영하고 탐지 논리에 의해 예상되는 정확한 텔레메트리를 생성해야 합니다. 추상적이거나 관련없는 예제는 오진을 초래할 수 있습니다.
-
공격 내러티브 및 명령: 적이 목표로 하는 것은 랜섬웨어 배포를 준비하는 것입니다. 암호화가 시작되기 전에, 맬웨어는 고가치 파일 목록(문서, 데이터베이스 등)을 작성하기 위해 파일 시스템을 검색해야 합니다. Gunra 랜섬웨어는 특히
FindFirstFileWandFindNextFileWAPI를 사용하여 이 대규모 열거를 수행합니다. 우리는 이 API를 DLL 가져오기 통해 명시적으로 호출하는 작은 C# 코드 조각을 컴파일하고 실행하여 Sysmon이 이 API 사용을ImageLoaded필드에 기록하게 만들 것입니다. -
회귀 테스트 스크립트:
# 이 파일을 TriggerDetection.cs로 저장 using System; using System.Runtime.InteropServices; using System.IO; class Program { static void Main() { // 이는 Gunra 랜섬웨어의 탐색 동작을 시뮬레이션합니다 // 구체적인 API의 로드를 강제함으로써. DirectoryInfo di = new DirectoryInfo(@"C:"); foreach (var file in di.GetFiles()) { // 파일 속성에 접근하면 탐색 API가 트리거됩니다 string name = file.Name; } Console.WriteLine("탐색 완료."); } } # csc.exe( .NET 프레임워크 포함)를 사용하여 컴파일 및 실행 Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WIN32_FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } } "@ # 명시적으로 함수를 호출하는 작은 C# 스크립트를 실행하여 로그에 문자열 존재를 확인합니다 $code = @" using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } static void Main() { FIND_DATA data; IntPtr handle = IntPtr.Zero; // Sysmon ImageLoaded 필드에서 특정 문자열을 트리거합니다 if (FindFirstFileW("C:*", out data)) { Console.WriteLine("FindFirstFileW를 통해 파일 발견"); FindNextFileW(handle, out data); } } } "@ $code | Out-File -FilePath "$env:TEMPTriggerDetection.cs" & csc.exe "$env:TEMPTriggerDetection.cs" & "$env:TEMPTriggerDetection.exe" -
정리 명령:
Remove-Item "$env:TEMPTriggerDetection.cs" -ErrorAction SilentlyContinue Remove-Item "$env:TEMPTriggerDetection.exe" -ErrorAction SilentlyContinue