CTFSHOW-WEB入门-PHP特性109-115

  1. 题目:web 109
    1. 题目:
    2. 解题思路:题目要求获得两个参数,v1 v2,if语句中的意思是要求两个参数都包含字母,条件满足的话,执行 echo new 类名(方法());这里使用echo 输出对象,会触发tostring方法,所以后面的类名要用实现toString方法的类,由于php中的内置类较为安全和稳定,所以使用php的内置类,常见的内置类且实现了toString的有:
    3. DateTime
      1. <font style="color:rgb(251, 71, 135);">DateTime</font> 类实现了 <font style="color:rgb(251, 71, 135);">__toString()</font> 方法,默认返回 ISO 8601 格式的日期时间字符串。
plain 复制代码
$date = new DateTime();
echo $date;  // 输出类似 2023-10-21T15:23:01+00:00
    2. **<font style="color:rgba(0, 0, 0, 0.88);">DateTimeImmutable</font>**
        1. <font style="color:rgba(0, 0, 0, 0.88);">与 </font>`<font style="color:rgb(251, 71, 135);">DateTime</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 类似,</font>`<font style="color:rgb(251, 71, 135);">DateTimeImmutable</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 也实现了 </font>`<font style="color:rgb(251, 71, 135);">__toString()</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 方法。</font>
plain 复制代码
$dateImmutable = new DateTimeImmutable();
echo $dateImmutable;  // 输出类似 2023-10-21T15:23:01+00:00
    3. **<font style="color:rgba(0, 0, 0, 0.88);">SimpleXMLElement</font>**
        1. `<font style="color:rgb(251, 71, 135);">SimpleXMLElement</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 实现了 </font>`<font style="color:rgb(251, 71, 135);">__toString()</font>`<font style="color:rgba(0, 0, 0, 0.88);">,返回 XML 的字符串表示。</font>
plain 复制代码
$xml = new SimpleXMLElement('<root><element>Hello World</element></root>');
echo $xml;  // 输出: <root><element>Hello World</element></root>
    4. **<font style="color:rgba(0, 0, 0, 0.88);">DOMElement</font>**
        1. `<font style="color:rgb(251, 71, 135);">DOMElement</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 及其某些其它 DOM 扩展类(如 </font>`<font style="color:rgb(251, 71, 135);">DOMDocument</font>`<font style="color:rgba(0, 0, 0, 0.88);">、</font>`<font style="color:rgb(251, 71, 135);">DOMNode</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 等)也实现了 </font>`<font style="color:rgb(251, 71, 135);">__toString()</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 方法,返回相应的元素的字符串表示。</font>
plain 复制代码
$doc = new DOMDocument();
$doc->loadXML('<root><element>Hello World</element></root>');
$element = $doc->documentElement;
echo $element;  // 输出: <root><element>Hello World</element></root>
    5. **<font style="color:rgba(0, 0, 0, 0.88);">stdClass</font>**
        1. <font style="color:rgba(0, 0, 0, 0.88);">虽然 </font>`<font style="color:rgb(251, 71, 135);">stdClass</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 的 </font>`<font style="color:rgb(251, 71, 135);">__toString()</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 方法返回一个空字符串,但它是一个通用的对象,可以用来作为动态属性容器。</font>
plain 复制代码
$obj = new stdClass();
echo $obj;  // 输出: (空字符串)
    6. **<font style="color:rgba(0, 0, 0, 0.88);">ArrayObject</font>**
        1. `<font style="color:rgb(251, 71, 135);">ArrayObject</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 实现了 </font>`<font style="color:rgb(251, 71, 135);">__toString()</font>`<font style="color:rgba(0, 0, 0, 0.88);"> 方法,返回数组的字符串表示。</font>
