大川渝读者博客
立即登录 马上注册
当前位置: WEB技术 > WordPress防止暴力破解网站管理员密码

WordPress防止暴力破解网站管理员账号密码方法

一、author页面地址

author页面地址为 http://yoursite/?author=1 ID是自增的
请求这个地址会 301 到一个url,这个url里包含了作者的用户名。虽然不算漏洞,还是给了爆破者很大的便利。

301指向的url :  .../author/你的后台登录用户名

解决方案

1.在主题代码里实现,只要访问主页url后头有author参数就让他跳到主页

将下面的代码添加到当前主题的  functions.php  文件:

  1. function my_author_link() {
  2. return home_url('/' );
  3. }
  4. add_filter('author_link','my_author_link');
2.通过.htaccess文件添加301重定向来隐藏后台用户名

在 .htaccess 文件里加入

  1. redirect 301 /(这里还有path的请自行添加)/author/你的后台登录用户名/ http://yoursite/

上面这段代码意思为:
将 http://yoursite/.../author/你的后台登录用户名/
跳转至

http://yoursite/
当我们输入http://yoursite/?author=1 时会先跳转至http://yoursite/.../author/你的后台登录用户名/,所以将跳转后的链接做301重定向即可。
此方法也可以在你的web服务器配置文件中实现

二.xmlrpc.php

xmlrpc 是 WordPress 中进行远程调用的接口,而使用 xmlrpc 调用接口进行账号爆破在很早之前就被提出并加以利用。xmlrpc登录接口默认没有验证码,最大错误尝试次数限制等。利用xmlrpc.php提供的接口尝试猜解用户的密码,可以绕过wordpress对暴力破解的限制。

1.攻击方式

攻击的方式直接POST以下数据到xmlrpc.php

  1. <?xml version="1.0" encoding="iso-8859-1"?>
  2. <methodCall> <methodName>wp.getUsersBlogs</methodName> <params> <param><value>username</value></param> <param><value>password</value></param> </params>
  3. </methodCall>

其中username字段是预先收集的用户名。password是尝试的密码。关于getUsersBlogs接口的更多信息可以参考官方的指南  。如果密码正确,返回为:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <methodResponse>
  3. <params>
  4. <param>
  5. <value>
  6. <array>
  7. <data>
  8. <value>
  9. <struct>
  10. <member>
  11. <name>isAdmin</name>
  12. <value>
  13. <boolean>1</boolean>
  14. </value>
  15. </member>
  16. <member>
  17. <name>url</name>
  18. <value>
  19. <string>http://yoursite/</string>
  20. </value>
  21. </member>
  22. <member>
  23. <name>siteid</name>
  24. <value>
  25. <string>1</string>
  26. </value>
  27. </member>
  28. <member>
  29. <name>SiteName</name>
  30. <value>
  31. <string>Your Site</string>
  32. </value>
  33. </member>
  34. <member>
  35. <name>xmlrpc</name>
  36. <value>
  37. <string>http://yoursite/xmlrpc.php</string>
  38. </value>
  39. </member>
  40. </struct>
  41. </value>
  42. </data>
  43. </array>
  44. </value>
  45. </param>
  46. </params>
  47. </methodResponse>

错误返回:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <methodResponse>
  3. <fault>
  4. <value>
  5. <struct>
  6. <member>
  7. <name>faultCode</name>
  8. <value>
  9. <int>403</int>
  10. </value>
  11. </member>
  12. <member>
  13. <name>faultString</name>
  14. <value>
  15. <string>用户名或密码不正确。</string>
  16. </value>
  17. </member>
  18. </struct>
  19. </value>
  20. </fault>
  21. </methodResponse>

近日 SUCURI 发布文章介绍了如何利用 xmlrpc 调用接口中的 system.multicall 来提高爆破效率,使得成千上万次的帐号密码组合尝试能在一次请求完成,极大的压缩请求次数,在一定程度上能够躲避日志的检测。

2.原理分析

