代码执行与命令执行漏洞一览

代码执行&命令执行

代码执行

基础
  • 用户可以通过请求将代码注入到应用中最终到WebServer中执行

  • 当应用在调用一些能将字符转化为代码的函数(如PHP中的eval)时,
    没有考虑用户是否能控制这个字符串,这就会造成代码执行漏洞。

  • 引起的函数,过滤不严导致

    php:
    eval()
    assert()
    大多是因为载入缓存或者模板一级对变量的处理不严导致的,如直接把一个外部可控的参数拼接到模板里,然后调用这两个函数去当成PHP代码执行
    preg_replace()
    执行需要存在/e参数,参数是用来处理字符串的,多存在于URL,HTML标签一级文章内容等过滤功能
    call_user_func()
    call_user_func_array()
    多用在框架里动态调用函数
    array_map()
    调用并且除第一个参数外其他参数为数组
    Python:
    exec
    asp:
    <%=CreateObject(“wscript.shell”).exec(“cmd.exe /c ipconfig”).StdOut.ReadAll()%>
    Java:
    没有类似函数,但采用的反射机制和各种基于反射机制的表达式引擎(OGNL、SpEL、MVEL等)有类似功能测试代码
    
测试代码
  • eval&assert函数

    • 把字符串按照 PHP 代码来计算。

    • 动态执行代码,参数是php代码

      <?php
          $data = $_GET['data'];
          eval("\$ret = $data;");
          echo $ret;
      ?>
      

      在这里插入图片描述

  • preg_replace()

    • 执行一个正则表达式的搜索和替换。

    • 语法

      mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
      
      $pattern: 要搜索的模式,可以是字符串或一个字符串数组。
          e:
          设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线(\)和 NULL 字符在 后向引用替换时会被用反斜线转义.
      
      $replacement: 用于替换的字符串或字符串数组。
          replacement中可以包含后向引用\\n 或$n,语法上首选后者。 每个这样的引用将被匹配到的第n个捕获子组捕获到的文本替换。 n 可以是0-99,\\0和$0代表完整的模式匹配文本。 捕获子组的序号计数方式为:代表捕获子组的左括号从左到右, 从1开始数。如果要在replacement 中使用反斜线,必须使用4个("\\\\",译注:因为这首先是php的字符串,经过转义后,是两个,再经过 正则表达式引擎后才被认为是一个原文反斜线)。
      
      当在替换模式下工作并且后向引用后面紧跟着需要是另外一个数字(比如:在一个匹配模式后紧接着增加一个原文数字), 不能使用\\1这样的语法来描述后向引用。比如, \\11将会使preg_replace() 不能理解你希望的是一个\\1后向引用紧跟一个原文1,还是 一个\\11后向引用后面不跟任何东西。 这种情况下解决方案是使用${1}1。 这创建了一个独立的$1后向引用, 一个独立的原文1。
      
      $subject: 要搜索替换的目标字符串或字符串数组。
      
      $limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
      
      $count: 可选,为替换执行的次数。
      
      搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换,当pattern处即第一个参数存在e修饰符时,replacement的值会被当成PHP代码执行
      
      
    • 例子

      <?php 
      echo preg_replace("/test/e",$_GET["h"],"jutst test"); 
      ?> 
      

    在这里插入图片描述

    <?php
       preg_replace("/\[(.*)\]/e",'\\1',$_GET['str']);
    ?>
    意思是
    正则是从$_GET['str']中搜索[]中的内容作为第一次结果,preg_replace()函数第二个为\\1代表这里用第一次结果填充
    这里是直接执行代码
    
  • call_user_func()&array_map()等数十个函数有调用其他函数的功能

    其中一个参数作为要调用的函数名,若传入的参数名可控,则可以调用意外的函数来执行

    mixed call_user_func(callable $callback [,mixed $parameter [,mixed $...]])

    • 第一个参数为回调函数,后面的参数为回调函数的参数

    • 测试代码

      <?php
      $b="phpinfo()"
      call_user_func($_GET['a'],$b)
      ?>
      

    在这里插入图片描述

  • 同类型

    在这里插入图片描述

  • 动态函数执行

    • php函数可以直接由字符串拼接成

    • 写法

    • 利用

      <?php
      $_GET['a']($_GET['b']);
      ?>
      意思是
      接受GET请求的a参数,作为参数,b参数作为函数的参数。当请求参数为assert是,b的参数为phpinfo()
      

      在这里插入图片描述

防范
  • 白名单过滤

命令执行

  • 可以执行CMD或者bash命令

  • 可引起的函数

    system()
    exec()
    shell_exec()
    passthru()
    pcntl_exec()
    popen()
    popen_open()
    (`)反引号
    
    • pcntl_exec()

      • 函数说明
        void pcntl_exec(string $path [,array $args[,arry $envs]])
        KaTeX parse error: Expected 'EOF', got '#' at position 35: …ash脚本,则需要在文件头加上#̲!/bin/bash来标识路径…args标识传递给 p a t h 程 序 的 参 数 , path程序的参数, pathenvs则是执行这个程序的环境变量
    • popen(),popen_open()

      • 不会执行一个结果而是返回一个文件指针,但是命令已经执行了

      • 测试代码

        <?php
        popen('whoiam >>D:/1.txt','r');
        ?>
        

        执行完后在1.txt文件里就能看到用户名

    • 反引号命令

      • 实际上是调用的shell_exec()函数
防御
  • 防注入函数

    • escapeshellcmd()过滤一整条命令
    • escapshellarg()保障参数是以字符串参数形式存在,不能被注入
  • 白名单

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值