악성코드 분석일지 - Info_Stealer

2022. 3. 16. 22:01보안 연구/Reversing

반응형

본 티스토리 블로그는 PC 환경에 최적화되어 있습니다.

모바일 유저분들은 아래 티스토리 블로그를 이용해 주세요.

 

 

악성코드 분석일지 - Info_Stealer

본 네이버 블로그는 모바일 환경에 최적화되어 있습니다. PC 유저분들은 아래 티스토리 블로그를 이용해 ...

blog.naver.com

 

 

안녕하세요, ICMP입니다.

 

이번에 분석할 악성코드는 정보 탈취에 특화된 RedLine Stealer이며, 단순히 정보 탈취를 넘어서 유출된 정보를 딥웹에 판매하는 정황도 포착되어 상당히 무서운 녀석입니다.

 

정보 수집되는 항목도 상당히 많고 원격 명령 실행을 위한 기능도 탑재하고 있기 때문에 상당히 위력적이라고 할 수 있습니다.

 

그럼 부검을 진행해 보도록 하겠습니다.

 

 

 

1. 파일 정보

일단 겉보기에는 아무런 문제가 없는 것처럼 보이지만 IDA와 같은 디컴파일러에 넣으면 인자들이 모두 깨져서 나오는 것을 알 수 있습니다.

거의 이런 경우는 패킹 같은 기법이 걸려 있다고 봐야 합니다.

 

현재 패킹 시그니처를 확인하지 못했으므로 일단 실행 중 압축을 해제해야 합니다.

다행히도 온라인으로 실행 압축을 해제해 주는 사이트가 존재해서 해당 기능의 도움을 받았습니다.

 

 

https://www.unpac.me/

 

www.unpac.me

 

 

해당 사이트에 들어가서 가입을 진행한 뒤 패킹이 걸려있는 악성코드를 올려주고 압축이 풀릴 때까지 기다린 뒤 결과물을 확인해 보면 다음과 같습니다.

총 네 개의 결과물을 확인할 수 있군요.

샌드박스에 올려 동작을 확인해 보면 외부 통신을 진행한다고 합니다.

 

 

 

 

자, 이제 사전 정보를 어느 정도 모았습니다!

나를 알고 적을 알면 백전백승!!! 한번 코드를 분석해 보도록 하겠습니다.

 

 

 

2. 정적 분석

일단 실행 압축이 해제된 방식이기에 일부 링크가 깨져서 동적 분석은 불가능한 것으로 보입니다.

다행히도 내부 문자열들이 모두 평문 상태로 확인이 가능하기에 바로 보도록 하겠습니다.

 

EntryPoint() 내부는 암호화된 정보들이 클래스로 저장되어 있으며, Execute() 함수 호출 부분의 바디를 보면 이들을 끌어와서 복호화 하는 과정이 존재합니다.

간단하게 입력된 데이터를 base64로 디코딩하고 key와 xor 한 뒤 이 결괏값을 다시 base64로 디코딩 합니다.

아래는 파이썬으로 작성된 코드입니다.

 

봇넷의 아이디는 PUB, 접속 ip는 45.9.20.20, 포트 넘버는 13441임을 알 수 있으며 이는 샌드박스의 결과와 일치함을 알 수 있습니다.

 

이어서 계속 분석을 진행해 보면, 해당 try 코드가 끝나면 아래와 같이 해당 IP 접속 주소를 가반으로 연결을 진행합니다.

 

 

직후에 호출되는 코드를 이어서 확인하면 다음과 같습니다.

 

 

어떤 클래스를 호출한 뒤 어떤 주소로 또다시 connection을 시도하는 것으로 보이나, 정확한 동작을 확인하기 위해 내부 코드들을 확인해 보도록 하겠습니다.

 

1) ScanningArgs

간단하게 감염 PC의 가상화폐 지갑 정보, ftp, web 브라우저 정보를 저장할 수 있는 클래스인 듯 합니다.

아래는 ScanningArgs의 멤버 목록을 정리한 내용입니다.

 

