ctfshow 利用create_function函数,并绕过base64编码
highlight_file(__FILE__); error_reporting(0); extract($_GET); create_function($name,base64_encode($value))();
这里我被迷惑了好久
刚开始的时候觉得extract和create_function这两个函数最可疑,
这里的意思是extract()函数(传进来的必须是数组)来处理$_GET传入的参数,我起初一直在由于为什么,我传入的是value,name而不是value[],name[]为什么可以呢,是我太无知了
原来,在 PHP 中,$_GET 是一个超全局变量,用于获取通过 HTTP GET 方法传递的参数。当用户通过 URL 向服务器发送 GET 请求时,URL 中的参数会被解析并存储在 $_GET 数组中。
$_GET 是一个关联数组,其中的键表示 URL 中的参数名,而对应的值则是该参数的值。它本身就是个关联数组,所以我传进去的参数就是这个数组的元素,而经过extract函数的处理是这些元素都变成对应名称的变量。这就豁然开朗了
接下来就是,create_function函数
在这里create_function($name,base64_encode($value))();是一个匿名函数,我们可以把当成这样的函数
nmp(我们自定义的函数名,这是将匿名实例化),这个create_function的用法就是前面一个变量是函数的形参,后面的一整体(记得是整体,而是后面一个单独的变量)是整个这个函数的执行体(也是方法)
那这里我们就可以看出
nmp($name){
base64_encode($value)
}
就是这样一个函数,然后我们进行传参,这里还有一个知识点就是要绕过base64,起初我一直在纠结的是base64指针对大小写字母,数字,+,/这64个字符,然后我一直在想通配符,感觉就很麻烦
看了别人的方法才豁然开朗,原来是可以直接通过闭合来绕过的
假如我name传入的是){}system('ls \');/*的话,那带入就应该是
nmp(){}system('ls \');/*){
base64_encode($value)
}
nmp(){}//空函数体
system('ls \');
/*){
base64_encode($value)
}这样就成功绕过了
ctfshow之利用ini_set设置报错日志,利用%00或\000来截断system致使其报错
highlight_file(__FILE__); error_reporting(2); extract($_GET); ini_set($name,$value); system( "ls '".filter($_GET[1])."'" ); function filter($cmd){ $cmd = str_replace("'","",$cmd); $cmd = str_replace("\\","",$cmd); $cmd = str_replace("`","",$cmd); $cmd = str_replace("$","",$cmd); return $cmd; }
这里用了extract函数用于将传入的数组,把数组元素变成相应的变量
这里还有一个ini_set($name,$value);函数
这里用来通过$_GET传参进来的name和value来设置php.ini
然后system(
"ls '".filter($_GET[1])."'"
);
这里的filter是自定义函数,过滤了',\\,`,$
拿道这道题目的时候我是毫无头绪的,就多传入了一个?1=/,然后知道flag应该就再/flag里面
传入1=/usr/local/lib/php/extensions(是php扩展一个常见的默认安装目录)列出 /usr/local/lib/php/extensions/ 目录下的文件和子目录。
no-debug-non-zts-20180731 文件(其实是标识,20180731是特定版本,用于区别不同版本的php扩展库)
那就看看这个路径下有哪些扩展,1=/usr/local/lib/php/extensions/no-debug-non-zts-20180731
有个xdebug.so扩展,
利用:xdebug在处理截断问题的时候,会将异常payload回显
现在就要先从ini_set($name,$value);函数这里思考了, 我们可以利用ini_set函数来暂时修改php.ini中的PHP配置 ,其中这里可以利用的方法是PHP error_log记录日志,这里的name和value是我们可控的, 可以控制PHP配置文件的error_log及其错误日志的写入文件 , xdebug在处理截断问题的时候,会将异常payload回显 ,system可以用0字节(%00和\000)来进行截断
这里可以构造payload:?name=error_log&value=/var/www/html/2.php&1=%00<?php system('cat /flag');?>
因为前面我已经猜测flag 可能再/flag里面
成功写入
访问2.php