0x00 前言:

这篇是去年组内分享的时候给小伙伴写的0基础快速审计tp3系列的文章,主要是对架构做个分析以及审计一些sql注入漏洞~

现在想想打算放出来,过了一年了,可能里面有一些问题,望看到的大佬不吝指教

0x01 架构:

应用入口文件index.php:

if(version_compare(PHP_VERSION,'5.3.0','<'))  die('require PHP > 5.3.0 !');

// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define('APP_DEBUG',True); // 定义应用目录
define('APP_PATH','./Application/'); // 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php'; app_debug为调试模式,开启app_debug可使thinkphp报错,方便调试和报错注入 thinkphp入口文件中可查看当前的框架版本 const THINK_VERSION = '3.2.3';

应用文件目录在Application(也可能不叫这个名字,在index.php定义应用目录),也就是开发者的应用都是写在这个文件夹里的,我们审计的部分也在这里。

mvc架构: mvc即模型,视图,控制器

Model(模型)是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。

View(视图)是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。

Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

而这个架构中我们的重点又放在controller里面,因为参数的传递是否可控通常是决定是否存在漏洞的根本因素。还有一个原因则是目前很多cms有一个问题就是完全的弱化了model层,controller层不但做了数据的接收,也同样处理了数据逻辑,和数据库进行交互。

因此一般来说,我们拿到一套thinkphp框架的cms时,逻辑应该是:

1.在index.php中开启debug方便调试,确认应用目录。

2.确定应用前台模块。(application的下一个目录,通常是Home,还可能存在Api和Admin。那么重点是审计Home和Api这种前台模块,主要后台注入也没啥意思...)

3.审计controller目录中的所有控制器文件。

0x02 路由和传参

传参:

php中获取参数一般是,$_GET,$_POST等,框架中也可以使用这种方式传参数,但更多的是使用框架自定义的函数I函数

I方法是ThinkPHP用于更加方便和安全的获取系统输入变量,可以用于任何地方,用法格式如下:

I('变量类型.变量名/修饰符',['默认值'],['过滤方法'],['额外数据源'])

example:I('id','','intval');

这种用法是使用intval过滤id参数,这个id参数可以来自get,post,它会自动辨别。

除了这种获取参数的方法,Thinkphp还有一种获取参数的方法,叫做参数绑定

example:

namespace Home\Controller;
use Think\Controller;
class BlogController extends Controller{
public function read($id){
echo 'id='.$id;
}
}

使用路由http://serverName/index.php?c=Blog&a=read&id=5即是给$id传值为5

因此我们在查看是否存在可控参数时切不要忘记还有这种方式传参。

路由:

thinkphp使用URL_MODEL=2 ;这种方式来指定路由模式,1,2,3分别代表不同的路由模式 具体可参考http://document.thinkphp.cn/manual_3_2.html#url文档来查看,但依据我的经验,除了某些特殊情况,我们可以在搭好cms之后通过黑盒快速找到路由规则。

0x03 TP常见的sql注入

1.智障拼接导致的sql注入:

 public function show(){
$article=M('article');
$id=I('id');
$article->where('id='.$id)->setInc('views');
$data = $article->field('title,content,addtime,views')->find($id);
$data['content']=htmlspecialchars_decode($data['content']);
$this->ajaxReturn($data);
}
}

这段代码中,$id参数被直接拼接到where方法中的id字段,导致sql注入。 I函数默认的过滤方法是htmlspecialchars,对sql注入的防御是没有作用的。 而where方法只对数组形式的参数进行过滤 具体可参考官方文档的说明: https://www.kancloud.cn/manual/thinkphp/1844
因此此处可总结为:
如果参数获取时没有进行有效过滤又通过字符串拼接的方式带入where方法,则基本可断定存在sql注入。
补天会收的cms中目前已经很少存在这种智障写法了,但是非常非常小的cms里还是存在这种写法的。还有就是安服的同学们做代码审计很可能会遇到:)

