- 题目:web 109
- 题目:

- 解题思路:题目要求获得两个参数,v1 v2,if语句中的意思是要求两个参数都包含字母,条件满足的话,执行 echo new 类名(方法());这里使用echo 输出对象,会触发tostring方法,所以后面的类名要用实现toString方法的类,由于php中的内置类较为安全和稳定,所以使用php的内置类,常见的内置类且实现了toString的有:
- DateTime
<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)得到目录结果:查看flag:
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 是方法名。
- 题目:web 110
- 题目:

- 解题思路:分析一下这个题目的代码,思路与上一题类似,区别是v1 和v2 的过滤更加严格,过滤了括号,因此不可以用有参数的函数了,但是还有一些无参数的函数可以使用。 php 中查看目录的函数有:scandir()、golb()、dirname()、basename()、realpath()、getcwd() ,其中 scandir()、golb() 、dirname()、basename()、realpath() 都需要给定参数,而 getcwd() 不需要参数,getchwd() 函数会返回当前工作目录。 而类FilesystemIterator 是 PHP 的一个类,用于遍历文件系统中的目录和文件。那么我们就可以通过遍历当前目录获取目录内容:v1=FilesystemIterator&v2=getcwd得到当前目录下有一个文件:
直接进行访问:getflag:
- 知识点:内置类FilesystemIterator可以遍历目录内容,以及无参函数getcwd获取当前目录
- 注意: 这里说一下为什么Directoryiterator为什么不能用? 当你创建一个
DirectoryIterator
对象并将其实例化为某个目录时,该对象会默认指向所代表的目录。举个例子,如果你创建一个 DirectoryIterator
对象来表示 /var/www/html
目录,那么该对象就会默认指向 /var/www/html
目录。 而当你对这个目录进行迭代操作时,DirectoryIterator
会遍历该目录中的所有文件和子目录。这意味着,遍历的结果会包括当前目录 .
和上级目录 ..
。通常,这两个特殊的目录会作为遍历结果的一部分返回,因为它们是文件系统中的标准目录表示法。所以,使用 DirectoryIterator
遍历目录时,默认情况下会包括 .
和 ..
这两个目录项。
- 题目:web 111
- 题目:

- 解题思路:分析代码可以知道,这道题我们利用的点在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:
- 知识点:PHP中的超全局变量:
<font style="color:rgb(251, 71, 135);">$_GET</font>
- 用于收集 URL 中查询字符串的变量。当你通过 URL 传递参数时,可以使用这个变量访问这些参数。
- 示例:
<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>
。
<font style="color:rgb(251, 71, 135);">$_POST</font>
- 用于收集通过 HTTP POST 方法发送到脚本的数据。通常用于表单提交。
- 示例:
<font style="color:rgb(251, 71, 135);">$_POST['username']</font>
获取通过 POST 提交的表单中 <font style="color:rgb(251, 71, 135);">username</font>
字段的值。
<font style="color:rgb(251, 71, 135);">$_REQUEST</font>
- 包含了
<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 中的值。
- 示例:
<font style="color:rgb(251, 71, 135);">$_REQUEST['anyField']</font>
。
<font style="color:rgb(251, 71, 135);">$_SESSION</font>
- 用于在用户会话期间存储数据。会话数据存储在服务器上,并通过会话 ID 区分。
- 示例:
<font style="color:rgb(251, 71, 135);">$_SESSION['user_id']</font>
可能保存用户登录状态。
<font style="color:rgb(251, 71, 135);">$_COOKIE</font>
- 用于访问存储在用户计算机上的 cookie 数据。可以读取和设置 cookie。
- 示例:
<font style="color:rgb(251, 71, 135);">$_COOKIE['logged_in']</font>
获取名为 <font style="color:rgb(251, 71, 135);">logged_in</font>
的 cookie 值。
<font style="color:rgb(251, 71, 135);">$_FILES</font>
- 用于访问通过 HTTP POST 上传到脚本的文件。这个变量是一个数组,包含了文件的相关信息。
- 示例:
<font style="color:rgb(251, 71, 135);">$_FILES['file']['name']</font>
获取上传文件的原始文件名。
<font style="color:rgb(251, 71, 135);">$_SERVER</font>
- 包含了关于当前请求和脚本执行环境的信息。例如:HTTP 头、路径、脚本位置等。
- '示例:
<font style="color:rgb(251, 71, 135);">$_SERVER['HTTP_USER_AGENT']</font>
获取用户的浏览器信息。
<font style="color:rgb(251, 71, 135);">$_ENV</font>
- 用于访问环境变量。通常来自服务器上配置的环境变量。
- 示例:
<font style="color:rgb(251, 71, 135);">$_ENV['PATH']</font>
可能包含系统的 PATH 环境变量。
<font style="color:rgb(251, 71, 135);">GLOBALS</font>
- 是一个包含了所有全局变量的关联数组。你可以通过这个数组访问在函数或方法外定义的变量。
- 示例:
<font style="color:rgb(251, 71, 135);">GLOBALS['myVar']</font>
访问全局变量 <font style="color:rgb(251, 71, 135);">$myVar</font>
。
- 题目:web 112
- 题目:

- 解题思路:这个题考察的是文件包含,题目中filter函数过滤的有.../ 上级目录,字符串http data https input rot13 base64 string 等包含伪协议的关键字,那么我们就要 利用其他伪协议的替代,这里用到的是:

- 知识点:伪协议的替代协议
- 题目:web 113
- 题目:

- 解题思路:这个题又过滤了filter,于是上一题的payload无法使用 ,又去查找了其他协议,发现还有compress.zlib://和compress.zip2://协议,于是使用compress.zlib://协议:
**file=compress.zlib://flag.php**
可以访问到结果:
但是这里有一个疑问第二个协议却不行,两者都是对压缩文件生效的,但是这里flag,php 不是压缩文件也生效了 
- 看看还有没有其他的解法可以使用:有的兄弟,有的!: 通过/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得到结果:
- 知识点:伪协议的替代 使用
**/proc/self/root**
目录溢出
- 题目:web 114
- 题目:

- 解题思路:这道题目将filter换成了compress zip root等形式,那么就过滤了使用根目录的特殊符号挂载符号,也不能使用上次试过的compress协议,于是可以使用filter:直接访问源文件就行:
file=php://filter/resource=flag.php
得到好结果:
- 另解:使用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>
的内容被解压并展示。
- 知识点: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。
- 题目:web 115
- 题目:

- 解题思路:分析题目发现题目要求我们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:
- 知识点:强类型比较时候不进行类型转换,直接进行的是字符串的比较