Self-VM DevOops靶机复盘
难度-Easy
Self-VM DevOops靶机复盘
网段扫描
1
2
3
4
5
6
7
8
9
root@LingMj:~/xxoo/jarjar# arp-scan -l
Interface: eth0, type: EN10MB, MAC: 00:0c:29:d1:27:55, IPv4: 192.168.137.190
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.137.1 3e:21:9c:12:bd:a3 (Unknown: locally administered)
192.168.137.135 a0:78:17:62:e5:0a Apple, Inc.
192.168.137.154 3e:21:9c:12:bd:a3 (Unknown: locally administered)
4 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.10.0: 256 hosts scanned in 2.020 seconds (126.73 hosts/sec). 3 responded
端口扫描
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
root@LingMj:~/xxoo/jarjar# nmap -p- -sV -sC 192.168.137.154
Starting Nmap 7.95 ( https://nmap.org ) at 2025-04-27 21:21 EDT
Nmap scan report for devoops.hmv.mshome.net (192.168.137.154)
Host is up (0.011s latency).
Not shown: 65534 closed tcp ports (reset)
PORT STATE SERVICE VERSION
3000/tcp open ppp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, Kerberos, NCP, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie, X11Probe:
| HTTP/1.1 400 Bad Request
| FourOhFourRequest:
| HTTP/1.1 403 Forbidden
| Vary: Origin
| Content-Type: text/plain
| Date: Mon, 28 Apr 2025 09:21:38 GMT
| Connection: close
| Blocked request. This host (undefined) is not allowed.
| allow this host, add undefined to `server.allowedHosts` in vite.config.js.
| GetRequest:
| HTTP/1.1 403 Forbidden
| Vary: Origin
| Content-Type: text/plain
| Date: Mon, 28 Apr 2025 09:21:37 GMT
| Connection: close
| Blocked request. This host (undefined) is not allowed.
| allow this host, add undefined to `server.allowedHosts` in vite.config.js.
| HTTPOptions, RTSPRequest:
| HTTP/1.1 204 No Content
| Vary: Origin, Access-Control-Request-Headers
| Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
| Content-Length: 0
| Date: Mon, 28 Apr 2025 09:21:37 GMT
|_ Connection: close
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-Port3000-TCP:V=7.95%I=7%D=4/27%Time=680ED824%P=aarch64-unknown-linux-gn
SF:u%r(GetRequest,FE,"HTTP/1\.1\x20403\x20Forbidden\r\nVary:\x20Origin\r\n
SF:Content-Type:\x20text/plain\r\nDate:\x20Mon,\x2028\x20Apr\x202025\x2009
SF::21:37\x20GMT\r\nConnection:\x20close\r\n\r\nBlocked\x20request\.\x20Th
SF:is\x20host\x20\(undefined\)\x20is\x20not\x20allowed\.\nTo\x20allow\x20t
SF:his\x20host,\x20add\x20undefined\x20to\x20`server\.allowedHosts`\x20in\
SF:x20vite\.config\.js\.")%r(Help,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r
SF:\n\r\n")%r(NCP,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(HTTPO
SF:ptions,D2,"HTTP/1\.1\x20204\x20No\x20Content\r\nVary:\x20Origin,\x20Acc
SF:ess-Control-Request-Headers\r\nAccess-Control-Allow-Methods:\x20GET,HEA
SF:D,PUT,PATCH,POST,DELETE\r\nContent-Length:\x200\r\nDate:\x20Mon,\x2028\
SF:x20Apr\x202025\x2009:21:37\x20GMT\r\nConnection:\x20close\r\n\r\n")%r(R
SF:TSPRequest,D2,"HTTP/1\.1\x20204\x20No\x20Content\r\nVary:\x20Origin,\x2
SF:0Access-Control-Request-Headers\r\nAccess-Control-Allow-Methods:\x20GET
SF:,HEAD,PUT,PATCH,POST,DELETE\r\nContent-Length:\x200\r\nDate:\x20Mon,\x2
SF:028\x20Apr\x202025\x2009:21:37\x20GMT\r\nConnection:\x20close\r\n\r\n")
SF:%r(RPCCheck,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(DNSVersi
SF:onBindReqTCP,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(DNSStat
SF:usRequestTCP,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(SSLSess
SF:ionReq,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(TerminalServe
SF:rCookie,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(TLSSessionRe
SF:q,1C,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(Kerberos,1C,"HTTP/
SF:1\.1\x20400\x20Bad\x20Request\r\n\r\n")%r(SMBProgNeg,1C,"HTTP/1\.1\x204
SF:00\x20Bad\x20Request\r\n\r\n")%r(X11Probe,1C,"HTTP/1\.1\x20400\x20Bad\x
SF:20Request\r\n\r\n")%r(FourOhFourRequest,FE,"HTTP/1\.1\x20403\x20Forbidd
SF:en\r\nVary:\x20Origin\r\nContent-Type:\x20text/plain\r\nDate:\x20Mon,\x
SF:2028\x20Apr\x202025\x2009:21:38\x20GMT\r\nConnection:\x20close\r\n\r\nB
SF:locked\x20request\.\x20This\x20host\x20\(undefined\)\x20is\x20not\x20al
SF:lowed\.\nTo\x20allow\x20this\x20host,\x20add\x20undefined\x20to\x20`ser
SF:ver\.allowedHosts`\x20in\x20vite\.config\.js\.");
MAC Address: 3E:21:9C:12:BD:A3 (Unknown)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.39 seconds
获取webshell
这个靶机对我还是很有难度的,哈哈哈
没扫出对应的东西,更新gobuster没用
找一下密码
确实可读任意文件
还能读什么
这个是提示?
太多不好看
浅浅读一下server.js,一个认证,认证✅可以命令执行
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
import express from 'express';
import jwt from 'jsonwebtoken';
import 'dotenv/config'
import { exec } from 'child_process';
import { promisify } from 'util';
const app = express();
const address = 'localhost';
const port = 3001;
const exec_promise = promisify(exec);
const COMMAND_FILTER = process.env.COMMAND_FILTER
? process.env.COMMAND_FILTER.split(',')
.map(cmd => cmd.trim().toLowerCase())
.filter(cmd => cmd !== '')
: [];
app.use(express.json());
function is_safe_command(cmd) {
if (!cmd || typeof cmd !== 'string') {
return false;
}
if (COMMAND_FILTER.length === 0) {
return false;
}
const lower_cmd = cmd.toLowerCase();
for (const forbidden of COMMAND_FILTER) {
const regex = new RegExp(`\\\\b${forbidden.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\b|^${forbidden.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}$`, 'i');
if (regex.test(lower_cmd)) {
return false;
}
}
if (/[;&|]/.test(cmd)) {
return false;
}
if (/[<>]/.test(cmd)) {
return false;
}
if (/[`$()]/.test(cmd)) {
return false;
}
return true;
}
async function execute_command_sync(command) {
try {
const { stdout, stderr } = await exec_promise(command);
if (stderr) {
return { status: false, data: { stdout, stderr } };
}
return { status: true, data: { stdout, stderr } };
} catch (error) {
return { status: true, data: error.message };
}
}
app.get('/', (req, res) => {
return res.json({
'status': 'working',
'data': `listening on http://${address}:${port}`
})
})
app.get('/api/sign', (req, res) => {
return res.json({
'status': 'signed',
'data': jwt.sign({
uid: -1,
role: 'guest',
}, process.env.JWT_SECRET, { expiresIn: '1800s' }),
});
});
app.get('/api/execute', async (req, res) => {
const authorization_header_raw = req.headers['authorization'];
if (!authorization_header_raw || !authorization_header_raw.startsWith('Bearer ')) {
return res.status(401).json({
'status': 'rejected',
'data': 'permission denied'
});
}
const jwt_raw = authorization_header_raw.split(' ')[1];
try {
const payload = jwt.verify(jwt_raw, process.env.JWT_SECRET);
if (payload.role !== 'admin') {
return res.status(403).json({
'status': 'rejected',
'data': 'permission denied'
});
}
} catch (err) {
return res.status(401).json({
'status': 'rejected',
'data': `permission denied`
});
}
const command = req.query.cmd;
const is_command_safe = is_safe_command(command);
if (!is_command_safe) {
return res.status(401).json({
'status': 'rejected',
'data': `this command is unsafe`
});
}
const result = await execute_command_sync(command);
return res.json({
'status': result.status === true ? 'executed' : 'failed',
'data': result.data
})
});
app.listen(port, address, () => {
console.log(`Listening on http://${address}:${port}`)
});
1
2
JWT_SECRET='2942szKG7Ev83aDviugAa6rFpKixZzZz'
COMMAND_FILTER='nc,python,python3,py,py3,bash,sh,ash,|,&,<,>,ls,cat,pwd,head,tail,grep,xxd'
1
jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOi0xLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3NDU4MzQ5NTgsImV4cCI6MTc0NTgzNjc1OH0.FKklJqCYfNPVJFqk43p-715A5T7jVpe0HroQGMua8BA"
伪造一下才行
得处理一下不然不能提权,没ban wget和curl看看能不能用
没成功
奇怪为啥都不成功呢
换nc都ash成功了
完了这个靶机寄了,哈哈哈,搁置一下
提权
userflag:
rootflag:
This post is licensed under CC BY 4.0 by the author.