2.不能预编译的地方未作控制导致的注入:
tp3.x系列对于这种不能预编译的语句的参数貌似没做什么处理...包括limit order filed table..etc 因为按理来说这些地方是应该写死的。。。 limit注入代码示例:

public function read(){
$Customer=M('Customer_abroad);
$start = $_GET['start'];
$limit = $_GET['limit'];
$data['total'] = $Customer->count();
$data['success'] = true;
$data['message'] = '读取数据';
$data['data'] = $Customer->order('id DESC')->limit($start,$limit)->select();
$this->ajaxReturn($data,'JSON');
}

limit方法即对应sql语句中的limit,这里是没办法预编译的,thinkphp也没有对此处有防御方法,因此如果这里的参数可控就会存在limit注入
代码来源:https://github.com/focalhot/FHCRM/blob/master/System/Lib/Action/CustomerAction.class.php(已经没了)

表名注入代码示例:

public function zan_collect()
{
$data = $this->request->param();
$id = $data['id'];
$uid = session('userid');
if (!session('userid') || !session('username')) { return json(array('code' => 0, 'msg' => '登录后才能操作'));
} else { //状态:
// 0 用户 1 帖子 2 评论
$zan_collect = $data['zan_collect']; $msgsubject = '';
$zan_collect == 'zan' ? $msgsubject = '点赞' : $msgsubject = '收藏';
$tablename = '';
$type = $data['type'];
switch ($type) {
case 1:
$tablename = 'forum'; break; case 2: $tablename = 'comment';
break; case 3: $tablename = 'article';
break; default:
$msgsubject = '关注';
$tablename = 'user';
break;
}
$zuid = $id;
if ($type != '0') {
$zuid = Db::name($tablename)->where('id', $id)->value('uid'); }
if ($zuid == $uid) {
return json(array('code' => 0, 'res' => '减', 'msg' => '不可以孤芳自赏哦')); } $insertdata['type'] = $type;
$insertdata['uid'] = $uid;
$insertdata['sid'] = $id; $n = Db::name($zan_collect)->where($insertdata)->find();

这段代码的最后一行Db::name($zan_collect),如果$zan_collect是可控的,那么此处就存在一个表名注入。 另外,除了Db::name()之外,thinkphp3.2.x还使用M方法和D方法实例表,因此如果此处的写法为M($zan_collect)或者D($zan_collect)也是一样的效果。

代码来源:laysns-v2.4

注:对于order by ,limit,和表名的注入,一般的防御方法时将此处的参数写死,或者使用switch case语句。

3.不知道该怪开发还是怪框架的问题

举个例子,3.x系列不用I函数而直接原生取值基本可以说凉凉... 这里就不细说了,太多了说起来费劲,可以看看先知某师傅写的文章https://xz.aliyun.com/t/2630

内容非常全面,我就不赘述了,放一个栗子大家可以练手

https://github.com/duiying/TP3-CMS

Thinkphp3分析与审计的更多相关文章

  1. [Abp vNext 源码分析] - 文章目录

    一.简要介绍 ABP vNext 是 ABP 框架作者所发起的新项目,截止目前 (2019 年 2 月 18 日) 已经拥有 1400 多个 Star,最新版本号为 v 0.16.0 ,但还属于预览版 ...

  2. Eventlog Analyzer日志管理系统、日志分析工具、日志服务器的功能及作用

    Eventlog Analyzer日志管理系统.日志分析工具.日志服务器的功能及作用 Eventlog Analyzer是用来分析和审计系统及事件日志的管理软件,能够对全网范围内的主机.服务器.网络设 ...

  3. IIS Web服务器日志、日志服务器分析

    IIS Web服务器日志.日志服务器分析 EventLog Analyzer是一款全面的工具,用于审计.管理和跟踪您的Microsoft Internet Information Services(I ...

  4. syslog系统日志、事件日志分析、EventLog Analyzer

    syslog系统日志.事件日志分析.EventLog Analyzer Eventlog Analyzer是用来分析和审计系统及事件日志的管理软件,能够对全网范围内的主机.服务器.网络设备.数据库以及 ...

  5. 【转】webshell检测——使用auditd进行system调用审计

    本文档将介绍:如何通过Linux审计系统auditd监测WebShell执行系统命令的行为. 测试环境:CentOS7.0_x64 auditd简介 Linux审计系统提供了一种跟踪系统上与安全相关的 ...

  6. [Abp vNext 源码分析] - 9. 接口参数的验证

    一.简要说明 ABP vNext 当中的审计模块早在 依赖注入与拦截器一文中有所提及,但没有详细的对其进行分析. 审计模块是 ABP vNext 框架的一个基本组件,它能够提供一些实用日志记录.不过这 ...

  7. [原题复现+审计][0CTF 2016] WEB piapiapia(反序列化、数组绕过)[改变序列化长度,导致反序列化漏洞]

    简介  原题复现:  考察知识点:反序列化.数组绕过  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到此题 漏洞学习 数组 ...

  8. Oracle的回收站和闪回查询机制(二)

    上一篇中讲诉了Oracle中一些闪回查询(Flashback Query),这是利用回滚段信息来恢复一个或一些表到以前的一个时间点(一个快照).要注意的是,Flashback Query仅仅是查询以前 ...

  9. 【转载】LinkedIn是如何优化Kafka的

    http://www.wtoutiao.com/p/18d5RY0.html 在LinkedIn的数据基础设施中,Kafka是核心支柱之一.来自LinkedIn的工程师曾经就Kafka写过一系列的专题 ...

随机推荐

  1. Codeforces Round #666 (Div. 2) C. Multiples of Length (构造,贪心)

    题意:有一个长度为\(n\)的序列,可以操作\(3\)次,每次选取一段区间,然后区间的元素加减区间长度的倍数,\(3\)次操作后使得序列所有元素为\(0\),问具体操作情况. 题解:假如我们能选择一整 ...

  2. 获取csc.exe路径

    using System.Runtime.InteropServices; var frameworkPath = RuntimeEnvironment.GetRuntimeDirectory(); ...

  3. 加密后的程序在Win8中无法运行

    需要使用dotNET_Reactor 4.7以上的版本加密后才能在Win8中使用.

  4. 使用SignTool对软件安装包进行数字签名(一)--制作证书

    一.制作根证书 1.开始菜单-运行-输入cmd,弹出命令行窗体. 2.输入命令:cd /d F:\SignTool,将当前工作目录修改到SignTool路径下. 3.使用makecert命令制作证书, ...

  5. JPG学习笔记1(附完整代码)

    #topics h2 { background: rgba(43, 102, 149, 1); border-radius: 6px; box-shadow: 0 0 1px rgba(95, 90, ...

  6. ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE 【模拟+博弈】

    题目:戳这里 题意:A和B博弈,三种操作分别是x:加a,y:减b,z:取相反数.当x或y或z为0,说明该操作不可取,数据保证至少有一个操作可取,给定一个区间(l,k)和原始数字m,如果A和B在n次操作 ...

  7. 利用windows api共享内存通讯

    主要涉及CreateFile,CreateFileMapping,GetLastError,MapViewOfFile,sprintf,OpenFileMapping,CreateProcess Cr ...

  8. hdoj 5971

    Wrestling Match Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  9. sqli-libs(4) 双引号报错

    经测试,发现单引号不报错,而双引号却报错了 通过查看源码,发现下图中红色的箭头,如果不知道是什么意思,我们可以复制出来看看是什么含义: <?php$id=1;$id='"' .$id. ...

  10. CSS3 弹性盒子(Flex Box)

    1 CSS3 弹性盒子(Flex Box) 1 http://caniuse.com/#search=flex%20box https://www.w3.org/TR/css-flexbox-1/ C ...