服务器渗透测试练习(插曲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日周六校长请优生吃饭,我收到了邀请,所以不知道有没有时间更新,但是我尽力)。像这样的插曲会不时出现,主要是为了讲一些在主进程中没有详细说明的东西,所以是不定时出现的。

等着下次更新吧(开学之后都没什么时间了嘤嘤嘤)。

posted @ 2021-03-04 22:17  awcyvan  阅读(198)  评论(0)    收藏  举报