常见的网络攻击原理
1.XSS
1.1什么是XSS攻击?
- XSS攻击:跨站脚本攻击。(重点在于脚本的执行)
- 原理:恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,因此会达到恶意攻击用户的目的。
- XSS攻击分类:反射型、存储型、及 DOM-based型。 反射性和DOM-baseed型可以归类为非持久性XSS攻击。存储型可以归类为持久性XSS攻击。
1.2.XSS攻击分类
1.2.1.反射型XSS
- 原理:反射性xss一般指攻击者通过特定的方式来诱惑受害者去访问一个包含恶意代码的URL。当受害者点击恶意链接url的时候,恶意代码会直接在受害者的主机上的浏览器执行。
- 特点:非持久性XSS,攻击方式只有一次性。
- 反射性攻击步骤:
- 攻击者在url后面的参数中加入恶意攻击代码。
- 用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中并且返回给浏览器端。
- 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。
- 攻击者通过恶意代码来窃取到用户数据并发送到攻击者的网站。攻击者会获取到比如cookie等信息,然后使用该信息来冒充合法用户
的行为,调用目标网站接口执行攻击等操作。
- 常见的反射性XSS有哪些?
- 常见的是:恶意链接。
1.2.2.存储型XSS
- 原理:将恶意代码上传或存储到服务器中,下次只要受害者浏览包含此恶意代码的页面就会执行恶意代码。
- 存储型XSS的攻击步骤如下:
- 攻击者将恶意代码提交到目标网站数据库中。
- 用户打开目标网站时,网站服务器将恶意代码从数据库中取出,然后拼接到html中返回给浏览器中。
- 用户浏览器接收到响应后解析执行,那么其中的恶意代码也会被执行。
- 那么恶意代码执行后,就能获取到用户数据,比如上面的cookie等信息,那么把该cookie发送到攻击者网站中,那么攻击者拿到该
cookie然后会冒充该用户的行为,调用目标网站接口等违法操作。
- 防范操作:
- 后端需要对提交的数据进行过滤。
- 前端也可以做一下处理方式,比如对script标签,将特殊字符替换成HTML编码这些等。
1.2.3.DOM-based型XSS
- **原理:**用户在客户端输入的数据包含了恶意的js脚本的话,但是这些脚本又没有做任何过滤处理的话,那么我们的应用程序就有可能受到DOM-based XSS的攻击。
- 攻击步骤:
- 攻击者构造出特殊的URL、在其中可能包含恶意代码。
- 用户打开带有恶意代码的URL。
- 用户浏览器收到响应后解析执行。前端使用js取出url中的恶意代码并执行。
- 执行时,恶意代码窃取用户数据并发送到攻击者的网站中,那么攻击者网站拿到这些数据去冒充用户的行为操作。调用目标网站接口
执行攻击者一些操作。
- 导致被攻击的操作有:
- 使用document.write直接输出导致浏览器解析恶意代码
- 使用innerHTML直接输出导致浏览器解析恶意代码
- 使用location/location.href/location.replace/iframe.src 造成的XSS
1.2.4.SQL注入
- 原理:SQL注入是通过客户端的输入把SQL命令注入到一个应用的数据库中,从而执行恶意的SQL语句。
- 被攻击原因:sql语句伪造参数,然后对参数进行拼接后形成xss攻击的sql语句。最后会导致数据库被攻击了。
- 防范的方法:
- 我们可以使用预编译语句(PreparedStatement,这样的话即使我们使用sql语句伪造成参数,到了服务端的时候,这个伪造sql语句的参数也只是简单的字符,并不能起到攻击的作用。
- 数据库中密码不应明文存储的,可以对密码使用md5进行加密,为了加大破解成本,所以可以采用加盐的方式。
1.3.XSS如何防范
1.3.1.cookie 安全策略
在服务端设置cookie的时候设置http-only,, 这样就可以防止用户通过JS获取cookie。
- http-only: 只允许http或https请求读取cookie、JS代码是无法读取cookie的(document.cookie会显示http-only的cookie项被自动过滤掉)。发送请求时自动发送cookie.
- secure-only: 只允许https请求读取,发送请求时自动发送cookie。
- host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie。
1.3.2.X-XSS-Protection设置
目前该属性被所有的主流浏览器默认开启XSS保护。
该参数是设置在响应头中目的是用来防范XSS攻击的。它有如下几种配置:
- 禁用XSS保护
- 启用XSS保护
- mode=block; 启用xss保护,并且在检查到XSS攻击是,停止渲染页面。
1.3.3.XSS防御HTML编码
我们为什么要防御HTML编码呢?比如如下html代码:
因此我们需要将不可信数据放入到html标签内(比如div、span等)的时候需要进行html编码。
编码规则:将 & < > " ’ / 转义为实体字符。
// 使用正则表达式实现html编码
function htmlEncodeByRegExp(str) {
var s = '';
if (str.length === 0) {
return s;
}
return (s + str)
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/ /g, " ")
.replace(/\'/g, "'")
.replace(/\"/g, """)
.replace(/\//g, '/');
}
1.3.4.XSS 防御HTML Attribute编码
和HTML编码一样,html中的属性也要进行编码,比如 <input name="name"/>这样的,name是input的属性,因此在html解析时,会对name属性进行编码,因为假如name"/>这样的,name是input的属性,因此在html解析时,会对name属性进行编码,因为假如{name} 的值为:" " onclick="alert('属性XSS')" " " 这样的,也就是说input变成这样的了,<input name=" " onclick="alert('属性XSS')" " "></input>,input属性name被插入onclick事件了,因此也需要针对这种常规的html属性,都需要对其进行HTML属性编码。
- 因此我们需要将不可信数据放入html属性时(不含src、href、style 和 事件处理函数(onclick, onmouseover等))。需要进行HTML Attribute 编码。
编码规则:除了字母、数字、字符以外,使用 &#x;16进制格式来转义ASCII值小于256所有的字符。
function encodeForHTMLAttibute(str) {
let encoded = '';
for(let i = 0; i < str.length; i++) {
let ch = hex = str[i];
if (!/[A-Za-z0-9]/.test(str[i]) && str.charCodeAt(i) < 256) {
hex = '&#x' + ch.charCodeAt(0).toString(16) + ';';
}
encoded += hex;
}
return encoded;
};
1.3.5.XSS防御之javascript编码
在上面的 XSS 防御HTML Attribute编码中我们是可以防御XSS攻击,但是它只能防御的是HTML通用属性,并不是全部属性,在html中还存在很多支持协议解析的html属性,比如 onclick, onerror, href, src 等这些,类似这些属性我们是无法通过HTML编码来防范XSS攻击的。因为浏览器会先解析html编码的字符,将其转换为该属性的值,但是该属性本身支持JS代码执行,因此游览器在HTML解码后,对该属性的值进行JS解析,因此会执行响应的代码。
1.3.6.XSS 防御之 URL 编码
- 作用范围:将不可信数据作为 URL 参数值时需要对参数进行 URL 编码
- 编码规则:将参数值进行 encodeURIComponent 编码
- 编码代码如下:
function encodeForURL(str){
return encodeURIComponent(str);
};
1.3.7.XSS 防御之 CSS 编码
- 作用范围:将不可信数据作为 CSS 时进行 CSS 编码
- 比如:通过css构造(background-img:url\expression\link-href@import)
<div style="background-image: url(javascript:alert('xss'));"></div>
<style>body{background-image: url("javascript:alert('xss')");}</style>
1.3.8.开启CSP网页安全政策防止XSS攻击
Content-Security-Policy 中文的意思是 网页安全政策.
主要用来防止XSS攻击。是一种由开发者定义的安全性政策申明,通过CSP所约束的责任指定可信的内容来源,通过 Content-Security-Policy 网页的开发者可以控制整个页面中 外部资源 的加载和执行。
可以控制哪些 域名下的静态资源可以被页面加载,哪些不能被加载。这样就可以很大程度的防范了 来自 跨站(域名不同) 的脚本攻击。
使用方法:
<meta http-equiv="Content-Security-Policy" content="">
2.CSRF
2.1.CSRF是什么?
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
2.2.CSRF可以做什么?
CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。
2.3.CSRF的原理
- 用户是网站A的注册用户,且登录进去,于是网站A就给用户下发cookie。
从上图可以看出,要完成一次CSRF攻击,受害者必须满足两个必要的条件:
(1)登录受信任网站A,并在本地生成Cookie。(如果用户没有登录网站A,那么网站B在诱导的时候,请求网站A的api接口时,会提示你登录)
(2)在不登出A的情况下,访问危险网站B(其实是利用了网站A的漏洞)。
我们在讲CSRF时,一定要把上面的两点说清楚。
温馨提示一下,cookie保证了用户可以处于登录状态,但网站B其实拿不到 cookie。
2.4.CSRF如何防御
Token 验证:(用的最多)
(1)服务器发送给客户端一个token;
(2)客户端提交的表单中带着这个token。
(3)如果这个 token 不合法,那么服务器拒绝这个请求。
隐藏令牌:
把 token 隐藏在 http 的 head头中。
方法二和方法一有点像,本质上没有太大区别,只是使用方式上有区别。
Referer 验证:
Referer 指的是页面请求来源。意思是,只接受本站的请求,服务器才做响应;如果不是,就拦截。
3.XSS和CSRF的区别
区别一:
CSRF:需要用户先登录网站A,获取 cookie。XSS:不需要登录。
区别二:(原理的区别)
CSRF:是利用网站A本身的漏洞,去请求网站A的api。XSS:是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容。
4.SSRF
SSRF(Server-Side Request Forgery:服务器端请求伪造)
**原理:**其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制。导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
4.1.漏洞的出现
漏洞出现点
- 分享:通过URL地址分享网页内容
- 转码服务
- 在线翻译
- 图片加载与下载:通过URL地址加载或下载图片
- 图片、文章收藏功能
- 未公开的api实现以及其他调用URL的功能
- 从URL关键字中寻找
4.2.防御方法
- 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
- 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
- 限制请求的端口为http常用的端口,比如,80,443,8080,8090。
- 黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
- 禁用不需要的协议。仅仅允许http和https请求。
5.CRLF
- CRLF是”回车 + 换行”(\r\n)的简称。
- 在HTTP协议中,HTTP Header与HTTP Body是用两个CRLF分隔的,浏览器就是根据这两个CRLF来取出HTTP 内容并显示出来。
- 所以,一旦我们能够控制HTTP 消息头中的字符,注入一些恶意的换行,这样我们就能注入一些会话Cookie或者HTML代码,所以CRLF Injection又叫HTTP Response Splitting,简称HRS。
5.1.案例
- Location 字段的 302 跳转
一般网站会在HTTP头中用 Location: http://www.baidu.com 这种方式来进行302跳转, 如果我们能控制 Location: 后面的某个网址的URL,就可以进行HRS攻击, 响应头首部中多了个Set-Cookie字段, 这就证实了该系统存在CRLF注入漏洞
输入正常URL
/?url=https://whoamianony.top获取正常302跳转数据包的响应头
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content- Type: text/html Content-Length: 154 Connection: close Location: https://whoamianony.top将输入的URL修改为
/?url=https://whoamianony.top%0d%0aSet-Cookie: PHPSESSID=whoami获取此时302跳转数据包的响应头
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content- Type: text/html Content-Length: 154 Connection: close Location: https://whoamianony.top%0d%0aSet-Cookie: PHPSESSID=whoami响应头变为
HTTP/1.1 302 Moved Temporarily Date: Fri, 27 Jun 2014 17:52:17 GMT Content- Type: text/html Content-Length: 154 Connection: close Location: https://whoamianony.top Set-Cookie: PHPSESSID=whoami
- Host头部注入
- User_Agent头部注入
- 发送POST数据包
漏洞修复
对 \r, \n之类的行结束符进行过滤
