全局变量(PHP)

news/2025/1/8 2:04:43/文章来源:https://www.cnblogs.com/sjjjjer/p/18656602

免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!!
附:完整笔记目录~
ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!

1.1 🐘全局变量(PHP)

  1. 引子:从本章开始,正式进入Web开发篇,当然文章所写内容并非如何从零开始成为一名合格的开发者,而是站在安全的角度学开发。再说白点,就是开发者在开发业务系统时,哪处容易出现安全问题就学哪处。本章则从PHP基础之全局变量开始。

  2. $GLOBALS
    $GLOBALS全局变量,为PHP内置的全局数组,存储了当前脚本所有的全局作用域变量。(其中,全局作用域变量指在函数外部所定义的变量,可在整个脚本中被访问,不过在函数内部默认无法访问。)
    demo:

    <?php
    $x = 1;
    $y = 2;
    $z = 19;
    function add()
    {# $z = $x + $y;# 由于x,y,z定义在函数外,无法直接调用,# 此时$GLOBALS全局变量的作用就体现出来了,# 可通过$GLOBALS全局数组实现对x,y,z变量的访问和更改$GLOBALS['z'] = $GLOBALS['x'] + $GLOBALS['y'];
    }add();
    echo "z的值为" . $z;
    # RES: z的值为3
    # 综上所述,通过部分全局变量可实现对于原本无法直接访问变量的调用与修改。
    
  3. $_GET & $_POST & $_REQUEST
    $_GET全局变量用于获取Http请求包中请求方法为get的数据, $_POST全局变量用于获取请求方式为post的数据,$_REQUEST可同时接收来自get&post的数据。
    demo:

    <?php
    echo "接收到GET请求包的值为:" . $_GET['x'] . '<hr>';
    # http://192.168.2.106:81/global/GlobalDemo2.php?x=19
    # RES: 接收到GET请求包的值为:19echo "接收到POST请求包的值为:" . $_POST['y'] . '<hr>';
    # http://192.168.2.106:81/global/GlobalDemo2.php?x=19
    # body: y=19
    # RES: 接收到POST请求包的值为:19echo "接收到GET/POST请求包的值为:" . $_REQUEST['z'];
    # http://192.168.2.106:81/global/GlobalDemo2.php?x=19&z=19
    # body: y=19
    # RES: 接收到GET/POST请求包的值为:19
    # http://192.168.2.106:81/global/GlobalDemo2.php?x=19
    # body: y=19&z=19
    # RES: 接收到GET/POST请求包的值为:19
    
  4. $_COOKIE & $_SESSION
    用于访问&存储Cookie&Session值信息。
    demo1:

    <?php
    // 获取用户名和密码
    $username = $_POST['username'];
    $password = $_POST['password'];
    // 保存为 Cookie
    setcookie('username', $username, time() + 86400, '/');
    setcookie('password', $password, time() + 86400, '/');
    // 其中 'username' & 'password' 为Cookie Name
    // $username & $password 为Cookie Value
    // time() + 86400 为Cookie有效期,即从当前开始持续24小时
    // '/' 为Cookie生效范围,'/'即为用户访问该网站任意路径都会携带Cookieecho "Cookie中的username值为:" . $_COOKIE['username'] . '<hr>';
    echo "Cookie中的password值为:" . $_COOKIE['password'] . '<hr>';
    // RES:Cookie中的username值为:test
    //     Cookie中的password值为:test
    

    demo2:

    <?php
    // 启动会话
    session_start();// 获取用户名和密码
    $username = $_POST['username'];
    $password = $_POST['password'];
    // 将用户名和密码保存到Session中
    $_SESSION['username'] = $username;
    $_SESSION['password'] = $password;echo '生成的Session ID为:' . session_id() . '<hr>';
    // 生成的Session ID为:q738a9r9i2knp06ctb08gtu16b
    echo "Session中的username值为:" . $_SESSION['username'] . '<hr>';
    // Session中的username值为:test
    

    由于Session的设计原理,生成Session后会返回给客户端一个Session ID,待客户端下次访问时会携带该Session ID且与存储于服务端的Session文件名(文件名即为Session ID)比较,若文件存在则证明该用户身份正确。需要注意的是,Session ID默认会在浏览器关闭后失效。
    因此我们可以根据Session ID尝试寻找被存储的Session文件并查看其文件内容:
    image-20250106154314115

  5. $_Files
    该全局变量访问&存储经POST方法上传的文件信息,如文件名、MIME类型、文件大小等信息。
    什么是MIME类型?
    MIME:Multipurpose Internet Mail Extensions,也称媒体类型,为互联网通信中表示文件内容的类型。最初于电子邮件系统中被用于对不同类型文件的正确接收&发送,后被广泛应用至Http等网络协议中。
    demo:

    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>文件上传</title>
    </head>
    <body><h2>文件上传表单</h2><form action="GlobalDemo5.php" method="post" enctype="multipart/form-data"><label for="file">选择文件:</label><input type="file" name="file" id="file" required><br><br><button type="submit">上传文件</button></form>
    </body>
    </html><?php
    echo '<br>';
    echo "被上传文件的临时存储路径为:".$_FILES['file']['tmp_name'].'<hr>';
    echo "被上传文件名为:".$_FILES['file']['name'].'<hr>';
    echo "被上传文件大小为:".$_FILES['file']['size'].'<hr>';
    echo "被上传文件类型为:".$_FILES['file']['type'];
    // 被上传文件的临时存储路径为:C:\Windows\phpB828.tmp,
    // --> 临时路径可由php.ini中upload_tmp_dir指定,若未指定则采取系统默认
    // 被上传文件名为:1.png
    // 被上传文件大小为:376394
    // 被上传文件类型为:image/png
    
  6. $_ENV & $_SERVER
    其中$_ENV存储了系统环境变量信息,$_SERVER存储了服务器&执行环境信息。
    demo:

    <?php
    // 若想使$_ENV全局变量能访问当前系统环境变量,
    // 需在php.ini文件中启用 variables_order  Default Value: "EGPCS"
    echo "PHP脚本路径为:".$_ENV['SCRIPT_NAME'].'<hr>';
    echo "PHP配置文件路径为:".$_ENV['PHPRC'].'<hr>';
    echo "PHP运行环境为:".$_ENV['SERVER_SOFTWARE'].'<hr>';
    // PHP脚本路径为:/global/GlobalDemo6.php
    // PHP配置文件路径为:D:/Lan/IDE/Extra/PHPkaifa/phpstudy_pro/Extensions/php/php7.3.4nts
    // PHP运行环境为:Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02echo "访问服务端的客户端UA头为:".$_SERVER['HTTP_USER_AGENT'].'<hr>';
    echo "访问服务端的客户端ip为:".$_SERVER['REMOTE_ADDR'].'<hr>';
    echo "访问服务端的客户端port为:".$_SERVER['REMOTE_PORT'].'<hr>';
    echo "服务端的ip为:".$_SERVER['SERVER_ADDR'].'<hr>';
    // 访问服务端的客户端UA头为:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
    // 访问服务端的客户端ip为:192.168.2.106
    // 访问服务端的客户端port为:63323
    // 服务端的ip为:192.168.2.106
    

    感觉下来,这两个全局变量所存储的信息内容差不多,$_ENV能访问&存储的信息,$_SERVER也可以。只不过$_ENV默认无法访问到系统环境变量信息,需在php.ini文件中开启。

  7. 实验
    好了,你已经学会php Web开发了,现在开始代码审计吧(不是。

    1. 实验案例:DuomiCms
      由于笔者比较菜(😭),因此本文的审计流程为“对着答案出题”。想了解完整代审流程可参考这位大佬的文章:https://blog.csdn.net/qq_59023242/article/details/135080259

    2. 审计目标:绕过账户&密码验证,实现后台登录。
      这里直接给出答案,也就是payload。

      /interface/comment.php?_SESSION[duomi_admin_id]=19&_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_name]=sj
      
    3. 首先分析一下这段payload,/interface/comment.php为访问路径,? 后为传递参数,该参数的含义为为全局变量_SESSION所存储内容重新赋值。
      当输入错误账户&密码后,生成的Session文件内容为:
      image-20250106215535428
      输入payload后,Session文件内容被覆盖为:
      image-20250106215731960
      再尝试缩减该payload为:

      ?_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_id]=19
      

      发现此时仍可绕过账户&密码验证,可以推测Session中duomi_group_id & duomi_admin_id的值是绕过前台登陆的关键,但又因为duomi_admin_id的值为我随意赋的,因此我们需要重点关注的仅剩duomi_group_id字段。ok,接下来看代码。

    4. 找到intereface/comment.php文件,搜索duomi_group_id发现无结果,但在文件开头发现该文件包含了common.php 与 core.class.php的脚本文件。
      image-20250106221939568

    5. 在common.php文件中仍未找到duomi_group_id,但发现了:

      <?php
      ...
      foreach(Array('_GET','_POST','_COOKIE') as $_request)
      {foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
      }# 该代码将来自Http请求数据中的 键 & 值 分别存储至 $_k & $_v 变量中
      # 也就是说该文件有接收&处理用户提交数据的功能
      

      虽然得知了common.php文件具有接收&处理用户所传数据的功能,但文件中并未发现duomi_group_id,也就是说对于duomi_group_id数据的处理并不在该文件中。推测该文件可能仅是对接收数据的初步处理,更深一步的处理可能在别的且包含该文件的文件中。

    6. 全局搜索包含/common.php的文件
      image-20250106224832183
      由于后台登录路径为/admin,而我们要实现后台登录绕过,因此优先看admin目录下文件。虽然仍未找到对duomi_group_id的处理,但在/admin/config.php文件下找到了:

      <?php
      ...
      //检验用户登录状态
      $cuserLogin = new userLogin();
      if($cuserLogin->getUserID()==-1)
      {header("location:login.php?gotopage=".urlencode($EkNowurl));exit();
      }# 由注释可知,该代码的功能为检验用户登录状态,以及一个对所返回userid的判断
      # 但我们仍不知其所返回userid是否与duomi_group_id相关,因此追踪一下userLogin对象
      
    7. 查看duomiphp/check.admin.php文件,也就是定义userLogin对象的文件,成功找到了定义duomi_group_id的代码。
      image-20250106231226275
      并在49-54行中,发现了将keepgroupidTag(doumi_gourp_id)赋值给了groupid,也就是说传递给_SESSION[duomi_group_id]的值最终被groupid所接收,但在该check.admin.php文件中发现并未处理获取到的groupid,因此还需找处理groupid的代码。
      image-20250106232010509

    8. 全局搜索groupid,最终在/admin/admin_manager.php文件中找到对groupid的处理逻辑。
      image-20250106235559017
      也就验证了为什么payload的写法为:

      /interface/comment.php?_SESSION[duomi_admin_id]=19&_SESSION[duomi_group_id]=1&_SESSION[duomi_admin_name]=sj
      
    9. 试验结束!

    ps:接下来如果还有类似的代审实验,笔者应该不会再记录了,因为记得有点像流水账,有很多细节我自己都不太懂,还是不误导大家了。这里还是建议有一定开发底子后再接触代审。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865133.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET 响应式编程 System.Reactive 系列文章(一):基础概念

