命令注入是一种常见的技巧,用于实现远程代码执行(RCE)。命令注入发生在Web应用或服务接受用户输入并将其用于执行操作系统命令的场景中,如果用户输入未被妥善清理或验证,攻击者可以注入额外的命令,从而执行任意代码。
命令注入的过程:
在这个例子中,grep
命令将被test
字符串中断,然后执行whoami
命令,显示当前登录的用户名。
-
侦察:首先,参赛者需要找出Web应用或服务中可能接受用户输入并用于执行命令的部分,例如搜索框、表单字段、URL参数等。
-
发现漏洞:分析这些输入点,确定它们是否被直接用于执行命令。常见的迹象包括错误消息泄漏命令执行的细节,或者应用行为的异常变化。
-
构建payload:设计一个payload,即一个包含命令的字符串,该字符串可以被注入到正常输入中。payload可能包括分号(
;
)、管道符号(|
)或与命令行相关的其他特殊字符,用于分隔或修改原始命令。 -
注入payload:将payload注入到已识别的输入点中,通常需要对payload进行适当的编码或格式化,以绕过任何现有的过滤或转义机制。
-
执行命令:当payload被应用程序或服务处理时,注入的命令将被执行。这可能允许攻击者执行一系列操作,如读取文件、创建新文件、执行shell命令或甚至控制整个系统。
-
实例:假设一个Web应用有一个搜索功能,允许用户输入查询字符串,而该应用使用
grep
命令在服务器上搜索文件。如果输入未经清理直接用于命令中,攻击者可以注入额外的命令,例如:用户输入:test; whoami
结果命令:grep 'test; whoami' /path/to/files
当面对一个远程代码执行(RCE)挑战并且发现空格被过滤的情况时,你需要找到一种方法来绕过这种过滤,从而成功执行命令或代码。当Web应用或服务试图阻止命令注入攻击时,它们经常通过过滤空格来尝试阻止多词命令的构造。然而,有几种方法可以绕过这种过滤:
绕过过滤空格的方法:
-
使用替代分隔符:
- Linux/Unix系统中,可以使用分号(
;
)或管道符(|
)来代替空格分隔命令。例如,ls -l;pwd
或ls -l|wc -l
。
- Linux/Unix系统中,可以使用分号(
-
使用环境变量:
- 在Linux中,可以使用环境变量IFS(Internal Field Separator)来绕过空格过滤。例如,
echo ${IFS}2
相当于echo " "2
。
- 在Linux中,可以使用环境变量IFS(Internal Field Separator)来绕过空格过滤。例如,
-
使用特殊编码:
- URL编码(%20代表空格)
- Base64编码
- 十六进制编码(
\x20
)
-
使用注释:
- 在某些情况下,可以使用注释来“截断”命令,例如在PHP中,
<?php echo 'test'; //
可以被修改为<?php echo 'test'; // echo 'test2'
,其中echo 'test2'
被注释掉,但在某些情况下可能被解析器解析为命令的一部分。
- 在某些情况下,可以使用注释来“截断”命令,例如在PHP中,
-
使用多字节字符:
- 在某些编码中,多字节字符可以被解析为空格,例如在UTF-8中使用
\u0020
。
- 在某些编码中,多字节字符可以被解析为空格,例如在UTF-8中使用
-
使用字符编码:
- 在PHP中,可以使用
chr()
函数来生成特定的ASCII字符,如chr(32)
代表空格。
- 在PHP中,可以使用
-
使用字符串连接:
- 在某些语言中,可以使用字符串连接来构建命令,如在PHP中使用
'ls'.chr(32).'-l'
。
- 在某些语言中,可以使用字符串连接来构建命令,如在PHP中使用
-
利用漏洞或错误:
- 寻找Web应用的其他逻辑漏洞或错误,可能允许以非标准方式构造命令。
实例:
假设在PHP中,preg_match()
函数被用来过滤空格,但没有过滤其他字符,你可以尝试以下方法:
- 使用分号代替空格:
ls;pwd
- 使用IFS环境变量:
echo ${IFS}pwd
(在支持IFS的上下文中) - 使用URL编码:
ls%20-l
遇到涉及RCE(Remote Code Execution,远程代码执行)的题目,特别是涉及到远程文件包含(Remote File Inclusion,RFI)的情况,通常意味着目标应用程序存在一个漏洞,允许攻击者通过URL参数或其他输入向量远程加载并执行外部文件中的代码。这种类型的攻击特别常见于使用PHP编写的网站,因为PHP支持各种伪协议来读取本地或远程文件。
解决远程文件包含问题的一般步骤:
-
确认RFI的存在:
- 首先,你需要确认目标应用程序是否允许远程文件包含。这通常可以通过尝试在URL参数中输入一个已知的远程文件路径来完成,例如尝试加载一个简单的文本文件或者一个PHP文件,该文件只包含
<?php phpinfo(); ?>
这样的内容。
- 首先,你需要确认目标应用程序是否允许远程文件包含。这通常可以通过尝试在URL参数中输入一个已知的远程文件路径来完成,例如尝试加载一个简单的文本文件或者一个PHP文件,该文件只包含
-
了解限制:
- 确定应用程序是否对包含的文件类型或来源有任何限制。这可能包括白名单、黑名单、或者只允许包含特定类型的文件。
-
创建一个可控制的远程文件服务器:
- 在你自己的VPS或实验室环境中设置一个HTTP服务器,用于托管你想要让目标应用程序加载的恶意文件。
-
构建恶意文件:
- 创建一个PHP文件,该文件可以执行你想要的操作,如读取文件、执行命令等。确保该文件遵循目标应用程序的任何限制,比如文件扩展名。
-
触发RFI:
- 将你的恶意文件URL作为参数传递给目标应用程序,以触发远程文件包含。
-
读取FLAG或执行命令:
- 如果一切顺利,你的恶意文件会被目标应用程序加载并执行。你可以利用这一点来读取FLAG文件,或者执行其他命令来获取更多的信息或权限。
-
调试和迭代:
- 如果第一次尝试失败,检查错误日志,或者尝试使用不同的方法或技巧来绕过可能的防御措施。
具体技巧:
- 使用
php://filter
伪协议来绕过某些过滤。 - 利用
readfile()
,include()
,require()
,include_once()
,require_once()
等函数的特性。 - 尝试使用
data:
URI scheme 或其他伪协议,如phar://
。 - 如果应用程序使用
allow_url_fopen
选项,尝试直接通过URL读取文件。 - 注意字符编码和URL编码,这有时可以帮助绕过过滤。
利用php://input
流来进行远程代码执行(RCE)是一种高级技巧,通常在Web应用程序存在某些漏洞或不当配置时才有可能实现。php://input
是PHP中一个特殊的流,它允许脚本读取POST或PUT请求中的原始输入数据,这在某些情况下可以被恶意利用。
php://input
的特性:
php://input
流提供了对HTTP请求体中原始数据的访问。对于POST请求,它会返回请求体的全部内容。对于PUT或PATCH请求,它也会返回相应的方法体。php://input
只能被读取一次,这意味着如果它在一个脚本中被读取了一次,后续尝试读取它将会返回空字符串。
利用php://input
进行RCE:
-
发现漏洞:首先,你需要找到一个Web应用中的漏洞,这个漏洞允许用户输入的数据直接被包含或执行,而没有适当的清理或验证。这可能是一个文件包含漏洞,或者一个脚本直接使用用户提供的数据进行某些操作。
-
构造请求:然后,构造一个带有恶意数据的HTTP请求,通常是一个POST、PUT或PATCH请求。恶意数据将被放置在请求体中,旨在被
php://input
流读取。 -
注入恶意代码:恶意数据通常是一段PHP代码,被设计成能在被读取时执行。这可以是简单的命令执行,如
passthru('whoami');
,或者是更复杂的payload,如创建一个反向shell。 -
触发执行:发送构造好的请求,触发
php://input
流的读取。如果一切按计划进行,恶意代码将被执行,允许远程代码执行。
示例:
假设一个PHP脚本存在以下代码:
1$data = file_get_contents('php://input');
2echo $data;
攻击者可以构造如下请求:
1POST /vulnerable_script.php HTTP/1.1
2Host: example.com
3Content-Type: application/x-www-form-urlencoded
4
5<?php system('whoami'); ?>
当这个请求到达服务器时,php://input
将读取请求体中的PHP代码,并由于echo
语句的存在,尝试执行这段代码。如果脚本没有对php://input
的数据进行适当的清理或验证,那么system('whoami');
命令将被执行,泄露服务器的用户信息。
在CTF(Capture The Flag)竞赛中,读取源代码以实现远程代码执行(RCE)通常是指利用Web应用中存在的漏洞,如文件包含漏洞、路径遍历漏洞或命令注入漏洞,来访问和读取服务器上的源代码文件。读取源代码可以帮助参赛者理解应用的内部工作原理,找到其他潜在的漏洞,或者直接从源代码中读取FLAG。
利用路径遍历漏洞读取源代码:
路径遍历漏洞(也称为目录遍历漏洞)允许攻击者通过修改URL或表单中的文件路径参数,来访问Web服务器上本应限制访问的文件。例如,如果一个Web应用允许用户下载指定路径的图片,攻击者可以尝试使用../
序列来读取服务器上的其他文件,包括源代码文件。
示例:
假设Web应用中有一个功能允许用户下载图片,URL形如:
1http://example.com/download.php?file=images/pic1.jpg
如果存在路径遍历漏洞,攻击者可以尝试以下URL:
1http://example.com/download.php?file=../../../../etc/passwd
或
1http://example.com/download.php?file=../../../../var/www/html/index.php
这样就可能读取服务器上的敏感文件,包括源代码文件。
利用文件包含漏洞读取源代码:
文件包含漏洞(File Inclusion Vulnerability)允许攻击者通过URL参数或表单输入指定要包含的文件,这可能包括服务器上的任意文件,甚至是远程文件。如果应用使用include()
, require()
, include_once()
, require_once()
等函数,且未对参数进行适当的验证,攻击者可以读取源代码。
示例:
如果Web应用中有如下代码:
1$filename = $_GET['file'];
2include($filename);
攻击者可以尝试以下URL:
1http://example.com/vulnerable_page.php?file=../../../../var/www/html/index.php
利用命令注入读取源代码:
如果Web应用允许用户输入被直接用于执行命令,攻击者可以尝试注入命令来读取文件。例如,如果应用有如下代码:
1$command = "ls -la " . $_GET['dir'];
2system($command);
攻击者可以尝试以下URL:
1http://example.com/vulnerable_page.php?dir=.;/var/www/html
这将列出Web应用的目录结构,从中可能找到源代码文件。
阅读源代码的目的:
- 查找FLAG:源代码中可能直接包含FLAG。
- 发现漏洞:阅读源代码可以帮助识别其他潜在的安全漏洞。
- 理解逻辑:理解Web应用的内部逻辑有助于制定更有效的攻击策略。