题目给到源码

<?php 
$ip = isset($_POST['ip'])?$_POST['ip']:die();
if(!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/i',$ip)){
die("ip 格式错误!");
}
echo strlen($ip);
if(strlen($ip)<7||strlen($ip)>21){
die("ip 长度错误!");
}
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' .$ip );
}else {
// *nix
$cmd = shell_exec( 'ping -c 1 ' .$ip );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
## 要求,利用命令执行getshell

正则匹配的时候,仅仅匹配了点旁边的1-3位数字,且为限定​​&​​结束匹配字符串

因此只要构造一个以正常形式 ip 开头的参数即可

然后在这个正常的 ip 之后利用管道或者逻辑运算就可以执行任意命令

payload:

ip=1.1.1.1 || ls

得到flag文件名,直接访问即可。


管道符:

1.&

Usage:第一条命令 & 第二条命令 [& 第三条命令…]

用这种方法可以同时执行多条命令,而不管命令是否执行成功

2.&&

Usage:第一条命令 && 第二条命令 [&& 第三条命令…]

用这种方法可以同时执行多条命令,当碰到执行出错的命令后将不执行后面的命令,如果一直没有出错则一直执行完所有命令;

3.||

Usage:第一条命令 || 第二条命令 [|| 第三条命令…]

用这种方法可以同时执行多条命令,当碰到执行正确的命令后将不执行后面的命令,如果没有出现正确的命令则一直执行完所有命令;

4.|

Usage:第一条命令 | 第二条命令 [| 第三条命令…]

将第一条命令的结果作为第二条命令的参数来使用,记得在unix中这种方式很常见。