WordPress 中关于 xmlrpc 服务的定义代码主要位于 wp-includes/class-IXR.php 和 wp-includes/class-wp-xmlrpc-server.php 中。基类 IXR_Server 中定义了三个内置的调用方法,分别为 system.getCapabilities,system.listMethods 和 system.multicall,其调用映射位于 IXR_Server 基类定义中:

  1. <?php
  2. function setCallbacks()
  3. {
  4. $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
  5. $this->callbacks['system.listMethods'] = 'this:listMethods';
  6. $this->callbacks['system.multicall'] = 'this:multiCall';
  7. }

而基类在初始化时,调用  setCallbacks()  绑定了调用映射关系:

  1. <?php
  2. function __construct( $callbacks = false, $data = false, $wait = false )
  3. {
  4. $this->setCapabilities();
  5. if ($callbacks) {
  6. $this->callbacks = $callbacks;
  7. }
  8. $this->setCallbacks(); // 绑定默认的三个基本调用映射
  9. if (!$wait) {
  10. $this->serve($data);
  11. }
  12. }
再来看看 system.multicall 对应的处理函数:
  1. <?php
  2. function multiCall($methodcalls)
  3. {
  4. // See http://www.xmlrpc.com/discuss/msgReader$1208
  5. $return = array();
  6. foreach ($methodcalls as $call) {
  7. $method = $call['methodName'];
  8. $params = $call['params'];
  9. if ($method == 'system.multicall') {
  10. $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
  11. } else {
  12. $result = $this->call($method, $params);
  13. }
  14. if (is_a($result, 'IXR_Error')) {
  15. $return[] = array(
  16. 'faultCode' => $result->code,
  17. 'faultString' => $result->message
  18. );
  19. } else {
  20. $return[] = array($result);
  21. }
  22. }
  23. return $return;
  24. }
可以从代码中看出,程序会解析请求传递的 XML,遍历多重调用中的每一个接口调用请求,并会将最终有调用的结果合在一起返回给请求端。

这样一来,就可以将500种甚至是10000种帐号密码爆破尝试包含在一次请求中,服务端会很快处理完并返回结果,这样极大地提高了爆破的效率,利用多重调用接口压缩了请求次数,10000种帐号密码尝试只会在目标服务器上留下一条访问日志,一定程度上躲避了日志的安全检测。

通过阅读 WordPress 中 xmlrpc 相关处理的代码,能大量的 xmlrpc 调用都验证了用户名和密码:

  1. <?php
  2. if ( !$user = $this->login($username, $password) )
  3. return $this->error;

通过搜索上述登录验证代码可以得到所有能够用来进行爆破的调用方法列表如下:

  1. wp.getUsersBlogs, wp.newPost, wp.editPost, wp.deletePost, wp.getPost, wp.getPosts, wp.newTerm, wp.editTerm, wp.deleteTerm, wp.getTerm, wp.getTerms, wp.getTaxonomy, wp.getTaxonomies, wp.getUser, wp.getUsers, wp.getProfile, wp.editProfile, wp.getPage, wp.getPages, wp.newPage, wp.deletePage, wp.editPage, wp.getPageList, wp.getAuthors, wp.getTags, wp.newCategory, wp.deleteCategory, wp.suggestCategories, wp.getComment, wp.getComments, wp.deleteComment, wp.editComment, wp.newComment, wp.getCommentStatusList, wp.getCommentCount, wp.getPostStatusList, wp.getPageStatusList, wp.getPageTemplates, wp.getOptions, wp.setOptions, wp.getMediaItem, wp.getMediaLibrary, wp.getPostFormats, wp.getPostType, wp.getPostTypes, wp.getRevisions, wp.restoreRevision, blogger.getUsersBlogs, blogger.getUserInfo, blogger.getPost, blogger.getRecentPosts, blogger.newPost, blogger.editPost, blogger.deletePost, mw.newPost, mw.editPost, mw.getPost, mw.getRecentPosts, mw.getCategories, mw.newMediaObject, mt.getRecentPostTitles, mt.getPostCategories, mt.setPostCategories

