Home Dynstr - HackTheBox
Post
Cancel

Dynstr - HackTheBox

Dynstr, a cool medium-rated linux box that’s all about DNS (as you probably guessed from the name). It features a web service that allows you to update DNS records on the server. One of the parameters in the request used to update DNS records is vulnerable to command injection, which I exploited to gain code execution on the box.

Inside the box www-data, 2 local users were identified (dyna and bindmgr). Some log files generated by the script utility were obtained in the home directory of bindmgr. Going through the log files, I was able to recover an SSH private key for the user bindmgr, but couldn’t get access as the SSH key is mapped to a specific hostname. After bypassing this, I got access to the box as bindmgr over SSH, and exploited a custom script to gain code execution as root.


Info




Recon


NMAP

# Nmap 7.70 scan initiated Tue Oct  5 10:33:02 2021 as: nmap -sC -sV -v -oN namp.txt 10.10.10.244
Increasing send delay for 10.10.10.244 from 0 to 5 due to 14 out of 46 dropped probes since last increase.
Increasing send delay for 10.10.10.244 from 5 to 10 due to 13 out of 43 dropped probes since last increase.
Increasing send delay for 10.10.10.244 from 320 to 640 due to 22 out of 73 dropped probes since last increase.
Nmap scan report for dynstr.htb (10.10.10.244)
Host is up (0.28s latency).
Not shown: 997 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
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-methods: 
|_  Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Dyna DNS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Oct  5 10:35:42 2021 -- 1 IP address (1 host up) scanned in 160.32 seconds

Web

Web technologies detected by Wappalyzer;

Found a credential in the homepage dynadns:sndanyd, and an email address dns@dyna.htb;

Testing the credential on SSH didn’t work, and all of the domains listed above point to the same page.

Running gobuster in vhost enumeration didn’t yield anything. Directory enumeration yield one hit;

The path has no index file nor directory listing. Bruteforcing with ffuf discovered another directory;

It appears to be a special path as it handles requests for non-existing paths/files;

This is strange to me so I decided to do some google-fu, and found this at https://www.dynu.com/en-US/Forum/ViewTopic/badauth-being-received/439;

Turns out the URL is used to assign a domain name to an IP address in the DNS server.

Using the above info, I crafted a request for the page using the credentials I obtained from the homepage for the user dynadns;

Sending the request, I got a new response;

I’m gessing the server is not allowing me to modify the root domain. So with the 3 domains found in the home page of the http://dynstr.htb, I was able to change the DNS records of their subdomains;

I started listeners using netcat in both TCP and UDP modes, but didn’t get any requests. So I setup a wildcard rule *.dnsalias.htb to match all subdomains, which works, but I still didn’t get any callbacks;

After resuming testing the next day, I discovered something weird: DNS updates are returning a different IP in response. The IP included in the request was the IP I was assigned the last time I connected to the HTB VPN, and the IP in the response is my current IP;

Going through my previous notes, I realised I made a mistake; I have been passing the IP to map to domain name using the ip GET parameter, instead of myip. Changing the parameter worked.

Running out of things to do, I started to fuzz the parameters submitted for the DNS update for injection-related vulnerabilities, and was able to get a new response;

A quick check on my debian host showed nsupdate is a command line utility for DNS update;

I suspect the web app is passing the hostname GET parameter without proper validation to a system call to nsupdate. If exploitable, this will give me a foothold into the server.


Foothold


After discovering a possible command injection flaw in the hostname GET parameter passed to http://dynstr.htb/nic/update, I tried to gain code execution by joining commands using linux ;, &&, and || operators. None of them worked. The web app also seems to be checking if the submitted hostname ends with a valid domain, in this case either dnsalias.htb, no-ip.htb, and dynamicdns.htb.

After further testing, I was able to execute code by wrapping it in backtick characters. I got a response after 5 seconds due to the sleep 5 command;

