xss原理利用及修复

注:本文仅供参考学习

什么是xss?
XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS;
这是一种将恶意JavaScript代码插入到其他WEB用户页面里执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能,在HTML页面里嵌入恶意代码。当用户浏览该页面时,这些嵌入在HTML中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的,如COOKIE窃取、账户劫持、拒绝服务攻击等。
简单来说XSS攻击可以理解为html注入!与sql注入不同的是,sql注入是针对数据库,而xss则是针对html(包括xss和js)

xss的分类
反射型
反射性的xss是非持久的,是不经过后端不存进数据库的,利用起来比较困难,需要诱惑受害者点击链接,比较鸡肋.(dom型也属于反射)
存储型
存储型的xss是持久的,经过后端存进数据库,比较好利用。只要存在存储型xss,每个访问这个网页的用户都会触发。

xss的危害
对受害者可能采用cookie资料窃取 回话劫持 钓鱼欺骗等攻击手段、
强制弹出广告页面 刷流量
网页挂马(可看上篇文章)
提升用户权限 进一步渗透网站
传播跨站脚本蠕虫等

xss的简单利用
值得一提的是,浏览器有个防护xss的策略
叫做X-XSS-Protection
当浏览器检测到可能加载了恶意脚本会拦截
可以在返回包中添加X-XSS-Protection:0绕过

X-XSS-Protection:0 关闭
X-XSS-Protection:1 开启
X-XSS-Protection:1;mode=block
启用XSS过滤。 如果检测到攻击,浏览器将不会清除页面,而是阻止页面加载。
X-XSS-Protection:1; report=  (Chromium only)
启用XSS过滤。 如果检测到跨站脚本攻击,浏览器将清除页面并使用CSP report-uri指令的功能发送违规报告。

关于闭合的话,跟sql注入那个闭合一样,闭合前面的语句,是为了执行我们想要的语句,推荐一个payload

'">

如何绕过过滤
首先尝试大小写
特殊字符
各种事件
特殊编码
当过滤某个标签可以进行编码尝试绕过 假如eval函数应用

xss盲打实验
xss盲打就是将可能出现xss的地方都插上xss平台上的语句(用来获取cookie后台等敏感信息)
这里我将xss语句都插进去

xss原理利用及修复_第1张图片

模拟管理员登录后台

xss原理利用及修复_第2张图片

发现成功打到管理员后台
获取cookie等敏感信息

xss原理利用及修复_第3张图片

值得注意的是当启动httponly的时候是打不到的

常见过滤

绕过魔术引号
绕过 magic_quotes_gpc,magic_quotes_gpc=ON是php中的安全设置,开启后会把一些特殊字符进行轮换,比如'(单引号)转换为\',"(双引号)转换为\" ,\转换为\\
比如:会转换为,这样我们的xss就不生效了。
针对开启了magic_quotes_gpc的网站,我们可以通过javascript中的String.fromCharCode方法来绕过,我们可以把alert("XSS");转换为
String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41)那么我们的XSS语句就变成了 
String.fromCharCode()是javascript中的字符串方法,用来把ASCII转换为字符串。
最后使用包含即可。

Hex编码
比如: 可以转换为:
%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%22%78%73%73%22%29%3b%3c%2f%73%63%72%69%70%74%3e

存储型XSS的攻防
限制输入长度
在Input标签里面加上maxlength属性
限制输入长度

但攻击者可以从f12修改
或者抓包

对script过滤
使用nickname

$nickname = str_replace("script", "", @$_POST['nickname']);//昵称

Str_replace()把script替换为空
但可以大小写绕过
因为Js是不区分大小写的 所以脚本正常执行

使用str_ireplace()函数进行不区分大小写地过滤script关键字

$nickname = str_ireplace("script", "", @$_POST['nickname']);//昵称

strireplace()函数类似于上面的strreplace(),但是它不区分大小写。
但可以双写script绕过
原理就是str_ireplace()函数只找出了中间的script关键字,前面的S和后面的cript组合在一起,构成了新的Script关键字。

使用preg_replace()函数进行正则表达式过滤script关键字

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//昵称

可以用img标签的onerror标签

过滤alert关键字

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//昵称$nickname = preg_replace( "(.*)a(.*)l(.*)e(.*)r(.*)t/i", "", $nickname);//昵称

但能通过编码绕过
字符编码:十进制、十六进制ASCII码或unicode 字符编码,样式为“数值;”, 例如“j”可以编码为“j”或“j”
上述代码解码之后如下:

a

你能明显感觉到限制:由于使用到了a标签,所以只有点击时,才会弹框。
作为一个大黑阔,我们当然是不满意的,能不能让所有进入这个页面的人都弹框?
当然可以了:用iframe标签编码