HTML注入-反射型URL
查看服务器端源代码时,其中重点关注的有两处
1 <div id="main"> 2 3 <h1>HTML Injection - Reflected (URL)h1> 4 5 php echo "Your current URL: " . $url . "
";?> 6 7 div>
这段代码中有一段PHP代码,执行html语句,输出一段“Your current URL:”字符,在文本中左对齐,并调用$url变量,将输出的内容跟在后面。
防御代码:
1 php 2 include("security.php"); 3 include("security_level_check.php"); 4 include("functions_external.php"); 5 include("selections.php"); 6 7 $url= ""; 8 switch($_COOKIE["security_level"]) 9 { 10 case "0" : 11 // $url = "http://" . $_SERVER["HTTP_HOST"] . urldecode($_SERVER["REQUEST_URI"]); 12 $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]; 13 break; 14 case "1" : 15 $url = ""; 16 break; 17 case "2" : 18 $url = "http://" . $_SERVER["HTTP_HOST"] . xss_check_3($_SERVER["REQUEST_URI"]); 19 break; 20 default : 21 // $url = "http://" . $_SERVER["HTTP_HOST"] . urldecode($_SERVER["REQUEST_URI"]); 22 $url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]; 23 break; 24 } 25 ?>
1 <select name="security_level"> 2 3 <option value="0">lowoption> 4 <option value="1">mediumoption> 5 <option value="2">highoption> 6 7 select>
阅读防御代码可以了解到根据设置的难度不同,调用的防御代码与不同。
当将等级设置为low时,执行
$url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
其中“$_SERVER["HTTP_HOST"]”表示获取当前域名,与之功能相似的还有一个是$_SERVER['SERVER_NAME']
当满足以下3个条件的时候,两者会输出相同的信息
A、服务器端口号为80
B、Apache中的conf中的ServerName设置正确
C、HTTP/1.1协议规范
不同点
A、$_SERVER['HTTP_HOST']:在HTTP/1.1协议下,会根据客户端的HTTP请求输出信息;
$_SERVER['SERVER_NAME']:默认情况下会直接输出Apache的配置文件httpd.conf中的ServerName的值
B、当服务器的端口号不是80时
$_SERVER['HTTP_HOST']会输出端口号,例如“www.funwall.cn:8080”
$_SERVER['SERVER_NAME']直接输出ServerName的值,例如“www.funwall.cn”
在这种情况下,可以理解成HTTP_HOST = SERVER_NAME:SERVRE_PORT
C、当配置文件httpd.conf中的ServerName与HTTP/1.0下的域名不一致的时候,假如httpd.conf配置如下:
ServerName funwall.cn
ServerAlias www.funwall.cn
客户端访问域名:www.funwall.cn
$_SERVER[HTTP_HOST]输出:www.funwall.cn
$_SERVER[SERVER_NAME]输出:funwall.cn
因此,在实际中应该用$_SERVER[HTTP_HOST]获取域名比较保险。
而“$_SERVER["REQUEST_URI"]”是获取域名后面的完整的地址路径。
在level low下,通过抓包改包,修改host参数,可以发现主页上回显会有相应的改变。
当将等级设置为medium时,执行
$url = "";
这里document对象 -- 代表整个HTML 文档,可用来访问页面中的所有元素;
document.URL是 设置URL属性从而在同一窗口打开另一网页;
document.write() 是动态向页面写入内容。
此时再通过前面的方式抓包改包,已经不起作用了。
在low和medium等级下,是没有做任何防护的,都是直接获取url然后将其直接输出,可以在连接中添加代码实现弹框,这里是ie禁用了部分js脚本,导致了弹框失败。
在high等级下,执行
$url = "http://" . $_SERVER["HTTP_HOST"] . xss_check_3($_SERVER["REQUEST_URI"]);
其中调用了xss_check_3函数对host后面的部分进行了过滤处理,使得无法进行注入。