Although the above command worked, multiple simple commands to communicate with my attack host kept failing. Using the ping command for example, I noticed a delay in response that is appropriate with the number of packets sent when pinging localhost. However, attempts to ping my own host returned a response immediately saying; 911 [wrngdom: 10.14.45`www.dnsalias.htb]

This make me suspicious of some kind of filter used by the web app, so I tried to base64-encode the commands. Using the base64 command-line program, I encoded a curl command to my attack host and sent it to the web app. It worked!

I then used the above described method to spawn a bash reverse shell;



User


Inside the box as the default www-data user, I found 2 users named dyna and bindmgr. The home directory of dyna is empty, but that of bindmgr contains some files, including user flag that is not readable to us;

So I downloaded all the files to my attack host for analysis.

The file command-output-C62796521.txt showed the output of a failed public key authentication to an sftp service;

The file strace-C62796521.txt showed the output of strace command. This is interesting because strace is used to trace all system calls made by a program.

The file C62796521-debugging.timing contains some numbers;

While the file C62796521-debugging.script contains terminal logs that are likely generated using the script command;

This is also a very interesting file for me as the console log generated by script is very neat and will be easier to analyse. Going through the file, I noticed multiple outputs of strace. Towards the end of the file, the user bindmgr attempted a public key SSH authentication. Since strace was executed during the authentication, it captured the system call used by the SSH client to load the SSH private key of the user bindmgr from disk;

I extracted the key to id_rsa on my attack host and tried to access the user account of bindmgr, but I got a prompt for password despite passing the private key. Enabling verbose output showed that the public key authentication failed.

I used scriptreplay and gave it the timing file and the typescript to make sense of what the user was actually doing. It showed the user bindmgr attempting to download a file from an SSH server using sFTP;

Looking at the authorized_keys file in bindmgr’s SSH directory, I noticed that access is allowed only to hosts with the name *.infra.dyna.htb;

This means I need to map my IP to match the above hostname. Using the nsupdate utility and the keys inside /etc/bin, I was able to gain SSH access after lots of googling about nsupdate;



PrivEsc


User can run a script as root using sudo;

The script checks for the file .version in the current working directory. If it does not exist, it aborts. If it does, it compares it’s value against the .version file in /etc/bind/named.bindmgr. If the value in the first .version file is higher, it copies the version file and any other file in the working directory to /etc/bind/named.bindmgr;

I noticed the call to cp uses relative path. So I tried to gain root by tampering with the $PATH variable to execute a cp script of my own, which failed;

Since the copy operation is done as root, and all files are included using a wildcard *, I was able to gain root by copying the bash binary and giving it the SUID permission, then have the permission retained after the copy operation by creating a file with the name --preserve=mode, which the cp command will interpret as a special argument;



Summary


  • Found a DNS, SSH, and web service running on the host using nmap
  • Found a credential on the homepage of the web service with username dynadns and password sndanyd
  • Discovered /nic/update by bruteforcing with ffuf and gobuster. Requesting the path showed badauth, but passing the credentials discovered previously gives a nochg <user-IP> response.
  • Some googling showed that /nic/update is used to update DNS records, and takes the parameters hostname, myip, and location. The parameter hostname was found to be vulnerable to command injection through fuzzing after a response mentioning nsupdate, which is a command-line tool for updating DNS records, was returned. Base64-encoding allows for more complex commands to be injected. This was exploited to gain a foothold into the box as the web user www-data.
  • Inside the box as www-data;
    • Two users, binmgr, and dyna, were discovered. The home directory of dyna is practically empty, while that of bindmgr contains the user flag which is not readable, and some interesting files.
    • The files obtained from the home of bindmgr include console logs generated by the linux script utility. The user attempted an SSH public key authentication while running strace, which prints out lots of data on all system calls, which include the contents of the user’s private key as it was read from disk.
    • Attempts to access the account bindmgr using the extracted SSH private key failed. Checking /home/bindmgr/.ssh/authorized_keys showed that access is limited to hosts that match *.infra.dyna.htb. Using the key file at /etc/bind/infra.key and the nsupdate tool, I mapped my IP to hacker.infra.dyna.htb, which satisfied the SSH requirement, and gave me access to the bindmgr account, and the user flag.
  • Inside the box as bindmgr;
    • The user has permission to run /usr/local/bin/bindmgr.sh using sudo.
    • Attempt to hijack the relative call to cp made by the script through path tampering failed.
    • Since a wildcard * was used in the cp command to copy all files, creating a SUID bash binary, and an empty file named --preserve=mode, which will be matched by the wildcard, and be interpreted by the cp command as a special argument used to preserve permissions during copy operations, resulted in the copied binary being created with the ownership changed to root but the SUID bits retained, which gave me root access to the box.
This post is licensed under CC BY 4.0 by the author.
Contents