在.NET中,响应式编程的核心库是System.Reactive,通常简称为Rx。本篇文章将介绍响应式编程的基础概念以及System.Reactive的核心组件,为后续深入学习奠定基础。.NET 响应式编程 System.Reactive 系列文章(一):基础概念 引言 在现代软件开发中,处理异步事件和数据流已经成…

【神兵利器】绕过EDR防病毒软件

免责声明 仅限用于技术研究和获得正式授权的攻防项目,请使用者遵守《中华人民共和国网络安全法》,切勿用于任何非法活动,若将工具做其他用途,由使用者承担全部法律及连带责任,作者及发布者不承担任何法律连带责任项目介绍 项目演示了使用Windows API函数(例如:VirtualAllo…

RAG项目推荐:bRAG-langchain-构建自己的 RAG 应用程序所需了解的一切

检索增强生成 (RAG) 项目项目链接:https://github.com/bRAGAI/bRAG-langchain/tree/mainbRAGAI 的官方平台即将上线。加入等待列表,成为早期使用者之一! 本仓库包含了对检索增强生成 (RAG) 在各种应用中的全面探索。 每个笔记本都提供了从入门级到高级实现的详细实践指南,包…

五上数学LK情况反馈203班

五上数学LK情况反馈203班 上周五进行了LK,使用答题卡,电子阅卷,答题卡放在中学部,我们只有拿着学生没有写答案的试卷讲评,需要知道具体错误的,由周老师告知学生,今天晚上有半数以上学生,周老师已经告知学生错误题目了,分数已经公布。 本次考试难度较大,带有XB的性质,…

【金融行业】2024中国网络安全产业势能榜优能企业 金融行业典型案例展示

金融行业一直是信息安全的重点领域,随着金融科技的快速发展和数字货币的崛起,金融机构面临着前所未有的挑战。数据泄露、网络攻击等安全事件的频发,促使金融企业加强安全保障。然而,信息安全的提高不仅仅是防止外部威胁的关键,更重要的是确保业务在突发事件或安全事件发生…

Timer、Ticker使用及其注意事项

在 Golang 中,Timer 和 Ticker 是常用的定时器工具,但它们的使用易出错,尤其是初学者。本文将深入探讨定时器的正确使用方式、常见误区,并通过源码解读帮助你更好地理解它们的工作原理。Timer、Ticker使用及其注意事项 在刚开始学习golang语言的时候就听说Timer、Ticker的使…

entire vs whole; coca

entire 868 whole 466left 4WORD 1: ENTIRE WORD W1 W2 AN 15134 932 VIRTUALLY 354 71 Virtually the entire sample几乎所有样本 Virtually the entire Israeli governing class几乎整个以色列统治阶级 DEVOTED 216 71 devoted his entire care…

第22章 高级线程处理

第22章 高级线程处理 22.1 同步概述 多线程我们常需要一些同步结构进行线程间通讯。同步结构可以分为三类:互斥锁一次只允许一个线程执行特定的活动或一段代码。主要目的是令线程访问共享的写状态而不互相影响。互斥锁包括 lock​、Mutex​ 和 SpinLock​。 2. 非互斥锁 实现…

DINO-X环境搭建推理测试

​引子 开放世界检测,前文也写OV-DINO(感兴趣的童鞋,请移步OV-DINO开放词检测环境安装与推理-CSDN博客)。这不,DINO系列又更新了。OK,那就让我们开始吧。 一、模型介绍 IDEA 开发了一个通用物体提示来支持无提示的开放世界检测,从而无需用户提供任何提示即可检测图像中…

一文说透汇编语言中的各种地址

本文讨论了学习汇编语言时一些易混淆的、关于地址的概念前言 由于笔者水平有限,随笔中难免有些许纰漏和错误,希望广大读者能指正。 一、各种地址之间的区分 笔者在刚开始学习汇编语言时,不是很能分清楚汇编地址、逻辑地址、物理地址、段地址、偏移地址、线性地址等概念,这对…