TP5框架及无框架变量覆盖反序列化

3ad5b2ff0be8c5e5b52630b856f649f4

Metinfo-变量覆盖

phpmydmin-无框架-反序列化

搜索反序列化关键函数:serialize(),unserialize(),__construct,__destruct

Snipaste_2023-07-05_09-45-46

$_POST['configuration']存在,并且变量action不等于clear,就调用反序列化函数

Snipaste_2023-07-05_09-46-15

php魔术方法,反序列化会触发__wakeup()

  • __wakeup() : 使用unserialize()时触发
  • __sleep() : 使用serialize()时触发
  • __destruct() : 对象被销毁时触发
  • __call() : 在对象上下文中调用不可访问的方法时触发
  • __callStatic() : 在静态上下文中调用不可访问的方法时触发
  • __get() : 用于从不可访问的属性读取数据
  • __set() : 用于将数据写入不可访问的属性
  • __isset() : 在不可访问的属性上调用isset()empty()触发
  • __unset() : 在不可访问的属性上使用unset()时触发
  • __toString() : 把类当作字符串使用时触发
  • __invoke() : 当脚本尝试将对象调用为函数时触发

Snipaste_2023-07-06_06-02-44

Snipaste_2023-07-06_06-03-10

Snipaste_2023-07-06_06-03-40

为什么是找wakeup,因为上面有说这里使用unserialize的时候就会触发

Snipaste_2023-07-06_06-06-34

英文注释是:在加载完session文件后,重新初始化对象,检查配置文件的是否改变,如果必要就重新加载

简单分析:getsource获取源码,filemtime() 函数返回文件内容的上次修改时间。成功,以 Unix 时间戳形式返回文件内容的上次修改时间。如果失败,则返回 FALSE。这里是检测源码的目前时间和返回的时间戳不等。(或者是默认源码的修改)

1
2
3
4
5
6
7
8
9
10
11
---load方法,根据判断file_get_contents是否存在来进行代码执行

---file_get_contents()将整个文件读取为字符串

---trim() 函数移除字符串两侧的空白字符或其他预定义字符。

---implode() 函数返回由数组元素组合成的字符串

---因此,这里是代码执行getsource的文件的代码

---getsource是返回目前的配置文件(小迪说是获取源代码)

总结:调用反序列函数,会调用创建对象的类中的wakeup方法,进而调用代码执行getsource(注意,这个getsource是对象的方法,要构造getsource就要在对象的类里面构造)

因此,我们要利用这个漏洞有两点:1.满足调用反序列化函数的条件2.满足wakeup方法里面load的条件(从这里构造payload)

Snipaste_2023-07-06_06-12-13

Snipaste_2023-07-06_06-14-23

Snipaste_2023-07-06_06-16-13

访问这个路径

在电脑中的盘符中创建一个test.txt文件,然后写入内容:woaixiaodi,然后传入下面的值

Payload:action=1&configuration=O:10:"PMA_Config":1:{s:6:"source",s:11:"E:/test.txt";}

1
序列化的格式(注意这里构造payload可以不是类真实的属性):对象名称:PMA_Config;长度:10;1个属性,格式为字符串形式,名为:source,长度为6,属性的内容:d:/test.txt,长度为11

Snipaste_2023-07-06_06-28-50

这里就会出现文件中的内容

如果这里的内容是恶意代码的话也会被执行

Snipaste_2023-07-06_06-29-56

Snipaste_2023-07-06_06-30-28

总结:这里就是先载入字符串,然后使用eval将载入的字符串当做php代码执行

Thinkphp5—有框架-搭建使用入口访问调试 SQL 等

安装,由于安装thinkphp5,官网已经没有下载了,所以去github上进行下载

https://github.com/top-think/think/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
git clone https://github.com/top-think/think.git thinkphp5
//这里的https可能会报错,下载不了,改成http试试,thinkPHP5是安装的目录

//然后进入到thinkphp5的目录
git checkout v5.0.15

//返回上一级目录
git clone https://github.com/top-think/framework.git thinkphp

//安装好之后同样进入thinkphp目录
git checkout v5.0.15

//查看版本
git branch -a

