Drupal V7.3.1 框架处理不当导致SQL注入
这个漏洞本是2014年时候被人发现的,本着学习的目的,我来做个详细的分析。漏洞虽然很早了,新版的Drupal甚至已经改变了框架的组织方式。但是丝毫不影响对于漏洞的分析。这是一个经典的使用PDO,但是处理不当,导致SQL语句拼接从而导致注入的问题。从这个问题,以及以往我见过的很多的漏洞来看,我不得不说,代码底层做的再安全,过滤的再完全,如果程序员的一个不小心,也将会导致重大安全问题的出现。多少的编码绕过,逻辑漏洞正是不小心带来的问题。
0x00 注入的定位
首先我根据网络上已经出现过的EXP,然后进行追踪。无奈,这个框架实在太大,我在跟进的过程中,遇到了诸多的问题,甚至路由模式都没有搞的很明白。然后根据已有的漏洞细节,我迅速定位到了漏洞的发生点。
在文件 \modules\user\user.module 中 有 user_login_authenticate_validate() 函数,代码如下:
- function user_login_authenticate_validate($form, &$form_state) {
- $password = trim($form_state['values']['pass']);
- if (!empty($form_state['values']['name']) && !empty($password)) {
- // Do not allow any login from the current user's IP if the limit has been
- // reached. Default is 50 failed attempts allowed in one hour. This is
- // independent of the per-user limit to catch attempts from one IP to log
- // in to many different user accounts. We have a reasonably high limit
- // since there may be only one apparent IP for all users at an institution.
- if (!flood_is_allowed('failed_login_attempt_ip', variable_get('user_failed_login_ip_limit', 50), variable_get('user_failed_login_ip_window', 3600))) {
- $form_state['flood_control_triggered'] = 'ip';
- return;
- }
- $account = db_query("SELECT * FROM {users} WHERE name = :name AND status = 1", array(':name' => $form_state['values']['name']))->fetchObject();
- //省略无关代码...
很明显,这里的SQL查询就是漏洞触发现场了,我们跟进db_query这个函数,代码如下:
- function db_query($query, array $args = array(), array $options = array()) {
- if (empty($options['target'])) {
- $options['target'] = 'default';
- }
- return Database::getConnection($options['target'])->query($query, $args, $options);
- }
继续跟进query函数:
- public function query($query, array $args = array(), $options = array()) {
- // Use default values if not already set.
- $options += $this->defaultOptions();
- try {
- // We allow either a pre-bound statement object or a literal string.
- // In either case, we want to end up with an executed statement object,
- // which we pass to PDOStatement::execute.
- if ($query instanceof DatabaseStatementInterface) {
- $stmt = $query;
- $stmt->execute(NULL, $options);
- }
- else {
- $this->expandArguments($query, $args);
- $stmt = $this->prepareQuery($query);
- $stmt->execute($args, $options);
- }
- //省略无关代码...
我们知道,如果在PHP连接MySQL数据库中,如果我们使用PDO进行预编译的话,我们的语句是无法改变原有的查询结构的,也就是说,注入的语句,无法进行查询,只能是当做字符串。从而从数据库查询层对注入做了彻底防御。那么这里是怎么产生问题的呢?
0x01 错误的处理导致的安全问题
但是这里有个问题,就是当参数是数组的时候,就会用到expandArguments这个方法,然后这个方法由于处理不当会导致安全问题。
函数代码如下:
- protected function expandArguments(&$query, &$args) {
- $modified = FALSE;
- // If the placeholder value to insert is an array, assume that we need
- // to expand it out into a comma-delimited set of placeholders.
- foreach (array_filter($args, 'is_array') as $key => $data) {
- $new_keys = array();
- foreach ($data as $i => $value) {
- // This assumes that there are no other placeholders that use the same
- // name. For example, if the array placeholder is defined as :example
- // and there is already an :example_2 placeholder, this will generate
- // a duplicate key. We do not account for that as the calling code
- // is already broken if that happens.
- $new_keys[$key . '_' . $i] = $value;
- }
- // Update the query with the new placeholders.
- // preg_replace is necessary to ensure the replacement does not affect
- // placeholders that start with the same exact text. For example, if the
- // query contains the placeholders :foo and :foobar, and :foo has an
- // array of values, using str_replace would affect both placeholders,
- // but using the following preg_replace would only affect :foo because
- // it is followed by a non-word character.
- $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query);
- // Update the args array with the new placeholders.
- unset($args[$key]);
- $args += $new_keys;
- $modified = TRUE;
- }
- return $modified;
- }
我们再来回顾一下之前的查询语句,
- db_query("SELECT * FROM {users} WHERE name = :name AND status = 1", array(':name' => $form_state['values']['name']))
这个数组我们是可控的,首先在array_filter之后,使用foreach进行遍历,然后二轮遍历中创建了一个新的数组。接着把$query变量中的键,进行了替换,替换掉以后的内容是之前新数组键用 ', '进行合并成的一个新的字符串。这样我们通过键来进行SQL注入就行的通了。注入语句将会通过拼接进入。
0x03 测试
可以看得很清楚,name数组中的两个键都被拼接进了SQL查询。
0x04 反思
这里是挺有意思,也很常见的一个问题。我在开头的引言中也说了。本来是做好了处理的,但是却使用了拼接,导致可控的外部数据进入了SQL查询。类似这样的问题还很常见,当然了,这也为自己挖洞提供了思路,在挖洞越来越困难的当下,挖洞思路的变化显得十分重要了。
Drupal V7.3.1 框架处理不当导致SQL注入的更多相关文章
- 管中窥豹——框架下的SQL注入 Java篇
管中窥豹--框架下的SQL注入 Java篇 背景 SQL注入漏洞应该算是很有年代感的漏洞了,但是现在依然活跃在各大漏洞榜单中,究其原因还是数据和代码的问题. SQL 语句在DBMS系统中作为表达式被解 ...
- 最新版SEMCMS_PHP_3.5 过滤不严导致sql注入
一.漏洞分析 在分析过程中看到网上已经有人发现semcms V2.4存在过滤不严导致sql注入的漏洞,不知道咋还没改,而且最新版过滤的关键字更少了. 首先查看首页文件index.php的代码 < ...
- 浅析PHP框架Laravel最新SQL注入漏洞
PHP知名开发框架Laravel,之前在官方博客通报了一个高危SQL注入漏洞,这里简单分析下. 首先,这个漏洞属于网站coding写法不规范,官方给了提示: 但官方还是做了修补,升级最新版本V5.8. ...
- dedecms SESSION变量覆盖导致SQL注入漏洞修补方案
dedecms的/plus/advancedsearch.php中,直接从$_SESSION[$sqlhash]获取值作为$query带入SQL查询,这个漏洞的利用前提是session.auto_st ...
- 代码审计-Thinkphp3框架EXP表达式SQL注入
最近看java框架源码也是看的有点头疼,好多还要复习熟悉 还有好多事没做...慢慢熬. 网上好像还没有特别详细的分析 我来误人子弟吧. 0x01 tp3 中的exp表达式 查询表达式的使用格式: $m ...
- yii框架各种防止sql注入,xss攻击,csrf攻击
PHP中常用到的方法有: /* 防sql注入,xss攻击 (1)*/ function actionClean($str) { $str=trim($str); ...
- 一次SQL注入导致的"越权"
原文来自SecIN社区-作者:tkswifty 相关背景 在实际的业务开发中,SQL交互往往是业务系统中不可或缺的一项.在Java中提供了类似Mybatis.Hibernate.SpringDat ...
- 【漏洞复现】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现
影响版本 wordpress < 5.8.3 分析 参考:https://blog.csdn.net/qq_46717339/article/details/122431779 在 5.8.3 ...
- Java SQL注入学习笔记
1 简介 文章主要内容包括: Java 持久层技术/框架简单介绍 不同场景/框架下易导致 SQL 注入的写法 如何避免和修复 SQL 注入 2 JDBC 介绍 JDBC: 全称 Java Databa ...
随机推荐
- centos 7 安装最新版本git
https://serverfault.com/questions/709433/install-a-newer-version-of-git-on-centos-7 You could use a ...
- mongoTemplate更新一个Document里面的数组的一个记录。
假如有一个Document如下: { "_id" : "69bca85a-5a61-4b04-81fb-ff6a71c3802a", "_class& ...
- LinUX系统ThinkPHP5链接MsSQL数据库的pdo_dblib扩展
LinUX(centOS6.8)系统ThinkPHP5链接MsSQL数据库的pdo_dblib扩展第一步 下载并安装freetds-current.tar.gz下载地址如下ftp://ftp.free ...
- # 20155327 2016-2017-4 《Java程序设计》第9周学习总结
20155327 2016-2017-4 <Java程序设计>第9周学习总结 20155327 2016-2017-4 <Java程序设计>第9周学习总结 教材学习内容总结 了 ...
- arean.c
glibc-2.14中的arean.c源代码,供研究malloc和free实现使用: /* Malloc implementation for multiple threads without loc ...
- Android如何判断当前手机是否正在播放音乐,并获取到正在播放的音乐的信息
我想实现如下的场景,判断当前Android手机上是否正在播放音乐,如果是,通过某个特定的手势, 或者点击某个按键,将当前我正在听的音乐共享出去. 第一步,就是判断当前是否有音乐正在播放. 最开始我想得 ...
- openGL中的原理理解1---一个视图需要支持OGL需要配置,GLenbalView的理解
OpenGL的绘图机制是 OpenGL的绘图方式与Windows一般的绘图方式是不同的,主要区别如下: (1)Windows采用的是GDI(Graphy Device Interface 图形设备接口 ...
- CentOS 6.0下phpvod搭建教程(LAMP+phpvod)
之所以安装CentOS是因为之前试过RedHat,但是发现RedHat在安装时,无法获取安装源,原因是RedHat系统没有在RHN注册. 网上的很多教程都说可以直接换用CentOS的源,可我小搞里一会 ...
- merge sort 的javascript实现
递归 上一篇blog里,用js实现了quicksort算法,quicksort算法是一个递归调用过程. 递归是一种非常强大的编程思想,它广泛的的存在于各种语言当中,尤其lisp的各种方言中,大量的使用 ...
- solr特点一:高亮(highlighting)
高亮的配置 参数详细说明: hl.fl: 用空格或逗号隔开的字段列表.要启用某个字段的highlight功能,就得保证该字段在schema中是stored.如果该参数未被给出,那么就会高亮默认字段 s ...