Information Gathering
Rustscan
Rustscan finds HTTP, WInRM, and port 8080 http open:
Enumeration
HTTP - TCP 80
The website shows a page running on IIS 10.0:
Underlined automation leads me to http://object.htb:8080, which I add to /etc/hosts
.
HTTP - TCP 8080
The website shows Jenkins login page:
There’s a feature for creating an account so I will create one as user jadu:
At the bottom right side of the page, Jenkins version is shown: 2.317
/asynchPeople
shows you the list of users and for this case, I only see admin other than user jadu:
Exploitation
Jenkins RCE
Going to /newJob
will allow me to create a new item on Jenkins:
Using Freestyle project, I can inject a script that will run on Windows system by clicking on Execute Windows batch command under Build:
First to confirm that command execution actually works, I will execute simple whoami
command:
Through out some previous trials, I discovered that user jadu has no right to build the created pipeline.
However, using Schedule, I can build the pipeline automatically every one minute as such:
After saving the pipeline, I can see that the command whoami
was successfully executed through Console Output:
Shell as oliver
Firewall
I tried uploading netcat.exe to the system for a reverse shell but there seems to be an error with it. I will check on Firewall setting to see what is the issue:
cmd.exe /c netsh advfirewall show allprofiles
Based on the output, for all three profiles (Domain, Private, and Public), the firewall policy is set to block inbound connections and allow outbound connections. Additionally, logging for both allowed and dropped connections is disabled, and the firewall log file is set with a maximum size of 4096 bytes:
However, if we specify the firewall to Outbound, it shows blocked:
cmd.exe /c powershell.exe -c Get-NetFirewallRule -Action Block -Enabled True -Direction Outbound
This is probably why all my attempts on spawning reverse shell failed.
Retrieve Jenkins Password
Instead of going for Reverse Shell connection, I will try searching for Jenkins Credentials.
Listing \Users\oliver\AppData\local\jenkins\.jenkins\users
shows two interesting directories, one admin and another jadu which is current user:
cmd.exe /c "dir C:\Users\oliver\AppData\local\jenkins\.jenkins\users
Inside admin folder, there is config.xml:
cmd.exe /c "dir C:\Users\oliver\AppData\local\jenkins\.jenkins\users\admin_17207690984073220035
I can view config.xml file but it is hashed with bcrypt algorithm:
cmd.exe /c "type C:\Users\oliver\AppData\local\jenkins\.jenkins\users\admin_17207690984073220035\config.xml"
Cracking Hash
Jenkins-Credentials-Decryptortells me that credentials.xml(or config.xml), master.key and hudson.util.Secret is required for the decryption:
From some enumeration, I discovered paths to required files:
Using the command below, I can retrieve master.key and hudson.util.secret:
Using the python script above, I will decrypt the password hash:
It decrypts and provides me the password for oliver: c1cdfun_d2434
Evil-Winrm
Using the found credentials and Evil-Winrm, now I have a shell connection as oliver:
Privesc: oliver to smith
Oliver is the member of the Domain Users which is very interesting:
net user oliver
I will upload SharpHound.exe through upload SharpHound.exe
command and run it to enumerate the environment. After running SharpHound.exe, zip file is created to be downloaded:
After downloading the zip file, I will get Bloodhound ready:
After drag & dropping the zip file to Bloodhound, I will first mark account oliver as owned:
ForceChangePassword
There is one outbound first degree object control right from oliver to account smith:
The user OLIVER@OBJECT.LOCAL has the capability to change the user SMITH@OBJECT.LOCAL’s password without knowing that user’s current password.
I will first upload PowerView.ps1 to the system and run it
Using the commands below, I can change the password for user smith into Password123!:
Evil-Winrm
Now with the new password, I can sign-in as smith:
sudo evil-winrm -i 10.10.11.132 -u smith -p 'Password123!'
Privesc:smith to maria
GenericWrite Abuse
The user SMITH@OBJECT.LOCAL has generic write access to the user MARIA@OBJECT.LOCAL.
Generic Write access grants you the ability to write to any non-protected attribute on the target object, including “members” for a group, and “serviceprincipalnames” for a user
To abuse GenericWrite, we have 2 options. One, we can set a service principal name and we can kerberoast that account. Two, we can set objects like logon script which would get executed on the next time account logs in.
Method 1: Targeted Kerberoasting
An SPN is a unique identifier for a service running on a server within a Windows domain. It usually takes the form of service/hostname, where “service” represents the service type (e.g., HTTP, MSSQL) and “hostname” is the hostname of the server where the service runs.
By modifying the SPN of a user account to include a service that the attacker controls (e.g., an HTTP service running on a rogue server), the attacker can trick the KDC into issuing a TGT encrypted with the user’s password hash when someone requests a Kerberos ticket for the malicious SPN.
I will upload PowerView.ps1 once more:
I will import it using Import-Module .\PowerView.ps1
I can query information regarding user maria:
Get-DomainObject -Identity maria
I will first test if I can change the SPN for account maria using the commands below:
I can confirm that SPN for user maria has just changed to the value what I set.
In order for the Kerberoasting to work, I need valid SPN name instead of something like nonexistent/jadu.
This time, instead of using Set-DomainObject, I will use setspn to set the SPN for user maria:
setspn -a MSSQLSvc/object.local:1433 object.local\maria
I can confirm new SPN with the following command:
Get-DomainUser maria | Select serviceprincipalname
PowerView has Get-DomainSPNTicket to Kerberoast, but it actually requires a credential object (even though I am logged in as smith):
Get-DomainSPNTicket -SPN "MSSQLSvc/object.local:1433"
The error message is about the credentials being invalid. I’ll create a credential object:
Above provides hash for account maria but it is not crackable:
Alternatively, I can also use rubeus.exe for kerberoasting as such:
Method 2: logon script
In Active Directory, a logon script is a batch file or script that is executed automatically when a user logs into a Windows domain.
The logon script setting is stored as an attribute of user objects in Active Directory.
An attacker with the GenericWrite permission could modify the logon script setting of a target user account to point to a malicious script hosted on a server under their control.
The attacker could then wait for the targeted user to log in to their domain account. Upon login, the system would execute the modified logon script.
As always, I will first prepare credentials for user smith as such:
Now using the commands below, I can set the logon script to foo.ps1 which will forward result of whoami
to C:\\Windows\\System32\\spool\\drivers\\color\\poc.txt
:
Through net usr maria
, I can see that Logon script is set properly as foo.ps1:
poc.txt confirms that whoami
command was succssfully executed as a Logon script:
Now I will create a script that will list files inside maria’s user directory:
echo 'dir c:\Users\maria\Desktop > c:\\Windows\\System32\\spool\\drivers\\color\\poc.txt' > foo.ps1
Checking on the result, it shows that there is Engines.xls file inside maria’s desktop:
I will copy Engines.xls file over to accessible diretory path to read it:
echo 'copy \users\maria\desktop\Engines.xls c:\\Windows\\System32\\spool\\drivers\\color\\' > foo.ps1
Now I can see that Engines.xls has been copied:
After downloading Engines.xls using download Engines.xls
, I can open it on local Kali machine:
Password Spraying
I will attempt on password spray using three passwords found:
- d34gb8@
- 0de_434_d545
- W3llcr4ft3d_4cls
Crackmapexec discovers one valid password: W3llcr4ft3d_4cls
crackmapexec winrm 10.10.11.132 -u maria -p pass.txt
Now I have evil-winrm shell as user maria:
Privesc: maria to Domain Admis
WriteOwner Abuse
The user MARIA@OBJECT.LOCAL has the ability to modify the owner of the group DOMAIN ADMINS@OBJECT.LOCAL.
Object owners retain the ability to modify object security descriptors, regardless of permissions on the object’s DACL.
I will first create a PSCredential object:
Once again, I will upload PowerView.ps1 using upload PowerView.ps1
and import it using Import-Module .\PowerView.ps1
.
Using Set-DomainObejctOwner, I will set maria as the owner of Domain Admins. After that, I use Add-DomainObjectAcl to grant maria all the rights. Finally I will add maria to Domain Admins:
I can confirm the above process using the command below:
Get-DomainGroupMember -Identity 'Domain Admins'
Accessing evil-winrm again after exit grants me full privilege”