plain 复制代码
$arrayObj = new ArrayObject([1, 2, 3]);
echo $arrayObj;  // 输出: Array
3. 使用内置类+函数名,?v1=DateTimeImmutable&v2=system(ls)得到目录结果:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1738916228400-f52225c1-8403-4a79-bb8b-395ce1d88327.png)查看flag:![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1738916344206-d7e83f64-01ba-49ea-aeb7-3d15a6171e54.png)
4. 知识点:`<font style="color:#dd0000;">echo new </font><font style="color:#0000bb;">$v1</font><font style="color:#dd0000;">(</font><font style="color:#0000bb;">$v2</font><font style="color:#dd0000;">());</font>`的执行机制:
php 复制代码
new $v1 表示创建 $v1 的一个实例。这里 $v1 必须是一个类名。
$v2() 则表示实例化后调用 $v2 这个函数或方法。
在这个上下文中,你假设用户输入的 $v1 是类名且 $v2 是方法名。
  1. 题目:web 110
    1. 题目:
    2. 解题思路:分析一下这个题目的代码,思路与上一题类似,区别是v1 和v2 的过滤更加严格,过滤了括号,因此不可以用有参数的函数了,但是还有一些无参数的函数可以使用。 php 中查看目录的函数有:scandir()、golb()、dirname()、basename()、realpath()、getcwd() ,其中 scandir()、golb() 、dirname()、basename()、realpath() 都需要给定参数,而 getcwd() 不需要参数,getchwd() 函数会返回当前工作目录。 而类FilesystemIterator 是 PHP 的一个类,用于遍历文件系统中的目录和文件。那么我们就可以通过遍历当前目录获取目录内容:v1=FilesystemIterator&v2=getcwd得到当前目录下有一个文件:直接进行访问:getflag:
    3. 知识点:内置类FilesystemIterator可以遍历目录内容,以及无参函数getcwd获取当前目录
    4. 注意: 这里说一下为什么Directoryiterator为什么不能用? 当你创建一个 DirectoryIterator 对象并将其实例化为某个目录时,该对象会默认指向所代表的目录。举个例子,如果你创建一个 DirectoryIterator 对象来表示 /var/www/html 目录,那么该对象就会默认指向 /var/www/html 目录。 而当你对这个目录进行迭代操作时,DirectoryIterator 会遍历该目录中的所有文件和子目录。这意味着,遍历的结果会包括当前目录 . 和上级目录 ..。通常,这两个特殊的目录会作为遍历结果的一部分返回,因为它们是文件系统中的标准目录表示法。所以,使用 DirectoryIterator 遍历目录时,默认情况下会包括 ... 这两个目录项。
  2. 题目:web 111
    1. 题目:
    2. 解题思路:分析代码可以知道,这道题我们利用的点在getflag函数里面,这里面的eval函数里面的KaTeX parse error: Expected 'EOF', got '&' at position 4: v1=&̲v2这一句较为复杂:其执行流程是首先获取$v2的值,将他作为变量名,重新作为一个变量,并将他的地址传递给 1 的值对应的变量(该变量对应的流程和 1的值对应的变量(该变量对应的流程和 1的值对应的变量(该变量对应的流程和v2一样),然后再输出v1变量的详细信息。这里仍然是对v1 v2进行了过滤,与上一题不同的是,同时还增添了对于v1的限制,要包含ctfshow. 这里就先将v1设置为ctfshow,这样就得到getFlag里面的KaTeX parse error: Expected 'EOF', got '&' at position 9: ctfshow=&̲另一个变量,另一个变量是什么呢...flag 里面,于是先设置v2=flag,这样就有KaTeX parse error: Expected 'EOF', got '&' at position 9: ctfshow=&̲flag:进行尝试:尝试失败了,我以为的是flag.php 文件里面没有 f l a g 这个变量,看了其他师傅们的博客知道,是因为对于这个文件的 g e t F l a g 来说, flag 这个变量,看了其他师傅们的博客知道,是因为对于这个文件的getFlag来说, flag这个变量,看了其他师傅们的博客知道,是因为对于这个文件的getFlag来说,flag,是一个外部变量,没有访问的权限,于是就要用到超全局变量:GLOBALS: $GLOBALS 是PHP的一个超级全局变量组,包含了全部变量的全局组合数组,变量的名字就是数组的键。 于是?v1=ctfshow&v2=GLOBALS get到flag:
    3. 知识点:PHP中的超全局变量:
    4. <font style="color:rgb(251, 71, 135);">$_GET</font>
      1. 用于收集 URL 中查询字符串的变量。当你通过 URL 传递参数时,可以使用这个变量访问这些参数。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_GET['name']</font> 获取 URL 中的 <font style="color:rgb(251, 71, 135);">?name=value</font> 中的 <font style="color:rgb(251, 71, 135);">value</font>
    5. <font style="color:rgb(251, 71, 135);">$_POST</font>
      1. 用于收集通过 HTTP POST 方法发送到脚本的数据。通常用于表单提交。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_POST['username']</font> 获取通过 POST 提交的表单中 <font style="color:rgb(251, 71, 135);">username</font> 字段的值。
    6. <font style="color:rgb(251, 71, 135);">$_REQUEST</font>
      1. 包含了 <font style="color:rgb(251, 71, 135);">$_GET</font><font style="color:rgb(251, 71, 135);">$_POST</font> 以及 <font style="color:rgb(251, 71, 135);">$_COOKIE</font> 的所有数据,是一个合并的数组。你可以通过它来访问表单数据,无论是 GET 还是 POST,甚至是 cookies 中的值。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_REQUEST['anyField']</font>
    7. <font style="color:rgb(251, 71, 135);">$_SESSION</font>
      1. 用于在用户会话期间存储数据。会话数据存储在服务器上,并通过会话 ID 区分。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_SESSION['user_id']</font> 可能保存用户登录状态。
    8. <font style="color:rgb(251, 71, 135);">$_COOKIE</font>
      1. 用于访问存储在用户计算机上的 cookie 数据。可以读取和设置 cookie。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_COOKIE['logged_in']</font> 获取名为 <font style="color:rgb(251, 71, 135);">logged_in</font> 的 cookie 值。
    9. <font style="color:rgb(251, 71, 135);">$_FILES</font>
      1. 用于访问通过 HTTP POST 上传到脚本的文件。这个变量是一个数组,包含了文件的相关信息。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_FILES['file']['name']</font> 获取上传文件的原始文件名。
    10. <font style="color:rgb(251, 71, 135);">$_SERVER</font>
      1. 包含了关于当前请求和脚本执行环境的信息。例如:HTTP 头、路径、脚本位置等。
      2. '示例: <font style="color:rgb(251, 71, 135);">$_SERVER['HTTP_USER_AGENT']</font> 获取用户的浏览器信息。
    11. <font style="color:rgb(251, 71, 135);">$_ENV</font>
      1. 用于访问环境变量。通常来自服务器上配置的环境变量。
      2. 示例: <font style="color:rgb(251, 71, 135);">$_ENV['PATH']</font> 可能包含系统的 PATH 环境变量。
    12. <font style="color:rgb(251, 71, 135);">GLOBALS</font>
      1. 是一个包含了所有全局变量的关联数组。你可以通过这个数组访问在函数或方法外定义的变量。
      2. 示例: <font style="color:rgb(251, 71, 135);">GLOBALS['myVar']</font> 访问全局变量 <font style="color:rgb(251, 71, 135);">$myVar</font>
  3. 题目:web 112
    1. 题目:
    2. 解题思路:这个题考察的是文件包含,题目中filter函数过滤的有.../ 上级目录,字符串http data https input rot13 base64 string 等包含伪协议的关键字,那么我们就要 利用其他伪协议的替代,这里用到的是:
    3. 知识点:伪协议的替代协议
  4. 题目:web 113
    1. 题目:
    2. 解题思路:这个题又过滤了filter,于是上一题的payload无法使用 ,又去查找了其他协议,发现还有compress.zlib://和compress.zip2://协议,于是使用compress.zlib://协议: **file=compress.zlib://flag.php**可以访问到结果: 但是这里有一个疑问第二个协议却不行,两者都是对压缩文件生效的,但是这里flag,php 不是压缩文件也生效了
    3. 看看还有没有其他的解法可以使用:有的兄弟,有的!: 通过/proc/self/root访问根文件系统中的任何文件和目录。 这里有一个前提知识: 在Linux系统中,/proc/self/root/是一个指向当前进程根文件系统挂载点的符号链接。通常,它直接指向系统的根目录/ 在大多数Linux文件系统中,路径解析不会因为连续的/或重复的目录名(如多次出现的/proc/self/root/)而改变最终访问的文件。 那么我们就可以利用多个挂载符号连接,超过函数可以解析的最大限制,从而实现目录溢出,访问到我们想要的文件:于是构造payload:file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php得到结果:
    4. 知识点:伪协议的替代 使用 **/proc/self/root**目录溢出
  5. 题目:web 114
    1. 题目:
    2. 解题思路:这道题目将filter换成了compress zip root等形式,那么就过滤了使用根目录的特殊符号挂载符号,也不能使用上次试过的compress协议,于是可以使用filter:直接访问源文件就行:file=php://filter/resource=flag.php得到好结果:
    3. 另解:使用filter的过滤器解压与压缩:?file=php://filter/read=zlib.deflate|zlib.Inflate/resource=flag.php,这里将当访问该 URL 时,PHP 引擎会首先读取 <font style="color:rgb(251, 71, 135);">flag.php</font> 文件的内容,由于选用了 <font style="color:rgb(251, 71, 135);">zlib.deflate</font> 过滤器,文件内容在输出之前会被压缩。紧接着,通过 <font style="color:rgb(251, 71, 135);">|</font> 符号,将压缩的数据传送给 <font style="color:rgb(251, 71, 135);">zlib.Inflate</font> 过滤器,这样最终的结果就是 <font style="color:rgb(251, 71, 135);">flag.php</font> 的内容被解压并展示。
    4. 知识点:filter 过滤器的种类
php 复制代码
在 php://filter 路径中,可以指定多种过滤器来对读取的文件内容进行预处理。这些过滤器主要分为字符串过滤器、转换过滤器、压缩过滤器和加密过滤器四大类。以下是对这些过滤器的详细归纳:
一、字符串过滤器
    string.rot13
        功能:对数据进行 ROT13 编码。ROT13 编码是一种简单的替换密码,它将字母表中的每个字母替换为字母表中13位之后的字母(忽略非字母字符)。
        示例:php://filter/read=string.rot13/resource=flag.php
    string.toupper
        功能:将字符串转换为大写。
        示例:php://filter/read=string.toupper/resource=flag.php
    string.tolower
        功能:将字符串转换为小写。
        示例:php://filter/read=string.tolower/resource=flag.php
    string.strip_tags
        功能:去除字符串中的 HTML 和 PHP 标签。
        示例:php://filter/read=string.strip_tags/resource=flag.php
二、转换过滤器
    convert.base64-encode
        功能:对数据进行 Base64 编码。
        示例:php://filter/read=convert.base64-encode/resource=flag.php
    convert.base64-decode
        功能:对数据进行 Base64 解码。
    convert.quoted-printable-encode
        功能:对数据进行 Quoted-Printable 编码。
    convert.quoted-printable-decode
        功能:对数据进行 Quoted-Printable 解码。
    convert.iconv.*
        功能:将数据流的内容按照指定字符编码进行转换。
        使用格式:convert.iconv.<input-encoding>.<output-encoding> 或 convert.iconv.<input-encoding>/<output-encoding>
        示例:将 flag.php 的内容从 UCS-2LE 编码转换为 UCS-2BE 编码:php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php
三、压缩过滤器
    zlib.deflate
        功能:对数据进行 zlib 压缩。
    zlib.inflate
        功能:对数据进行 zlib 解压。
    bzip2.compress
        功能:对数据进行 bzip2 压缩。
    bzip2.decompress
        功能:对数据进行 bzip2 解压。
四、加密过滤器
    mcrypt.* 和 mdecrypt.*
        功能:使用 libmcrypt 提供对称的加密和解密。
        示例格式:mcrypt.ciphername,其中 ciphername 是密码的名字,将被传递给 mcrypt_module_open()。
        注意:这些过滤器的使用可能需要 PHP 的 mcrypt 扩展库支持,并且需要指定加密算法和模式等参数。然而,需要注意的是,mcrypt 扩展在 PHP 7.1.0 中已经被废弃,并在 PHP 7.2.0 中被完全移除。因此,在现代的 PHP 环境中,建议使用其他加密扩展,如 OpenSSL。
  1. 题目:web 115
    1. 题目:
    2. 解题思路:分析题目发现题目要求我们get一个参数,num,要求这个函数不是数字---!is_numeric(),去掉首位空白符得到的不强等于36,通过filter函数==38,在进行比较,如果弱等于36,那么输出flag,于是我们构造payload:首先第一个函数is_numeric通过空白符就可以绕过,第二个函数trim函数处理的范围包括: 对于 trim() 函数会去除空格( %20)、制表符(%09)、换行符(%0a)、回车符(%0d)、空字节符(%00)、垂直制表符(%0b),不包括换页符(%0c )。由于这里是强比较,不会进行类型转换,在trim函数后,其与'36'不强相等:;其次,由于这些都不在filter函数内,于是乎,可以绕过过滤,得到flag:
    3. 知识点:强类型比较时候不进行类型转换,直接进行的是字符串的比较
相关推荐
软件开发技术局28 分钟前
撕碎QT面具(8):对控件采用自动增加函数(转到槽)的方式,发现函数不能被调用的解决方案
开发语言·qt
csbDD1 小时前
2025年网络安全(黑客技术)三个月自学手册
linux·网络·python·安全·web安全
anyup_前端梦工厂1 小时前
了解几个 HTML 标签属性,实现优化页面加载性能
前端·html
周杰伦fans2 小时前
C#中修饰符
开发语言·c#
yngsqq2 小时前
c# —— StringBuilder 类
java·开发语言
前端御书房2 小时前
前端PDF转图片技术调研实战指南:从踩坑到高可用方案的深度解析
前端·javascript
2301_789169542 小时前
angular中使用animation.css实现翻转展示卡片正反两面效果
前端·css·angular.js
赔罪2 小时前
Python 高级特性-切片
开发语言·python
阿湯哥2 小时前
越权漏洞及其修复方法
网络·安全·web安全
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端