这里是用参数传递最少获取信息最直接的 wp.getUsersBlogs 进行测试,将两次帐号密码尝试包含在同一次请求里,构造 XML 请求内容为:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <methodCall>
  3. <methodName>system.multicall</methodName>
  4. <params><param>
  5. <value><array><data>
  6. <value><struct>
  7. <member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
  8. <member><name>params</name><value><array><data>
  9. <value><string>admin</string></value>
  10. <value><string>admin888</string></value>
  11. </data></array></value></member>
  12. </struct></value>
  13.  
  14. <value><struct>
  15. <member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
  16. <member><name>params</name><value><array><data>
  17. <value><string>guest</string></value>
  18. <value><string>test</string></value>
  19. </data></array></value></member>
  20. </struct></value>
  21. </data></array></value>
  22. </param></params>
  23. </methodCall>

将上面包含两个子调用的 XML 请求POST至 xmlrpc 服务端入口,若目标开启了 xmlrpc 服务会返回类似如下的信息:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <methodResponse>
  3. <params>
  4. <param>
  5. <value>
  6. <array><data>
  7. <value><array><data>
  8. <value><array><data>
  9. <value><struct>
  10. <member><name>isAdmin</name><value><boolean>1</boolean></value></member>
  11. <member><name>url</name><value><string>http://172.16.96.130/xampp/wordpress-4.3.1/</string></value></member>
  12. <member><name>blogid</name><value><string>1</string></value></member>
  13. <member><name>blogName</name><value><string>WordPress 4.3.1</string></value></member>
  14. <member><name>xmlrpc</name><value><string>http://172.16.96.130/xampp/wordpress-4.3.1/xmlrpc.php</string></value></member>
  15. </struct></value>
  16. </data></array></value>
  17. </data></array></value>
  18. <value><struct>
  19. <member><name>faultCode</name><value><int>403</int></value></member>
  20. <member><name>faultString</name><value><string>用户名或密码不正确。</string></value></member>
  21. </struct></value>
  22. </data></array>
  23. </value>
  24. </param>
  25. </params>
  26. </methodResponse>

从结果中可以看到在同一次请求里面处理了两种帐号密码组合,并以集中形式将结果返回,通过该种方式可以极大地提高帐号爆破效率。

3.防护建议

1) 通过配置 Apache、Nginx 等 Web 服务器来限制 xmlrpc.php 文件的访问;

这里举例一个nginx

  1. location =/xmlrpc.php {
  2. deny all;
  3. }

2) 添加防护代码至WordPress配置文件

在wordpress的配置文件  wp-config.php  中添加如下代码

  1. add_filter('xmlrpc_enabled', '__return_false');

3) 从官方插件库中安装 Disable XML-RPC https://wordpress.org/plugins/disable-xml-rpc/ 并启用。

4) 在不影响站点运行的情况下可以直接删除 xmlrpc.php 文件。(不建议)

 

三. wordpress 后台默认地址

后台默认地址是 http://www.xxxxx.com/wp-login.php 这个地址很容易让有意爆破者,或者爆破工具(比如:wpscan) 找到,我们需要修改掉这个默认地址。
网上找到的很多做法是这样。在主题的 functions.php 里添加以下代码

  1. function login_protection() {
  2. if($_GET['word'] !='press')
  3. header('Location: /');
  4. }
  5. add_action('login_enqueue_scripts','login_protection');

这样一来,后台登录的唯一地址就是 http://www.xxxxx.com/wp-login.php?word=press,如果不是这个地址,就会自动跳转到 http://www.xxxxx.com/
但是,这并不能完全解决爆破入口的问题,懂一些http的人可以通过post来爆破该入口。

解决方案:

这里推荐三个插件
WPS Hide Login: 修改登录路由,来达到隐藏wordpress登录入口暴露的问题
WPS Limit Login: 限制后台登录试错次数,阻止黑客IP地址

Brute Force Login Protection :跟 WPS Limit Login 功能差不多

四.restAPI

