劫持与注入,怎么有种涩涩的感觉。确实,好多时候被攻击都是跟好色有关。当然,好色并不是罪,但即便好色也得注意上网环境的安全。
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中, 并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。 这是一种比较low的手段,却屡试不爽。
核心关键词:视觉欺骗,诱惑按钮,网站牛皮癣。
比如说,我给你在网页上显示一张小姐姐图片。作为直男看了很开心,就会去点。这时就中计了。
<style>
iframe {
width: 800px;
height: 300px;
position: absolute;
top: -0px;
left: -0px;
z-index: 2;
-moz-opacity: 0;
opacity: 0;
filter: alpha(opacity=0);
}
button {
position: absolute;
top: 281px;
left: 323px;
z-index: 1;
}
</style>
<button>最新动态</button>
<img src="pic.jpg">
<iframe src="http://localhost:3000" scrolling="no"></iframe>
从代码上来看,诱惑的实现简单的令人发指。就是在小姐姐图片上加一层透明的iframe,把透明通道打开后,就看到这个隐藏的内容了
小姐姐最新动态的fake按钮将和黑客想要你点击的按钮重合。就会和
作为前端,总是很自然地把浏览器当成自己的对手,但实际上,浏览器是我们的朋友。X-FRAME-OPTIONS 是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。
该响应头有三个值可选,分别是:
在nodejs相应的设置是:
ctx.set('X-FRAME-OPTIONS', 'DENY')
除此之外,如果浏览器版本太low,前端也有手段防范点击劫持。且见以下代码:
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>
self是对当前窗口自身的引用。top返回顶层窗口。即浏览器窗口。如果你的网页嵌套了iframe,就直接不显示了。
现在除了正常的前后端脚本安全问题,网络请求劫持的发生也越来越频繁。网络劫持一般指网站资源请求在请求过程中因为人为的攻击导致没有加载到预期的资源内容。网络请求劫持目前主要分为两种:DNS劫持与HTTP劫持。下面具体看看两种方式各是什么样的。
DNS劫持DNS劫持通常是指攻击者劫持了DNS服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致用户对该域名地址的访问由原IP地址转入到修改后的指定IP地址的现象,其结果就是让正确的网址不能解析或被解析指向另一网站IP,实现获取用户资料或者破坏原有网站正常服务的目的。DNS劫持一般通过篡改DNS服务器上的域名解析记录,来返回给用户一个错误的DNS查询结果实现。
DNS劫持症状可能为在某些地区的用户在成功连接宽带网络后,访问域名为www.a.com的网站,出现的却是www.b.com网站的内容,因为DNS服务器www.a.com域名的解析结果被修改指向了www.b.com网站指向的IP地址。
http劫持很常见:比如你在某些场合(比如星巴克。访问任何链接,都要事先经过登录)的网络打开打开百度时:右下角出现广告。或者你的混合app出现了很严重的广告信息。
HTTP劫持:在用户浏览器与访问的目的服务器之间所建立的网络数据传输通道中从网关或防火墙层上监视特定数据信息,当满足一定的条件时,就会在正常的数据包中插入或修改成为攻击者设计的网络数据包(比如js文件),目的是让用户浏览器解释“错误”的数据,或者以弹出新窗口的形式在使用者浏览器界面上展示宣传性广告或者直接显示某块其他的内容。
如图所示,这种情况下一般用户请求源网站的IP地址及网站加载的内容和脚本都是正确的,但是在网站内容请求返回的过程中,可能被ISP(InternetServiceProvider,互联网服务提供商)劫持修改,最终在浏览器页面上添加显示一些广告等内容信息。对于这些情况,网站开发者常常就无法通过修改网站代码程序等手段来进行防范了。请求劫持唯一可行的预防方法就是尽量使用HTTPS协议来访问目标网站。
举例来说,我开了一家餐厅,正常情况下,最多可以容纳30个人同时进餐。你直接走进餐厅,找一张桌子坐下点餐,马上就可以吃到东西。 很不幸,我得罪了一个流氓。他派出300个人同时涌进餐厅。这些人看上去跟正常的顾客一样,每个都说占据着位置喊着马上要上菜。但是,餐厅的容量只有30个人,根本不可能同时满足这么多的点餐需求,加上他们把门口都堵死了,里三层外三层,正常用餐的客人根本进不来,实际上就把餐厅瘫痪了。 ——http://www.ruanyifeng.com/blog/2018/06/ddos.html 阮一峰
DDOS 里面的 DOS 是 denial of service(停止服务)的缩写,表示这种攻击的目的,就是使得服务中断。最前面的那个 D 是 distributed (分布式),表示攻击不是来自一个地方,而是来自四面八方,因此更难防。你关了前门,他从后门进来;你关了后门,他从窗口跳起来。
它不是一种单独的攻击,而是一大类攻击的总称。
它有几十种类型,新的攻击方法还在不断发明出来。网站运行的各 个环节,都可以是攻击目标。只要把一个环节攻破,使得整个流程跑不起来,就达到了瘫痪服务的目的。
其中,比较常见的一种攻击是 cc 攻击。它就是简单粗暴地送来大量正常的请求,超出服务器的最大承受量,导致 宕机。比如:通过全世界大概20多个 IP 地址轮流发出请求,每个地址的请求量在每秒200 次~300次。
SYN Flood :此攻击通过向目标发送具有欺骗性源IP地址的大量TCP“初始连接请求”SYN数据包来利用TCP握手。目标机器 响应每个连接请求,然后等待握手中的最后一步,这一步从未发生过,耗尽了进程中的目标资源。
HTTP Flood :此攻击类似于同时在多个不同计算机上反复按Web浏览器中的刷新 - 大量HTTP请求泛滥服务器,导致拒绝服务。
怎么防御呢?
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符曝露出的,这类表单特别容易受到SQL注入式攻击.
看以下例子:
一个登录页面,用户表里存在一个名字为laowang
,明文密码为111111
的记录,你在密码框填入特殊密码
'1'or'1'='1'
然后奇迹般登录了。看看后端代码,发现这里是个查询语句:
# 拼接后的SQL
SELECT *
FROM test.user
WHERE username = 用户名 AND password = 你的明文密码
当我填入特殊密码时,sql语句变成了
// 填入特殊密码
// 拼接后的SQL
SELECT *
FROM test.user
WHERE username = 'laowang' AND password = '1'or'1'='1'
1固然不正确,但1=1永真。因此检索时一定可以检索出,因此可以登录成功!
怎么解决?也许有人说储存时加密是一个解决方法。其实是错误的。
如果你是储存时加密,那么一定也会出现上述问题。
最正派的解决手段是:所有的查询语句使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参数。
// 错误示范
const sql = `
SELECT *
FROM test.user
WHERE username = '${ctx.request.body.username}'
AND password = '${ctx.request.body.password}'
`
console.log('sql', sql)
res = await query(sql)
// 正确的写法
const sql = ` SELECT *
FROM test.user WHERE username = ? AND password = ?
`
console.log('sql', sql, )
res = await query(sql,[ctx.request.body.username, ctx.request.body.password])
'"=\<>&*;
等OS命令注入和SQL注入差不多,只不过SQL注入是针对数据库的,而OS命令注入是针对操作系统的。OS命令注入攻击指通过Web应用,执行非法的操作系统命令达到攻击的目的。只要在能调用Shell函数的地方就有存在被攻击的风险。倘若调用Shell时存在疏漏,就可以执行插入的非法命令。
以一段 Node.js 为例,假如业务需求是在接口中需要从 github 下载用户指定的 repo:
const exec = require('mz/child_process').exec;
let params = {/* 用户输入的参数 */};
exec(`git clone ${params.repo} /some/path`);
那么输入参数是:
https://github.com/xx/xx.git && rm -rf /* &&
那就呵呵了。
防御的思想和sql注入差不多,就是所有的拼接字符串添加检测!