Web 攻击常见攻击⽅式及防范⽅案
Web攻击(WebAttack)是针对⽤户上⽹⾏为或⽹站服务器等设备进⾏攻击的⾏为,如植⼊恶意代码,修改⽹站权限,获取⽹站⽤户隐私信息等等,Web应⽤程序的安全性是任何基于Web业务的重要组成部分确保Web应⽤程序安全⼗分重要,即使是代码中很⼩的 bug 也有可能导致隐私信息被泄露站点安全就是为保护站点不受未授权的访问、使⽤、修改和破坏⽽采取的⾏为或实践。
1.XSS 跨站脚本攻击 (Cross Site Scripting)
Precise Security近期的⼀项研究表明,跨站脚本攻击是最为常见的⼀类⽹络攻击。但尽管最为常见,⼤部分跨站脚本攻击却不是特别⾼端,多为业余⽹络罪犯使⽤别⼈编写的脚本发起的。
跨站脚本针对的是⽹站的⽤户,⽽不是Web应⽤本⾝。恶意⿊客在有漏洞的⽹站⾥注⼊⼀段代码,然后⽹站访客执⾏这段代码。此类代码可以⼊侵⽤户账户,激活⽊马程序,或者修改⽹站内容,诱骗⽤户给出私⼈信息。
设置Web应⽤防⽕墙(WAF)可以保护⽹站不受跨站脚本攻击危害。WAF就像个过滤器,能够识别并阻⽌对⽹站的恶意请求。购买⽹站托管服务的时候,Web托管公司通常已经为你的⽹站部署了WAF,但你⾃⼰仍然可以再设⼀个。XSS,允许攻击者将恶意代码植⼊到提供给其它⽤户使⽤的页⾯中 XSS涉及到
三⽅: 攻击者、客户端与Web应⽤ XSS的 攻击⽬标:盗取存储在客户端的cookie或者其他⽹站⽤于识别客户端⾝份的敏感信息。
通过恶意js脚本获取 Cookie 信息,然后通过ajax加上CORS功能将数据发送给恶意服务器,恶意服务器拿到⽤户的 Cookie 信息之后,就可以模拟⽤户的登录,然后进⾏账户操作。
监听⽤户⾏为通过恶意js脚本,可以做到监听⽤户各种事件,⽐如获取登陆的键⼊字符串完成hack⽤户信息。
更改DOM结构
⽐较常见的就是通过运营商或者路由器添加浮窗⼴告,增收⾃⾝收⼊。
举个例⼦:
⼀个搜索页⾯,根据url参数决定关键词的内容
这⾥看似并没有问题,但是如果不按套路出牌呢?⽤户输⼊"><script>alert('XSS');</script>,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:浏览器⽆法分辨出 <script>alert('XSS');</script> 是恶意代码,因⽽将其执⾏,试想⼀下,如果是获取cookie发送对⿊客服务器呢?根据攻击的来源,XSS攻击可以分成:
1.1 存储型 XSS 的攻击:
攻击者将恶意代码提交到⽬标⽹站的数据库中,⽤户打开⽬标⽹站时,⽹站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器⽤户浏览器接收到响应后解析执⾏,混在其中的恶意代码也被执⾏
恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作这种攻击常见于带有⽤户保存数据的⽹站功能,如论坛发帖、商品评论、⽤户私信等
1.2反射型 XSS 的攻击:<input type="text" value="<%= getParameter("keyword") %>"><button>搜索</button><div> 您搜索的关键词是:<%= getParameter("keyword") %></div>
1
2
3
4
5<input type="text" value=""><script>alert('XSS');</script>"><button>搜索</button><div> 您搜索的关键词是:"><script>alert('XSS');</script></div>
1
2
3
4
5
攻击者构造出特殊的 URL,其中包含恶意代码,⽤户打开带有恶意代码的 URL 时,⽹站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。⽤户浏览器接收到响应后解析执⾏,混在其中的恶意代码也被执⾏,恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作,反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库⾥,反射型 XSS 的恶意代码存在 URL ⾥。反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如⽹站搜索、跳转等。由于需要⽤户主动打开恶意的 URL 才能⽣效,攻击者往往会结合多种⼿段诱导⽤户点击。POST 的内容也可以触发反射型 XSS,只不过其触发条件⽐较苛刻(需要构造表单
提交页⾯,并引导⽤户点击),所以⾮常少见
1.3DOM 型 XSS 的攻击:
攻击者构造出特殊的 URL,其中包含恶意代码,⽤户打开带有恶意代码的 URL,⽤户浏览器接收到响应后解析执⾏,前端 JavaScript 取出 URL 中的恶意代码并执⾏,恶意代码窃取⽤户数据并发送到攻击者的⽹站,或者冒充⽤户的⾏为,调⽤⽬标⽹站接⼝执⾏攻击者指定的操作。DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执⾏恶意代码由浏览器端完成,属于前端 JavaScript ⾃⾝的安全漏洞,⽽其他两种 XSS 都属于服务端的安全漏洞XSS的预防 通过前⾯介绍,看到XSS攻击的两⼤要素:
攻击者提交⽽恶意代码 解决⽅案: 存储型和反射型XSS都是服务器没有严格检测⽤户输⼊数据,即不能相信⽤户的任何输⼊。通过给⽤户输⼊做过滤,例如将⽤户输⼊:<script src='xxx'></script>转码,成<scriptscr='xxx'></script>,这样浏览器的DOM 解析器就不能运⾏恶意脚本。对于基于DOM的XSS攻击,使⽤HTTPS进⾏传输html,可以避免中间⼈能更改html⽂件。充分利⽤CSP,严格实施CSP操作,可以有效防范XSS攻击。使⽤ HttpOnly 属性。避免js脚本操作cookie,即使页⾯被注⼊了恶意JavaScript 脚本,也是⽆法获取到设置了 HttpOnly 的数据。因此⼀些⽐较重要的数据我们建议设置 HttpOnly 标志。
浏览器执⾏恶意代码 解决⽅案: 充分利⽤ CSP,严格实施CSP操作,可以有效防范XSS攻击。 限制加载其他域下的资源⽂件,这样即使⿊客插⼊了⼀个 JavaScript ⽂件,这个 JavaScript ⽂件也是⽆法被加载的;禁⽌向第三⽅域提交数据,这样⽤户数据也不会外泄;禁⽌执⾏内联脚本和未授权的脚本;还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。
2.CSRF 跨站请求伪造(Cross-site request forgery )
攻击者诱导受害者进⼊第三⽅⽹站,在第三⽅⽹站中,向被攻击⽹站发送跨站请求
利⽤受害者在被攻击⽹站已经获取的注册凭证,绕过后台的⽤户验证,达到冒充⽤户对被攻击的⽹站执⾏某项操作的⽬
⼀个典型的CSRF攻击有着如下的流程:
受害者登录a,并保留了登录凭证(Cookie)
攻击者引诱受害者访问了b
b 向 a 发送了⼀个请求:a/act=xx。浏览器会默认携带a的Cookie
a接收到请求后,对请求进⾏验证,并确认是受害者的凭证,误以为是受害者⾃⼰发送的请求
a以受害者的名义执⾏了act=xx
攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a执⾏了⾃⼰定义的操作
csrf可以通过get请求,即通过访问img的页⾯后,浏览器⾃动访问⽬标地址,发送请求
同样,也可以设置⼀个⾃动提交的表单发送post请求,如下:
访问该页⾯后,表单会⾃动提交,相当于模拟⽤户完成了⼀次POST操作
还有⼀种为使⽤a标签的,需要⽤户点击链接才会触发
访问该页⾯后,表单会⾃动提交,相当于模拟⽤户完成了⼀次POST操作<form action="ample/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /></form><script> document.forms[0].submit(); </script>
1
2
34
5
6<a href="test/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!!<a/>
1
2
3
CSRF的特点
攻击⼀般发起在第三⽅⽹站,⽽不是被攻击的⽹站。被攻击的⽹站⽆法防⽌攻击发⽣。
攻击利⽤受害者在被攻击⽹站的登录凭证,冒充受害者提交操作;⽽不是直接窃取数据。
整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒⽤”。
跨站请求可以⽤各种⽅式:图⽚URL、超链接、CORS、Form提交等等。部分请求⽅式可以直接嵌⼊在第三⽅论坛、⽂章中,难以进⾏追踪。
CSRF的预防 CSRF通常从第三⽅⽹站发起,被攻击的⽹站⽆法防⽌攻击发⽣,只能通过增强⾃⼰⽹站针对CSRF的防护能⼒来提升安全性 解决⽅案:
阻⽌不明外域的访问
提交时要求附加本域才能获取的信息
CSRF Token
⽤户打开页⾯的时候,服务器需要给这个⽤户⽣成⼀个Token, 对于GET请求,Token将附在请求地址之后。 对于 POST 请求来说,要在
form 的最后加上<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
当⽤户从客户端得到了Token,再次提交给服务器的时候,服务器需要判断Token的有效性
双重Cookie验证
3.SQL注⼊攻击
开放Web应⽤安全项⽬(OWASP)新出炉的⼗⼤应⽤安全风险研究中,注⼊漏洞被列为⽹站最⾼风险因素。SQL注⼊⽅法是⽹络罪犯最常⽤的注⼊⼿法。
注⼊攻击⽅法直接针对⽹站和服务器的数据库。执⾏时,攻击者注⼊⼀段能够揭⽰隐藏数据和⽤户输⼊的代码,获得数据修改权限,全⾯俘获应⽤。
保护⽹站不受注⼊攻击危害,主要落实到代码库构建上。⽐如说,缓解SQL注⼊风险的⾸选⽅法就是始终尽量采⽤参数化语句。更进⼀步,可以考虑使⽤第三⽅⾝份验证⼯作流来外包你的数据库防护。
Sql 注⼊攻击,是通过将恶意的 Sql查询或添加语句插⼊到应⽤的输⼊参数中,再在后台 Sql服务器上解析执⾏进⾏的攻击
解决⽅案:
确认每种数据的类型,⽐如是数字,数据库则必须使⽤int类型来存储过滤参数中含有的⼀些数据库关键词(如 or、union、)
规定数据长度,能在⼀定程度上防⽌sql注⼊
严格限制数据库权限,能最⼤程度减少sql注⼊的危害
避免直接响应⼀些sql异常信息,sql发⽣异常后,⾃定义异常进⾏响应对访问数据库的Web应⽤程序采⽤Web应⽤防⽕墙
4. 标题⽹络钓鱼
⽹络钓鱼是另⼀种没有直接针对⽹站的攻击⽅法,但我们不能将它排除在名单之外,因为⽹络钓鱼也会破坏你系统的完整性。根据FBI《互联⽹犯罪报告》的说法,其原因在于⽹络钓鱼是最常见的社会⼯程⽹络犯罪。
⽹络钓鱼攻击⽤到的标准⼯具就是电⼦邮件。攻击者通常会伪装成其他⼈,诱骗受害者给出敏感信息或执⾏银⾏转账。此类攻击可以是古怪的419(属于预付费欺诈类),或者涉及假冒电⼦邮件地址、貌似真实的⽹站和极具说服⼒⽤语的⾼端攻击。后者以鱼叉式⽹络钓鱼之名⼴为⼈知。
缓解⽹络钓鱼风险最有效的办法,是培训员⼯和⾃⾝,增强对此类欺诈的辨识能⼒。保持警惕,总是检查发送者电⼦邮件地址是否合法,邮件内容是否古怪,请求是否不合常理。另外,谨记:天上不会掉馅饼,事出反常必有妖。@Component public class SqlInjectionFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)servletRequest; HttpServletRequest res=(HttpServletRequest)servletResponse; //获得所有请求参数名 Enumeration params = ParameterNames(); String sql = ""; while (params.hasMoreElements()) { // 得到参数名 String name = Element().toString(); // 得到参数对应值 String[] value = ParameterValues(name); for (int i = 0; i < value.length; i++) { sql = sql + value[i]; } } if (sqlValidate(sql)) { throw new IOException("您发送请求中的参数中含有⾮法字符"); } else { chain.doFilter(servletRequest,servletResponse); } } /** * 关键词校验 * @param str * @return */ protected static boolean sqlValidate(String str) { // 统⼀转为⼩写 str = LowerCase(); // 过滤掉的sql 关键字,可以⼿动添加 String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" + "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +
"table|from|grant|use|group_concat|column_name|" + "lumns|table_schema|union|where|select|delete|update|order|by|count|*|" + "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#"; String[] badStrs = badStr.split("\\|"); for (int i = 0; i < badStrs.length; i++) { if (str.indexOf(badStrs[i]) >= 0) { return true; } } return false; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
xp提交更改39
40
41
42
43
44
45
46
47
48
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论