WordPress相信大家都不陌生,之所以WordPress如此广泛的使用,它的插件机制功不可没,开发简单,松耦合性强,在WordPress运行过程中随时随地可被调用插件中的功能。本文通过UsrPro插件后门漏洞的分析来简单介绍WordPress的插件调用机制。
简介
WordPress的插件机制是通过HOOK:钩子的来实现的。在你的插件里面实现了一大堆的函数接口,通过add_action(“钩子”,”函数”),apply_filter(“钩子”,”函数”)等操作将这些功能通过钩子注册为系统事件,并且保存到全局关联数组里面,当你需要在某处调用这些功能时,通过do_action(‘钩子’)就能调用相应的函数。WordPress默认注册的系统事件保存在/wp-includes/default-filter.php中,有好几百个。
比如我们定义如下钩子事件:
Add_action(“admin_head”,”dosomething”);
接下来事件dosomethings函数就会保存到全局数组$wp_filter中
然后在某一个文件中需要执行这个admin_head事件扩展是:
Do_action(“admin_head”);
此时就会执行前面我们挂载到admin_head这个钩子上的所以函数,比如这里的dosomethins()函数。
下面我们举例一步一步分析。
技术分析
这里通过CVE-2017-16562,UserPro<4.9.17.1登录绕过漏洞为例,使用WordP版本为4.8.2。
WordPress是单入口的,index.php
然后进入wp-blog-header.php
这里加载WordPress的核心库文件和数据还有模板,进入wp-load.php
跟进wp-congif.php
跟进wp-settings.php,在这里WordPress真正的做了很多加载,我们走到加载激活的插件这里:
这里获取系统中已经激活的插件,其实这里就是获取/wp-content/plugins/userpro/目录下的php文件列表,然后包含进来。
比如这userpro插件只有一个index.php入口,跟进
这里首先添加初始化UserPro插件的时间函数userpro_init到系统钩子里面,此时你从全局变量$wp_filter中可以看到userpro_init事件。
接下来注意到functions/api.php文件,跟进
在api.php中添加了大量的事件函数钩子到init中,比如这里的quick_action,这里的数字9是当此事件被调用是的优先级。
加载完插件后,我们继续回到wp-settings.php中
在最后执行了所有的init扩展事件:
至此wp-settings.php已经完成了系统的各个组件内容的加载。
来看看官方对init事件的描述:
https://codex.wordpress.org/Plugin_API/Action_Reference/init
从这个官方的描述中看到,init钩子可以很好的拦截GET和POST请求数据。
所以,前面加载到init钩子里面的所以事件函数都可以在访问系统的时候直接被调用,而且可以直接传入参数到这些事件函数中。
之前我们了解到userpro/functions/api.php中加载很多init钩子,接下来我们看看quick_action这个事件函数:
通过GET获取up_auto_log参数,而且如果参数内容为true时进入userpro_auto_login(“admin”, true)函数,继续跟进次函数:
这里可以直接自动登录!
那么我们试试是不是可以真的登录:
直接在浏览器访问:http://localhost/wordpress-4.8.2/?up_auto_log=true
此时你就回直接登录到管理员账号了!
防护方案
升级插件到最新版本4.9.17.1