public class ScanningArgs
{
	public bool ScanBrowsers { get; set; }
	public bool ScanFiles { get; set; }
	public bool ScanFTP { get; set; }
	public bool ScanWallets { get; set; }
	public bool ScanScreen { get; set; }
	public bool ScanTelegram { get; set; }
	public bool ScanVPN { get; set; }
	public bool ScanSteam { get; set; }
	public bool ScanDiscord { get; set; }
	public List<string> ScanFilesPaths { get; set; }
	public List<string> BlockedCountry { get; set; }
	public List<string> BlockedIP { get; set; }
	public List<string> ScanChromeBrowsersPaths { get; set; }
	public List<string> ScanGeckoBrowsersPaths { get; set; }
}

 

 

 

2) TryGetArgs()

 

WCF라 하여 클라이언트와 서버 간의 통신을 간편화해 주는 기능 일부를 활용한 것으로 보입니다.

정확히는 좀 더 공부가 필요하지만, 정보 탈취 가능 항목을 뽑아내기 위해 해당 함수를 호출하는 것으로, 공격 대상의 브라우저 경로나 차단 국가 리스트와 같은 종합 정보를 수집하는 것을 확인할 수 있습니다.

 

아래는 IRemoteEndpoint 클래스 내부 정보입니다.

public interface IRemoteEndpoint
{
	bool CheckConnect();
	ScanningArgs GetArguments();
	void VerifyScanRequest(ScanResult user);
	ApiResponse Init(ScanResult user);
	ApiResponse InitDisplay(byte] display);
	ApiResponse PartDefenders(List<string> defenders);
	ApiResponse PartLanguages(List<string> languages);
	ApiResponse PartInstalledSoftwares(List<string> softwares);
	ApiResponse PartProcesses(List<string> processes);
	ApiResponse PartHardwares(List<SystemHardware> hardwares);
	ApiResponse PartBrowsers(List<Browser> browsers);
	ApiResponse PartFtpConnections(List<Account> ftps);
	ApiResponse PartInstalledBrowsers(List<BrowserVersion> installedBrowsers);
	ApiResponse PartScannedFiles(List<ScannedFile> remoteFiles);
	ApiResponse PartColdWallets(List<ScannedFile> remoteFiles);
	ApiResponse PartSteamFiles(List<ScannedFile> remoteFiles);
	ApiResponse PartNordVPN(List<Account> loginPairs);
	ApiResponse PartOpenVPN(List<ScannedFile> remoteFiles);
	ApiResponse PartProtonVPN(List<ScannedFile> remoteFiles);
	ApiResponse PartTelegramFiles(List<ScannedFile> remoteFiles);
	ApiResponse PartDiscord(List<ScannedFile> remoteFiles);
	void Confirm();
	IList<UpdateTask> GetUpdates(ScanResult user);
	void VerifyUpdate(ScanResult user, int updateId);
}

 

ScanResult 클래스 멤버인 ReleaseID에 아까 복호화 된 ‘PUB’ 값을 넣고 감염 단말기의 공격 가능 옵션 정보(settings)와 45.9.20.20:13441 연결정보, ScanResult 클래스 변수를 인자로 Send 함수를 호출합니다.

 

 

우선 데이터를 send 하기 전에 정보를 탈취하는 과정이 분명히 있을 것이며, send 메서드가 호출되기 직전인 create 메서드를 확인해 보겠습니다.

 

 

내부 클래스를 확인해 보면 다음과 같이 정보 수집 코드가 존재하는 것을 볼 수 있습니다.

(한 가지 예로, asdk9345asd는 감염 PC의 프로세서, 그래픽 카드, 전체 RAM 정보를 리스트 멤버에 저장합니다.)

 

즉, ByPartSender, ScanningArgs, ScanResult 클래스 정보를 공격자에게 전송합니다.

참고로, ScanResult 클래스 구조는 아래와 같습니다.

public struct ScanResult
{
	public string Hardware { get; set; }
	public string ReleaseID { get; set; }
	public string MachineName { get; set; }
	public string OSVersion { get; set; }
	public string Language { get; set; }
	public string Resolution { get; set; }
	public ScanDetails ScanDetails { get; set; }
	public string Country { get; set; }
	public string City { get; set; }
	public string TZ { get; set; }
	public string IPv4 { get; set; }
	public byte] Monitor { get; set; }
	public string ZipCode { get; set; }
	public string FileLocation { get; set; }
	public bool SeenBefore { get; set; }
}
 