参考博客:

https://www.cnblogs.com/lpxspring/p/12129136.html

https://blog.csdn.net/LingTing12116/article/details/108395121

Snipaste_2023-07-06_07-14-30

Snipaste_2023-07-06_07-14-42

thinkphp的目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
project  应用部署目录
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可更改)
│ ├─index 模块目录(可更改)
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─extend 扩展类库目录(可定义)
├─public WEB 部署目录(对外访问目录)
│ ├─static 静态资源存放目录(css,js,image)
│ ├─index.php 应用入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于 apache 的重写
├─runtime 应用的运行时目录(可写,可设置)
├─vendor 第三方类库目录(Composer)
├─thinkphp 框架系统目录
│ ├─lang 语言包目录
│ ├─library 框架核心类库目录
│ │ ├─think Think 类库包目录
│ │ └─traits 系统 Traits 目录
│ ├─tpl 系统模板目录
│ ├─.htaccess 用于 apache 的重写
│ ├─.travis.yml CI 定义文件
│ ├─base.php 基础定义文件
│ ├─composer.json composer 定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 惯例配置文件
│ ├─helper.php 助手函数文件(可选)
│ ├─LICENSE.txt 授权说明文件
│ ├─phpunit.xml 单元测试配置文件
│ ├─README.md README 文件
│ └─start.php 框架引导文件
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件

Snipaste_2023-07-06_08-38-03

url访问的方法(比如上面的index.php文件就是:APPlication目录下的index目录(模块),index.php文件(控制器),index()方法(操作))

Snipaste_2023-07-06_09-28-03

这里新建一个新的方法test

Snipaste_2023-07-06_09-29-41

Snipaste_2023-07-06_09-29-36

在index.php目录下创建Test.php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
namespace app\index\controller;
use think\Controller;
use think\Db;

class Test extends Controller{
public function x(){
echo 'xiaodi-testhhhhh';
}
public function testsqlin(){
$id = $_GET['x'];
$conn = mysql_connect("127.0.0.1","root","123.com");
$sql = "select * from user where id=$id";
echo $sql;
$result=mysql_query($sql,$conn);
}
}
?>

Snipaste_2023-07-06_09-43-31

这里的文件名的首字母好像是必须要大写,不能是test,需要Test

Snipaste_2023-07-06_09-48-42

这里沙漠里的鲸使用的php的版本是5.6,我用的是5.4的,所以语句还是老样子:mysql_query($sql,$conn);,这里鲸鱼哥还写了判断连接的if,我这里就没有写了

Snipaste_2023-07-06_09-58-18

Snipaste_2023-07-06_10-01-59

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
namespace app\index\controller;
use think\Controller;
use think\Db;

class Test extends Controller{
public function x(){
echo 'xiaodi-testhhhhh';
}
public function testsqlin(){
$id = $_GET['x'];
$conn = mysql_connect("127.0.0.1","root","123.com");
$sql = "select * from test.user where id=$id";
echo $sql;
$result=mysql_query($sql,$conn);
}
public function testsqlin1(){
$id=$_GET['x'];
db('user')->where('id',$id)->select();
}
}
?>
#这里只需要写表名,因为在之前中database的配置文件中就已经配置了数据库名,这里在查询的时候会自动带上那个数据库中进行查询,所以这里只要写一个表名就行了

Snipaste_2023-07-06_10-13-57

Snipaste_2023-07-06_10-16-35

Snipaste_2023-07-06_10-16-59

不开启调试模式,单纯的使用审计工具的mysql监控是监控不到的,github上的那种web监控好像可以(沙漠里的鲸说可以),这里我就不做实验了。

Snipaste_2023-07-06_10-18-30

总结:

1
2
3
4
5
如果发现thinkphp框架,存在以下思路:

如果按照thinkphp官方的写法去写的,那么你所面对的就是去挖掘thinkphp框架的漏洞,这里最好知道thinkphp的版本,这样就可以去百度有没有这个版本的漏洞,如果有就去验证,没有就pass了

还有一种就是使用的的确是thinkphp的框架,但是没有利用框架,和上面的两个sql查询的方法一样,那么这种就是常规的审计思路