wordpress的restAPI也是可以暴露用户名的
GET http://yoursite/wp-json/wp/v2/users

  1. [
  2. {
  3. "id": 1,
  4. "name": "nickname",
  5. "url": "",
  6. "description": "",
  7. "link": "http://yoursite/author/username",
  8. "slug": "username",
  9. "avatar_urls": {
  10. "24": "https://secure.gravatar.com/avatar/hashNumber?s=24&d=retro&r=g",
  11. "48": "https://secure.gravatar.com/avatar/hashNumber?s=48&d=retro&r=g",
  12. "96": "https://secure.gravatar.com/avatar/hashNumber?s=96&d=retro&r=g"
  13. },
  14. "meta": [],
  15. "_links": {
  16. "self": [
  17. {
  18. "href": "http://yoursite/wp-json/wp/v2/users/1"
  19. }
  20. ],
  21. "collection": [
  22. {
  23. "href": "http://yoursite/wp-json/wp/v2/users"
  24. }
  25. ]
  26. }
  27. }
  28. ]
 "link": "http://yoursite/author/username"  中  username  就是后台用户名了

解决方案:

方法一: 代码中禁止

在wordpress的主题所在 functions.php 中添加如下代码
过滤users端点,使未登录用户不能访问

  1. add_filter( 'rest_endpoints', function( $endpoints ){
  2. if(!is_user_logged_in()) {
  3. if ( isset( $endpoints['/wp/v2/users'] ) ) {
  4. unset( $endpoints['/wp/v2/users'] );
  5. }
  6. if ( isset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] ) ) {
  7. unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
  8. }
  9. }
  10. return $endpoints;
  11. });
或者

完全禁用未登录用户获取api

  1. /*禁用未登录的用户*/
  2. function rest_only_for_authorized_users($wp_rest_server) {
  3. if ( !is_user_logged_in() ) {
  4. wp_die('非法操作!');
  5. }
  6. }
  7. add_filter('rest_api_init', 'rest_only_for_authorized_users', 99);
两种方法,二选一

方法二:通过Web 服务器限制restAPI的访问

这里用nginx来举例子,其他服务器的设置请自行研究

全面禁用restAPI
  1. location ~* /wp/v2/(.*) {
  2. deny all;
  3. }
只禁用users端点
  1. location ~* /wp-json/wp/v2/users(\/)?(.*)? {
  2. deny all;
  3. }

方法三:WPS Bidouille插件

WPS Bidouille  中有个功能,可以直接在后台禁用掉restAPI的用户端点,所以,你只需要将用户端点在后台禁用即可。也可直接禁用REST API。

「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」

赞(0) 打赏
如果本文对你有所帮助,欢迎打赏¥:$$就足够感动我

支付宝扫一扫打赏

微信扫一扫打赏

上一篇:

下一篇:

相关推荐

0 条评论关于"WordPress防止暴力破解网站管理员密码"

最新评论

    暂无留言哦~~
   

扫码¥:19.9元赞助够本站永久VIP邀请码

扫码¥:19.9元 赞助够本站永久VIP注册邀请码..

添加:👉微信:Mojietou 👈

发送扫码成功截图获取注册邀请码...!

精彩评论

友情链接

他们同样是一群网虫,却不是每天泡在网上游走在淘宝和网游之间、刷着本来就快要透支的信用卡。他们或许没有踏出国门一步,但同学却不局限在一国一校,而是遍及全球!申请交换友链

站点统计

  • 文章总数: 642 篇
  • 草稿数目: 0 篇
  • 分类数目: 15 个
  • 独立页面: 12 个
  • 评论总数: 77 条
  • 链接总数: 14 个
  • 标签总数: 2898 个
  • 注册用户: 594 人
  • 访问总量: 8,669,862 次
  • 最近更新: 2021年1月24日
           

扫码¥:19.9元赞助够本站永久VIP注册邀请码.

添加:👉 微信:Mojietou 👈

发送扫码成功截图获取本站注册邀请码...!

服务热线:
 181XXXX8010

 QQ在线交流

 旺旺在线