不规范写法导致的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());
}
}
漏洞环境二
// 使用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());
}
}
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
漏洞分析
我们主要跟几个关键函数吧。
最近有点累了,害。这个自己也感觉没怎么讲,很多细节都没有说。等分析反序列化的时候再重新好好整理一下这个吧。建议师傅看下面参考链接好了。
第一个关键点: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
然后经过赋值得到sql语句
select count(*) as aggregate from `users` where `username` = ? and `R0ser1` <> ? and `` = ?
漏洞修复
参考
https://www.freebuf.com/column/199156.html