数据来源
部分数据来源:ChatGPT
命令执行简介
01 命令执行漏洞产生原因
命令执行漏洞的产生原因主要是输入验证不严格、代码逻辑错误、应用程序或系统中缺少安全机制等。攻击者可以通过构造特定的输入向应用程序或系统注入恶意代码,从而在受攻击的主机上执行任意命令。
具体来说,以下是一些产生命令执行漏洞的常见原因:
-
输入参数没有进行充分过滤和验证,使得攻击者可以往其中注入命令执行语句。
-
应用程序或系统中使用了不安全的API和库函数,使得攻击者能够构造可执行代码的语句。
-
没有抵御脚本注入攻击的有效措施(比如跨站脚本攻击),导致攻击者能够通过此类攻击向目标输入特殊字符和各种恶意代码。
-
程序或系统对外部命令的调用机制不完善,以至于攻击者可以利用该机制进行命令执行攻击。
-
系统环境变量被污染,使得攻击者针对性地构造命令引起非预期的行为发生。
-
代码实现者可能出于某些原因误坎了发布设计缺陷的代码,经轻松后门构造,导致了命令执行漏洞。
因此,在进行应用程序或系统开发时,应该特别注意输入验证与过滤、代码逻辑和架构安全、外部调用机制的安全性和足够防御脚本注入攻击的保护措施。
02 命令执行漏洞的危害
命令执行漏洞带来的危害非常大,因为攻击者可以通过此类漏洞对应用程序或系统进行远程代码执行攻击,从而实现窃取、修改、破坏、控制目标系统等攻击行为。
具体来说,以下是一些常见的命令执行漏洞危害:
-
数据泄露:攻击者可以利用漏洞执行命令,获取机密信息、用户个人数据和敏感系统凭证等敏感信息。
-
恶意软件感染:攻击者可以通过注入恶意代码感染企业系统,如插入木马病毒、勒索软件和挖矿蠕虫等恶意软件。
-
远程控制: 攻击者可以通过命令执行漏洞获取对受害者计算机的远程控制权限,执行各种指令,包括文件操作、网络操作、启停服务、在目标主机上部署后门等。
-
服务器挂掉/瘫痪:由于可执行任意命令且没有限制,攻击者可以向目标服务器发送大量恶意请求,导致服务器崩溃,停止服务,从而造成巨大经济损失。
综上所述,命令执行漏洞带来的危害不可忽视。要避免这种漏洞,应该加强代码审查、输入校验和过滤、熟悉系统中可用API的安全约束以及采取其他防御措施。
03 远程代码执行
远程代码执行(Remote Code Execution, RCE)漏洞通常是由于开发者在编写应用程序或系统时没有充分考虑安全性而导致的。
以下是一些可能导致远程代码执行漏洞的原因:
-
未经严格验证的用户传输数据:如果应用程序或系统没有对用户输入的数据进行适当的验证和过滤,攻击者就可以在这些输入中注入恶意代码,并通过远程代码执行 exploit 执行其控制的命令。
-
不正确的访问控制:如果应用程序或系统没有正确地实现访问控制机制,那么攻击者就可能通过受控的请求来利用应用程序内部权限,导致远程代码执行漏洞。例如,攻击者可能会访问受限于管理用户权限的接口并注入恶意代码。
-
缺少输入/输出过滤:当应用程序或系统缺少必要的输入/输出过滤时,攻击者就可以借此注入特定的操作指令,这些操作指令可能未被完全验证并未加以过滤而导致了RCE 漏洞。
-
没有保护机制:如果在应用程序或系统中没有实施足够保护机制,攻击者就可以使用攻击载荷以及不正确的系统配置,从而获取远程执行代码的权限。这通常是由于应用程序或系统较旧,已过时并未得到维护的原因。
总之,为了避免远程代码执行漏洞的发生,请开发团队仔细审核所有应用程序及其接口,并确保在编写代码时考虑必要的安全措施和输入校验。
1)远程代码执行- eval函数
eval()函数的使用可能会导致远程代码执行(RCE)漏洞,被黑客利用的原因在于该函数可动态地将字符串解析为 JavaScript 代码,并在当前上下文中执行。这意味着攻击者可以构造恶意字符串并传递给 eval() 函数来进行攻击,从而绕过所有访问权限检查和安全控制,实现从远程位置对目标服务器执行任意代码的代码注入攻击。黑客甚至可以通过提交文件或直接开放端口等方式从系统内部远离控制整个应用程序。
例如,一个网站可能允许用户通过 URL 获取信息。如果未能正确验证用户输入并使用 eval() 来运行脚本,则攻击者可以发送包含恶意代码的请求,生效后,该代码就会被自动执行;从而使黑客能够从远程位置获取非法授权访问,以及无限制地运行任何可能危及主机的任何程序。由此可见,eval()如果不合理使用,会更大增加系统漏洞产生的概率,不仅在 web 应用程序中,在其他语言环境下也同样存在相似漏洞潜在风险。
因此,为避免 eval() 导致 RCE 漏洞风险,程序员必须小心谨慎地使用该函数并对应用程序进行仔细的代码审计和测试,对用户输入和数据处理进行严格验证,以避免恶意代码注入和攻击。
2)远程代码执行 - assert函数
assert()函数是一种用于执行断言测试的PHP函数。在 PHP 中,assert() 是一个非常强大的函数,因为它允许程序员动态地执行代码,并以此来比较某些条件或检查许多系统的状态。但如果不恰当使用,则可能导致严重漏洞,特别是远程代码执行攻击(RCE) 。
黑客可能利用assert()函数中的漏洞来实现RCE攻击,其主要原理是将用户输入直接传给assert()函数进行检测。当应用程序未正确过滤和验证用户提供的输入时,黑客可以通过构造具有攻击性代码的输入,从而成功执行任意代码并获取服务器控制权。
例如,一个网站允许用户上传一个 PHP 文件作为个人资料照片,没有正确的对文件内容进行校验,那么,一个黑客可隐藏着可执行恶意代码从而达到 RCE 的目的。当管理员看到该照片时,assert()函数会在传递相应照片的 filename 属性时动态地执行这部分代码,这样就突破了页面的访问限制并使得黑客进入受害端的代码库。
为避免这种安全漏洞对于 PHP 程序员来说,应始终对所有传递给 assert() 函数的数据进行验证和过滤,并防止 PHP 代码中存在任何可预测或不安全的断言测试。 同时,合理应用 PHP 内置安全函数库的方法和常规开发优化等基本安全意识也更有必要。
3)远程代码执行 - preg_replace函数
preg_replace()函数是PHP中一个用于对字符串执行正则表达式搜索和替换的函数,它既强大又灵活。然而,如果未恰当使用 preg_replace() 函数,则可能产生安全漏洞,特别是远程代码执行(RCE)攻击风险。
黑客会利用 preg_replace() 函数的某些特性,如模式修饰符 /e 、 eval 替换等等,来实现RCE攻击。例如,黑客可以创建由含有 PHP 代码的字符串,并将其提交到带有 preg_replace() 函数的表单中。如果输入验证不充分并且未提供足够的过滤,语句会将黑客的字符串放入到执行上下文中,从而执行任意 PHP 代码。这就给黑客提供了许多方式可利用用户提供的数据来执行任意代码,甚至可能导致服务器被远程接管。
为避免此类问题发生,应该始终通过与预期的输入匹配的参数化查询来处理动态构建的查询,使用过滤器函数来确保数据类型的正确性,并剥离潜在的危险组成部分,特别针对所有 preg_replace() 调用做好输入数据验证和过滤。还需要仔细阅读 PHP 文档,深入研究 preg_replace() 的工作原理,以及其存在哪些安全隐患,并避免在代码中使用 /e 标志或其他可执行替换的特性,以减少漏洞被利用的可能性。
利用示例:
在php的www目录下创建一个preg_replace.php文件,内容如下:
<?php preg_replace("/test/e",$_POST["cmd"],"just test");?>
可以使用菜刀连接或浏览器的插件Hackbar执行
C刀连接
4)远程代码执行- array_map函数
array_map()函数是 PHP 中的一项功能较强大的函数,用于对数组中的所有元素按照相同的方式进行操作。尽管其本身并不直接提供远程代码执行(RCE)攻击的风险,但如果未正确使用,则可能会产生安全隐患。
黑客通常可利用 array_map() 函数类似 eval 一样运行用户可控制的代码的特性来实现 RCE 攻击。例如,黑客通过应用程序提交构造的PHP代码作为函数,最终将恶意脚本编译到函数体的某个位置以进行攻击。这就意味着,当该函数被调用时,攻击者的代码将执行,再次使得黑客可以获取服务器的访问权限。
为避免此类问题发生,需要在处理动态构建函数时采取严格的输入验证和数据过滤。 最好的方法是在不需要任意代码执行的情况下禁止 arrmap_map() 的使用,并利用其他可靠工具和安全库实现类似功能, 如foreach等语句等。在任何情况下也应该避免使用用户可操作或可控制的数据来创建函数或处理HTML模板等事务,防止黑客利用已知漏洞引导代码来获取服务器访问权限。
5)远程代码执行 - create_function函数
create_function()函数是 PHP 中的一个内置函数,用于创建一个新的匿名函数并返回该函数的名称。这使得可以将函数当作一种数据类型进行操作并将其传递给其他函数。尽管在某些情况下很有用,但如果未正确使用,则可能产生安全隐患,特别是远程代码执行(RCE)攻击。
黑客经常会利用 create_function() 函数的漏洞实现远程代码执行。
例子:
$inputCode = 'var_dump(phpinfo());';
$func=create_function('', $inputCode); $func();
变量 $inputCode 采用了用户输入,这就为黑客提供了可控制参数和生成自由形式的PHP代码的机会,而不是直接编写新函数来实现相同的功能。黑客使用可控制的 eval() 或 preg_replace() 等正则表达式函数等建立新的代码字符串,并通过 create_function() 来溢出shell执行上下文范畴,从而能够运行恶意代码。
为了避免此类问题,最好在编写您的代码时完全避免使用create_function()函数。因为现有的PHP版本中已删除此功能,这可大大减少了黑客攻击的空间。如果确实需要动态地构造新的PHP代码,应该改用受信任的框架和库提供的支持工具,如lambda或闭包,以及过滤和验证所有用户输入,并堆栈溢出等漏洞进行正确管理。最大限度地降低压力,保证代码执行过程的安全性和可靠性,提高应用程序面对攻击的韧性。
6)远程代码执行- caLL_user_func函数
call_user_func()函数是 PHP 中的一个内置函数,用于将函数作为参数传递并调用它。尽管其本身没有直接提供远程代码执行(RCE)攻击的风险,但如果未正确使用,则可能会产生安全隐患。
黑客可以利用 call_user_func() 函数可接受用户控制参数的特性来实现 RCE 攻击。例如,黑客利用漏洞动态构建payload并在该函数中执行恶意代码
例子:
$inputCode = 'phpinfo();'; // 攻击者可能控制的输入参数
call_user_func($inputCode); // 调用 call_user_func() 执行 $inputCode 中的 PHP 代码
变量 $inputCode 采用了用户输入,这就使得攻击者可以完全控制该参数,并向其中注入任意 PHP 代码,并最终使其被执行,从而令黑客可能获取服务器访问权限。
为避免此类问题发生,建议在处理函数参数时采取严格的输入验证和过滤,并且不要允许调用任何用户定义或不受信任的数据集合,对于某些特殊情况,可以通过使用强类型声明、检查参数数量等技巧来限制启用基础类型第三方库等缺省PHP特性风险。
另外,也可通过简化应用程序中的函数调用层次结构以及减少通过回调式编程方式使用 call_user_func() 来缓解这种风险,从而加强您的应用程序对远程执行攻击(RCE)的韧性。
这里推荐一个软件utools
我们可以用这个软件下载一些插件或文档,如我这里下载一个php的文档遇到不认识的php代码就可以搜索一下,就不用上百度搜索。
7)远程代码执行- array_filter函数
array_filter() 是 PHP 内置函数之一,用于从给定的数组中过滤出符合条件的元素并返回一个新的数组。它本身并不是远程代码执行(RCE)攻击的矢量,但是在处理回调函数参数时如果未正确使用,则可能会存在安全风险。
例如,如果开发者将用户输入作为 array_filter() 函数中的回调函数参数,并且该输入未经过充分验证和过滤,则黑客可以通过注入恶意回调函数来实现远程执行代码攻击。
下面是一个具有潜在 RCE 风险的示例:
$userInput = ' ; phpinfo();'; // 接受用户输入的回调函数
$myArray = ['apple', 'banana', 'cherry'];
$result = array_filter($myArray, $userInput); // 将 $userInput 作为回调函数参数传递
在这个例子中,由于 $userInput 字符串中包含了可执行的 PHP 代码,所以当它被传递给 array_filter() 函数时,恶意代码可以被执行,并可能导致服务器被黑客接管。
要避免此类问题,请始终对从外部来源到应用程序中的所有数据进行严格的输入验证和过滤。您还应确保仅将可信任的回调函数传递到带有 array_filter() 的 PHP 函数中,并尽可能使用匿名函数或其他减少代码复杂度的方式来代替直接回调函数。
示例:
www目录下创建一个文件,内容如下:
<?php
$cmd=$_POST['cmd']; // 接收一个post参数
$array1=array($cmd); // 把传入的post参数cmd转换为数组(array_filter接收的就是数组类型)
$func =$_GET['func']; // 接收要执行的操作函数
array_filter($array1,$func);
// 用回调函数过滤数组中的元素:array-filter(数组,函数)
// ?func=system
//cmd=whoam
?>
访问:http://127.0.0.1/array-filter.php?func=system
8)远程代码执行- 双引号
在 PHP 中,双引号字符串是一种特殊的字符串类型,它允许将变量或表达式插入到字符串中,并解析为其对应的值。如果双引号字符串包含用户输入或其他不受信任的数据,则可能会存在远程代码执行(RCE)攻击的风险。
例如,如果程序中使用了 eval() 函数对一个动态构建的包含双引号字符串进行求值,那么攻击者可以构造一个恶意字符串,其中包含可执行的PHP 代码,并成功获取服务器及其中相关敏感信息。
下面是一个具有潜在 RCE 风险的示例:
$userInput = '"; phpinfo(); //'; // 包含可执行代码的输入
$myString = "Hello, $userInput";
eval("echo $myString;");
在这个例子中,由于用户输入的 $userInput 字符串被放置在带双引号的字符串中,而 eval() 函数又能够执行传递给它的任意代码,因此当 $myString 被传递到 eval() 中并被解析时,其中的恶意代码也将得以执行,导致应用程序和服务器面临着被黑客接管的危险。
为避免此类问题,请确保在处理应用程序与用户之间的数据交互时,要对所有从外部来源到应用程序中的数据都进行输入验证和过滤,尽可能避免使用 eval() 函数,减少在程序中直接插入带双引号的字符串的使用,以及限制用户可以输入的字符类型和长度等。
04 远程系统命令执行
远程系统命令执行(Remote Code Execution,RCE)攻击是因为应用程序开发者在编写代码的过程中没有充分考虑安全性和防御措施,导致攻击者可以利用漏洞来执行任意命令,例如获取敏感信息、删除或篡改文件、控制服务器等。
RCE攻击的一种常见的原因是未对用户输入进行充分的验证和过滤。当应用程序接受来自用户的数据,包括表单提交、Cookie、HTTP 请求参数等,在不经过严格验证和过滤时将它们插入到shell命令等语句中,攻击者可以通过构造特定的输入来注入恶意代码,并执行任意系统命令。
1)远程系统命令执行- exec函数
在 PHP 中,exec() 函数是一个常用的执行系统命令的函数。攻击者可能利用 exec() 函数构造恶意输入来执行任意系统命令,实现远程系统命令执行(Remote Code Execution,RCE)攻击。
当 exec() 函数中包含用户输入或其他不受信任的数据且未经过充分验证和过滤时,攻击者可以构造特定的输入来注入可执行的系统命令,并利用服务器上的权限,从而控制该服务器、窃取敏感信息或者破坏服务器上的数据。
例如,假设存在以下代码:
$userInput = 'some user input'; // 这是用户输入
$cmd = 'ls -la ' . $userInput;
$result = exec($cmd);
在这个例子中,由于程序未对 $userInput 参数进行有效的过滤和验证,攻击者可以通过引入 shell 控制字符来注入可执行的系统命令, 并使 $cmd 变量直接从用户控制的输入字符串中构建而成。因此攻击者可以构造如下可以执行删除根目录下所有文件的命令:
$userInput = '; rm -rf /';
$cmd = 'ls -la ' . $userInput;
$result = exec($cmd);
为避免此类问题,请始终对从外部来源到应用程序中的所有数据进行严格的输入验证和过滤,并尽可能避免直接在应用程序中执行不可信的系统命令。相反,您应该考虑使用安全性更高的 API 函数来替换 exec(),例如 shell_exec、system、passthru 等,并始终在调用这些函数之前进行充分的数据验证和过滤,以确保用户输入仅包含预期的数据。
利用示例:
在php的www目录下创建一个exec.php文件,内容如下:
<?php $cmd=$_POST['cmd'];@exec($cmd,$return); // 执行$cmd,并把结果给数组$returnvar_dump($return) // 输出$return
?>
访问:http://127.0.0.1/exec.php
执行的结果和在命令行中运行时一样的
2)远程系统命令执行- system函数
在 PHP 中,system() 函数是一个常用的执行系统命令的函数。攻击者可能利用 system() 函数构造恶意输入来执行任意系统命令,实现远程系统命令执行(Remote Code Execution,RCE)攻击。
当 system() 函数中包含用户输入或其他不受信任的数据且未经过充分验证和过滤时,攻击者可以构造特定的输入来注入可执行的系统命令,并利用服务器上的权限,从而控制该服务器、窃取敏感信息或者破坏服务器上的数据。
例如,假设存在以下代码:
$userInput = 'some user input'; // 这是用户输入
$cmd = 'ls -la ' . $userInput;
$result = system($cmd);
在这个例子中,由于程序未对 $userInput 参数进行有效的过滤和验证,攻击者可以通过引入 shell 控制字符来注入可执行的系统命令, 并使 $cmd 变量直接从用户控制的输入字符串中构建而成。因此攻击者可以构造如下可以执行删除根目录下所有文件的命令:
$userInput = '; rm -rf /';
$cmd = 'ls -la ' . $userInput;
$result = system($cmd);
为避免此类问题,请始终对从外部来源到应用程序中的所有数据进行严格的输入验证和过滤,并尽可能避免直接在应用程序中执行不可信的系统命令。相反,您应该考虑使用安全性更高的 API 函数来替换 system(),例如 shell_exec、exec、passthru 等,并始终在调用这些函数之前进行充分的数据验证和过滤,以确保用户输入仅包含预期的数据。
3)远程系统命令执行- passthru函数
在 PHP 中,passthru() 函数是一个常用的执行系统命令的函数。攻击者可能利用 passthru() 函数构造恶意输入来执行任意系统命令,实现远程系统命令执行(Remote Code Execution,RCE)攻击。
当 passthru() 函数中包含用户输入或其他不受信任的数据且未经过充分验证和过滤时,攻击者可以构造特定的输入来注入可执行的系统命令,并利用服务器上的权限,从而控制该服务器、窃取敏感信息或者破坏服务器上的数据。
例如,假设存在以下代码:
$userInput = 'some user input'; // 这是用户输入
$cmd = 'ls -la ' . $userInput;
passthru($cmd);
在这个例子中,由于程序未对 $userInput 参数进行有效的过滤和验证,攻击者可以通过引入 shell 控制字符来注入可执行的系统命令,并使 $cmd 变量直接从用户控制的输入字符串中构建而成。因此攻击者可以构造如下可以执行删除根目录下所有文件的命令:
$userInput = '; rm -rf /';
$cmd = 'ls -la ' . $userInput;
passthru($cmd);
为避免此类问题,请始终对从外部来源到应用程序中的所有数据进行严格的输入验证和过滤,并尽可能避免直接在应用程序中执行不可信的系统命令。相反,您应该考虑使用安全性更高的 API 函数来替换 passthru(),例如 shell_exec、exec、system 等,并始终在调用这些函数之前进行充分的数据验证和过滤,以确保用户输入仅包含预期的数据。
示例:
在php的www目录下创建一个passthru.php文件,内容如下:
<?php$output = passthru("ipconfig"); // ipconfig是windows的系统命令,意思是查看ip地址。echo "<pre>$output</pre>";
?>
访问:http://127.0.0.1/passthru.php
4)远程系统命令执行- shell_exec函数
在 PHP 中,shell_exec() 函数是一个常用的执行系统命令的函数。攻击者可能利用 shell_exec() 函数构造恶意输入来执行任意系统命令,实现远程系统命令执行(Remote Code Execution,RCE)攻击。
当 shell_exec() 函数中包含用户输入或其他不受信任的数据且未经过充分验证和过滤时,攻击者可以构造特定的输入来注入可执行的系统命令,并利用服务器上的权限,从而控制该服务器、窃取敏感信息或者破坏服务器上的数据。
例如,假设存在以下代码:
$userInput = 'some user input'; // 这是用户输入
$cmd = 'ls -la ' . $userInput;
$result = shell_exec($cmd);
在这个例子中,由于程序未对 $userInput 参数进行有效的过滤和验证,攻击者可以通过引入 shell 控制字符来注入可执行的系统命令,并使 $cmd 变量直接从用户控制的输入字符串中构建而成。因此攻击者可以构造如下可以执行删除根目录下所有文件的命令:
$userInput = '; rm -rf /';
$cmd = 'ls -la ' . $userInput;
$result = shell_exec($cmd);
为避免此类问题,请始终对从外部来源到应用程序中的所有数据进行严格的输入验证和过滤,并尽可能避免直接在应用程序中执行不可信的系统命令。相反,您应该考虑使用安全性更高的 API 函数来替换 shell_exec(),例如 exec、system、passthru 等,并始终在调用这些函数之前进行充分的数据验证和过滤,以确保用户输入仅包含预期的数据。
命令执行常用特殊字符
在命令执行中,攻击者可能会使用特殊字符来注入可执行的系统命令,进而实现远程系统命令执行(Remote Code Execution,RCE)攻击。
以下是一些常用的特殊字符:
;
(分号):在 Linux 中,分号分隔符用于将多个命令组合在一起执行;在 Windows 中,分号被用于分隔环境变量。&
(与号):在 Linux 中,可以使用 “&” 运算符将一个程序置于后台运行;在 Windows 中,“&” 被用于连接不同的命令。|
(管道符):管道符将第一个命令的输出作为第二个命令的输入,可以在命令行中进行高级数据处理。$
(美元符):美元符是 shell 脚本中的变量前缀,将被替换为相应的变量值。(
和)
(括号):用于控制命令的执行顺序,类似于数学表达式中的括号。*
(星号)和?
(问号):用于匹配文件名或路径名中的通配符。因此,在处理用户输入时,请始终对特殊字符进行严格的过滤和验证,并尽可能限制对系统命令的访问权限以减少攻击面。
攻击者是如何利用的?
攻击者利用特殊字符来构造恶意输入,注入可执行的系统命令,从而实现远程系统命令执行(Remote Code Execution,RCE)攻击。
例如,在 PHP 中,如果程序在处理用户输入时没有进行充分的过滤和验证,攻击者就可能向程序输入以下恶意字符串:
; rm -rf /
在这种情况下,攻击者在原来的命令之后添加了一个分号,然后紧接着加上了一个用于删除文件的危险命令。当 PHP 程序执行这个命令时,攻击者的恶意代码也会一并被执行,导致服务器上的文件和目录被彻底删除,并可能造成不可估量的损失。
因此,在处理用户输入时,请始终对特殊字符进行严格的过滤和验证,并使用安全性更高的 API 函数来替换原始的命令执行函数,以避免因用户输入的恶意数据而给应用程序带来风险。
示例:(windows + R 输入cmd 打开命令行)
1)“|” :cmd1|cmd2 无论cmd1是否执行成功cmd2都会被执行
ping 127.0.0.1|ipconfig