一次笨办法TP测试
字数 1230 2025-08-10 08:28:40
ThinkPHP 5.0.13 安全测试与Getshell方法详解
环境概述
- 目标系统: Nginx + ThinkPHP 5.0.13
- PHP版本: 7.1.32
- 特点: 开启了DEBUG模式,常见危险函数被禁用
常规测试方法受阻
1. Session Getshell尝试
- 使用ThinkPHP写session的常规方法
- 蚁剑连接成功但无数据返回(可能EXP存在问题)
2. 日志文件包含尝试
- 两种日志包含思路:
- 包含Nginx日志(access.log/error.log)
- 包含ThinkPHP自身日志(runtime/log/202012/xx.log)
问题发现:
- 包含/etc/passwd成功但日志包含失败
- 可能原因:
- think\include模块被修改或禁用
- 日志默认名称被修改
- 日志路径被修改或日志功能被重写
验证过程:
- 使用think\Lang::load替代think\include模块 - 失败
- 检查Nginx配置文件 - 发现access.log为空(0B)
新方法尝试:Build::module模块创建
方法原理
- 利用think\Build::module创建新模块
- ThinkPHP会自动在新模块控制器中创建index.php
- 模块名可控,可尝试注入payload
测试Payload
_method=__construct&method=GET&server[]=1&filter[]=think\Build::module&get[]=xxx
本地测试成功示例
创建名为test;phpinfo();\\的模块:
- 成功注入payload
- 通过文件包含可执行phpinfo()
目标环境问题
- application目录不可写
- public目录也无写入权限
- 此方法在目标环境失败
最终解决方案:日志路径审计
审计步骤
- 使用show_source()函数读取相关文件
- 检查ThinkPHP日志命名规则文件:
thinkphp/think/log/driver/File.php - 发现开发者添加了BIND_MODULE修改日志路径
- 最终日志路径格式:
LOG_PATH/BIND_MODULE/202012/25.log
成功包含
- 确定BIND_MODULE值后
- 构造正确的日志路径进行包含
- 成功getshell
关键知识点总结
-
ThinkPHP日志机制:
- 默认路径:runtime/log/年月/日.log
- 可通过BIND_MODULE等配置修改路径
-
文件包含技巧:
- 优先使用show_source()而非readfile()
- 包含失败时考虑路径/权限问题
-
环境审计方法:
- 读取框架核心文件确定配置变更
- 关注自定义日志记录功能(如发现的record_log)
-
安全配置影响:
- 目录写入权限限制可阻断部分攻击
- 日志路径自定义增加攻击难度
-
DEBUG模式风险:
- 暴露LOG_PATH等关键信息
- 提供更多攻击面信息
防御建议
- 生产环境关闭DEBUG模式
- 限制框架核心文件的读取权限
- 使用非默认日志路径和命名规则
- 严格控制可写目录权限
- 及时更新框架版本修复已知漏洞