服务器渗透测试练习(插曲1:关于服务器对script标签的屏蔽)
#0:写在之前
我们之前在发掘漏洞的时候,找到了允许解析并执行script标签的漏洞,这里小小的谈一下关于这个的屏蔽方法。
#1:直接禁止有script字样出现
<!doctype html>
<html> <head> <meta charset="utf-8"> <title>login</title> <style>body{text-align: center}</style> <script> function check(){ if(document.frm.in.value.match("<script>")){ alert("出现script标签!"); return false; } else{ alert("没有出现script标签。"); return false; } }</script> </head> <body> <form method="post" name="frm" action=""> 输入: <br> <input type="text" name="in"> <br> <br> <input type="submit" name="sub" value="确定" onClick="return check()"> </form> </body> </html>
很明显,只需要把script大写就可以规避检测(浏览器解析HTML标签是不区分大小写的),那么,有没有什么可以更全面的检测方法呢?
只需要把原先的if语句的条件改为
toString(document.frm.in.value).toLowerCase().match("<script>")
将输入全部强制转换为小写,就可以规避所有的script标签了。
#2:去掉script标签
但是,有些网站并不希望用户看到一个因为输入中出现script标签就弹出的提示,他们更希望能够不动声色地处理掉script标签,那么可以
<!doctype html> <html> <head> <meta charset="utf-8"> <title>login</title> <style>body{text-align: center}</style> <script> function check(){ if(toString(document.frm.in.value).toLowerCase().match("<script>")){
var a=toString(document.frm.in.value).toLowerCase().replace("<script>","");
} else{
var a=toString(document.frm.in.value); } console.log(a); } </script> </head> <body> <form method="post" name="frm" action=""> 输入: <br> <input type="text" name="in"> <br> <br> <input type="submit" name="sub" value="确定" onClick="return check()"> </form> </body> </html>
但是,这个方法有两个不好的地方,第一个是用户输入都会被转换为小写,第二个是只能查找一次,如果输入是这个样子
<sCri<script>pt>alert("hey!")</scRi</script>pt>
那么在查找之后就还会剩下script标签,等于什么都没做。
第二个问题很简单,只需要把原本的script部分改为
function check(){ while(toString(document.frm.in.value).toLowerCase().match("<script>")){ var a=toString(document.frm.in.value).toLowerCase().replace("<script>",""); } console.log(a);
就可以循环检查直到没有script标签为止。那么就只剩下第一个问题需要解决了。其实很简单,把script从小写到大写的全部可能的排列方式都列出来,然后挨着进行循环检查,就可以解决这个问题,但是效率太低了(script共6个字母,每个字母有大写和小写两种情况,总共就是2^6=64种可能性,如果嵌套三层script标签,最少检查3次,最多192次,延迟会有点多,性能也不好。就有点类似与密码破解时使用的穷举法,把所有的情况全部列出,这种方法肯定不会高效),那么有没有更简单的方法呢?
目前为止,我还没有想到(如果有想法可以在评论区留言或私信我)。
#3:其他情况
上面两个问题算是解决了,但是,不是只有script标签才能执行代码,比如下面这些
<IMG SRC=http://*/*.js/> <IMG SRC=javascript:alert('XSS')> <INPUT SRC="javascript:alert('XSS');"> <img src="null.jpg" alt="" onerror="javascript:alert('error');"> <IMG DYNSRC="javascript:alert('XSS')"> <IMG LOWSRC="javascript:alert('XSS')"> <LINK REL="stylesheet" HREF="javascript:alert('XSS');"> <IMG SRC='vbscript:msgbox("XSS")'> <IFRAME SRC="javascript:alert('XSS');"></IFRAME> <TABLE BACKGROUND="javascript:alert('XSS')"></TABLE> <DIV STYLE="background-image: url(javascript:alert('XSS'))"></DIV>
<DIV STYLE="width: expression_r(alert('XSS'));"></DIV>
<SCRIPT>document.write("<SCRI");</SCRIPT>PT SRC="http://*/*.js"></SCRIPT>//这个是另一种调用方法,但是只适用于只检测一次的情况
还有很多方式,这里就不一一举例了,那么,对于这些该怎么办呢?
其实只需要参照之前的方法,检测是否有相应的一些字样,然后去掉就行了,说起简单,但是会让网站的性能大打折扣,所以没有什么网站会把大把的时间花在处理非法字符上,所以大多数的情况是,用htmlspecialchars()函数(PHP)进行原样输出,或者别的操作。但是在不能原样输出的情况下,我们就有机可乘,因为网站不太可能考虑到所有的情况。
提前更新是因为今天有时间,原定计划不变(可能吧,因为3月6日周六校长请优生吃饭,我收到了邀请,所以不知道有没有时间更新,但是我尽力)。像这样的插曲会不时出现,主要是为了讲一些在主进程中没有详细说明的东西,所以是不定时出现的。
等着下次更新吧(开学之后都没什么时间了嘤嘤嘤)。

浙公网安备 33010602011771号