题目告诉我们falg在flag.php中,但是访问了这个网页后,发现并没有,我们查看右键查看源代码有新的发现
代码审计
从第10行开始有php的代码,需要我们做php的代码审计
首先,通过if( !ini_get('display_errors') )判断当前PHP环境是否已设置display_errors配置参数。如果没有设置,则通过ini_set('display_errors', 'On')设置为打开错误显示功能。
使用error_reporting(E_ALL)设置错误报告级别为显示所有错误。
然后,从$_COOKIE数组中获取名为language的值,并将其赋值给$lan变量。
如果$lan不存在或为空,使用setcookie函数设置一个名为language的cookie,值为"english",并包含"english.php"文件。
如果$lan有值,根据该值包含相应的语言文件。
使用file_get_contents函数获取名为index.php的文件的内容,并将其赋值给变量$x。
最后,使用echo语句将变量$x的内容输出。
分析到这里方法就明确了,通过cookie传入文件包含的payload,就会执行
<?php //判断当前环境是否有设置diaplay_errors,没有设置的话,就使用On的方式打开 if(!ini_get('dispaly_errors')){ ini_get('display_errors','On'); } //设置错误显示级别为显示所有错误 error_reporting(*E_ALL*); //从cookie数组中获取language的数值,并赋值给lan变量 $lan=$_COOKIE['language']; //在lan不存在或为空的条件下,使用setcookie函数设置一个名为language数值为enlish的cookie并包含在enlish.php中 if(!$lan) { //使用 @ 符号抑制错误 @setcookie("language","english"); @include("english.php"); } //如果lan有数值的话,就会根据该数值包含相对应的语言文件,上传的COOKIE存在$lan,则$lan会自动拼接.php,并进行包含 else { @include($lan.".php"); } //使用file_get_contents函数获取名为index.php的文件内容并赋值给变量x $x=file_get_contents('index.php'); echo $x; ?>
我们打开bp进行抓包,这里抓包是在将题目链接在bp自带的浏览器中打开的
在里面添加内容:Cookie:language=php://filter/convert.base64-encode/resource=flag如果你是小白,看到这里可能要问(为什么如此构造?)
可以看出有这个内容的回显,我们再进行base64的解码
可以得到flag的内容
知识点
display_errors函数
display_errors是PHP配置选项之一,用于控制是否在页面上显示错误信息。
当display_errors配置参数被设置为On时,PHP会在页面上显示运行时错误信息。这对于开发和调试阶段非常有用,可以实时查看代码中的错误,并及时进行修复。
当display_errors配置参数被设置为Off时(或者未设置),PHP将禁止在页面上显示错误信息。这在生产环境中是一种常见的配置,以防止敏感信息暴露给用户或潜在的安全风险。
php伪协议
php://filter 是一个可以在 PHP 中进行数据过滤和流处理的协议。它可以让你通过一些特定的过滤器来处理各种数据流,包括文件,HTTP 请求,以及其它的输入和输出数据流。这些过滤器可以用于实现各种功能,例如数据加密和解密,数据压缩和解压缩,以及数据格式转换等。不过需要注意的是,如果使用不当,该协议也可能导致一些安全问题。协议的语法:
php://filter/标准输入输出流标识其中,[标准输入输出流标识] 可以是以下字符串之一:
read: 表示标准输入流(stdin) write: 表示标准输出流(stdout) 其它文件系统可用流标识符,比如 php://temp (临时流)和 php://memory(内存流)等。 而 [使用的过滤器] 部分则是一个或多个 PHP 过滤器名称,多个过滤器名称以 | 分隔。例如:urlencode|strip_tags
例如,如果您想使用 urlencode 过滤器将一段字符串编码并将其写入标准输出流(stdout),您可以使用以下语法:php://filter/write=urlencode|stdout
php://filter伪协议规则:
php://filter/过滤器|过滤器/resource=待过滤的数据流
构造php://filter伪协议规则:
php://filter/convert.base64-encode/resource=flag.php
?是起始符可以理解为连接拼接的意思,file1是场景代码中的变量,=是赋值的意思。
convert转换,base64,encode编码。
&引用,不同名字访问同一变量的内容。
resource=flag.php转换到flag.php文件中,就是说把flag.php文件转换为base64编码格式。
因为$lan会自动拼接.php,并进行包含,所以我们不需要加.php后缀。