Laravel不规范写法导致注入漏洞

不规范写法导致的SQL注入

漏洞概要

只要发现SQL语句是拼凑的基本都会有SQL注入,造成的结果就是没有绑定值,大家可以跟一下代码。

漏洞环境一

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
class MsgController extends Controller
{
    public function index(Request $request){
        DB::connection()->enableQueryLog();

        $id=$_GET['id'];
        $sql="select * from users where id=$id";
        $res=DB::statement($sql);
        dump($res);

        DD(DB::getQueryLog());
    }
}

image-20210804174542693

漏洞环境二

// 使用whereRaw 或者 selectRaw导致的SQL注入

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
class MsgController extends Controller
{
    public function index(Request $request){
        DB::connection()->enableQueryLog();
          $id=$request->input('id');
          $res=DB::table('users')->whereRaw("id=$id")->get();
          dump($res);
        DD(DB::getQueryLog());
    }
}

image-20210804174900840

Laravel 5.8 SQL注入

漏洞概要

漏洞存在于Laravel的表单验证功能,漏洞为Rule类的ignore方法

漏洞文件位于/vendor/laravel/ramework/src/Illuminate/Validation/Rules/Unique.php

该方法有两个参数,第一个参数为字段值,第二个参数为字段名,当字段名为空时,默认字段名为“id”。如果用户可以控制ignore()方法的参数值,就会产生SQL注入漏洞。

影响版本:5.8.5及以下版本

漏洞环境

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Validator;
use DB;
class MsgController extends Controller
{
    public function index(Request $request){
        DB::connection()->enableQueryLog();

        $validator = Validator::make($request->input(), [
            'username' => [
                'required',
                Rule::unique("users")->ignore($request->input("id"))
            ],
        ]);
        dump($validator->fails());

          DD(DB::getQueryLog());
    }
}

访问http://www.laravel.com/index?username=admin&id=1%22,R0ser1,%22

image-20210804200141887

漏洞分析

我们主要跟几个关键函数吧。

最近有点累了,害。这个自己也感觉没怎么讲,很多细节都没有说。等分析反序列化的时候再重新好好整理一下这个吧。建议师傅看下面参考链接好了。

第一个关键点:ignore函数

    public function ignore($id, $idColumn = null)
    {
        if ($id instanceof Model) {
            return $this->ignoreModel($id, $idColumn);
        }

        $this->ignore = $id;
        // 我们传入的$id=1",R0ser1,"
        $this->idColumn = $idColumn ?? 'id';
		//因为ignore其实有两个参数但是我们控制键的值没用的,控制键就好了。因为是PDO操作
        return $this;
    }

然后直接到我们的__toString函数

    public function __toString()
    {
        return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
            $this->table,
            $this->column,
            $this->ignore ? '"'.$this->ignore.'"' : 'NULL',
                             //直接赋值
            $this->idColumn,
            $this->formatWheres()
        ), ',');
    }
}

最后返回我们的$rules

image-20210804201036102

然后经过赋值得到sql语句

select count(*) as aggregate from `users` where `username` = ? and `R0ser1` <> ? and `` = ?

漏洞修复

image-20210804195832021

参考

https://xz.aliyun.com/t/5331

https://www.freebuf.com/column/199156.html

posted @ 2021-08-04 20:22  R0ser1  阅读(560)  评论(0编辑  收藏  举报