public class ScanDetails
{
	public List<string> SecurityUtils { get; set; } = new List<string>();
	public List<string> AvailableLanguages { get; set; } = new List<string>();
	public List<string> Softwares { get; set; } = new List<string>();
	public List<string> Processes { get; set; } = new List<string>();
	public List<SystemHardware> SystemHardwares { get; set; } = new List<SystemHardware>();
	public List<Browser> Browsers { get; set; } = new List<Browser>();
	public List<Account> FtpConnections { get; set; } = new List<Account>();
	public List<BrowserVersion> InstalledBrowsers { get; set; } = new List<BrowserVersion>();
	public List<ScannedFile> ScannedFiles { get; set; } = new List<ScannedFile>();
	public List<ScannedFile> GameLauncherFiles { get; set; } = new List<ScannedFile>();
	public List<ScannedFile> ScannedWallets { get; set; } = new List<ScannedFile>();
	public List<Account> NordAccounts { get; set; }
	public List<ScannedFile> Open { get; set; }
	public List<ScannedFile> Proton { get; set; }
	public List<ScannedFile> MessageClientFiles { get; set; }
	public List<ScannedFile> GameChatFiles { get; set; }
}

 

상당히 많은 클래스 멤버가 보이며, 탈취 정보가 상당히 많은 것을 알 수 있으며, 조금 더 대담하게 업데이트할 수 있는 코드가 존재했습니다.

(정확히는 원격 명령어 실행 기능이 탑재되어 있었습니다..)

해당 클래스들은 cmd 기능을 활용해 업데이트를 확인하고 프로그램의 업데이트를 진행하기 위한 메서드들이 저장되어 있습니다.

 

통신 시도를 위한 연결 IP와 봇 ID는 Snort와 같은 IPS에서 블랙리스트에 추가하면 될 것이고 우리는 호스트 기반 YARA 규칙으로 해당 악성코드를 사전에 탐지 및 검역소 이동을 진행해야 합니다.

 

아래는 해당 악성코드를 탐지해 내기 위한 규칙을 작성했습니다.

rule RedLine : INFO_stealer
{
	meta:
		description = "이 룰은 패킹된 원본 파일을 탐지하기 위한 규칙이 아닙니다. 이건 단순한 테스트입니다."
		
	strings:
		// PE 파일의 시그니처 MZ
		$MZ = {4D 5A}
		$s2 = "IRemoteEndpoint"
		
		// dotnet dll 
		$DOT_net = "mscorlib"
		
		// ScanningArgs
		$s3 = "zScanningArgs"
		$s4 = "ScanBrowsers"
		$s5 = "ScanFiles"
		$s6 = "ScanFTP"
		$s7 = "ScanWallets"
		$s8 = "ScanScreen"
		$s9 = "ScanTelegram"
		$s10 = "ScanVPN"
		$s11 = "ScanSteam"
		$s12 = "ScanDiscord"
		$s13 = "ScanFilesPaths"
		$s14 = "BlockedCountry"
		$s15 = "BlockedIP"
		$s16 = "ScanChromeBrowsersPaths"
		$s17 = "ScanGeckoBrowsersPaths"
		
	condition:
		(($MZ at 0) and $DOT_net) and (all of &s*)
}
 

디테일한 부분이 많이 생략되어 있어서 아쉬운 규칙입니다.

패킹된 파일도 같이 사용할 수 있는 규칙을 만들 수 있도록 실력을 더 키워야겠습니다.

 

 

3. 결론

이번 악성코드는 상당히 내부 탑재된 악성 기능들이 많았으며, 공격자는 고 수준의 패킹 기법을 통한 백신 우회를 진행했습니다.

특히 실제 유출된 데이터들을 다크 웹에서 거래되는 현장을 보고 상당히 충격이었습니다...

과연 제 실력으로 방어 해낼 수 있을는지...

 

요약 : 분발합시다!!!

 

반응형