03-xss攻防
xss学习可以步骤参考:https://www.cnblogs.com/tangtou/p/17281696.html
xss的构造
利用<>构造html/js关键字
这个之前已经学习过,在搜索框输入JS代码,就可以,还是用cms虚拟机,在本站搜索输入即可
<script>alert(/xss/)</script>
javascript伪协议
可以通过url载入资源的标签,不知道a标签可以看 html语言
<a href=javascript:alert(/xss/)>click me!</a>
产生自己的事件
事件是一种重要的编程思想
事件类型 | 说明 |
---|---|
window事件 | 对window对象触发的事件 |
form事件 | html表单内触发的事件 |
keyboard事件 | 键盘事件 |
mouse事件 | 鼠标事件 |
media事件 | 由多媒体触发的事件 |
把以下代码放在cms搜索框,会显示图片
<img src="http://192.168.2.133/html/style/img/smallcat.jpg" width="" height="99" border="0">
那么可以在img中插入onmouseover,就是鼠标悬停,触发xss,只要把鼠标放在上面就可以触发
<img
onmouseover = 'alert(/dont touch me!/)'
src="http://192.168.2.133/html/style/img/smallcat.jpg" width="" height="99" border="0">
<input type = 'text' onkeydown = 'alert(/xss/)'>
<input type = 'text' onkeyup = 'alert(/xss/)'>
onkeydown:按下按键触发,比如按下键盘不松手
onkeyup;抬起按键触发,松手键盘
XSS的变形
大小写绕过
已知虚拟机里面的cms搜索框存在XSS反射型漏洞,POC如下
<script>alert(/xss/)</script>
尝试站在代码角度,对xss漏洞进行修复,通过发现URL
http://192.168.2.133/cms/search.php?keywords=%3Cscript%3Ealert%28%2Fxss%2F%29%3C%2Fscript%3E&button=%E6%90%9C%E7%B4%A2
发现是把参数提交了search.php这个文件,进去这个文件后,先备份文件,再修改
主要对$_GET['keywords']
进行过滤
查找以下代码,$_GET是预定义超全局变量,参考PHP学习相关部分
这就是接收一个keywords参数,然后直接输出
把以上代码进行修改,增加一个$keywords
<?php
$keywords = @$_GET['keywords'];
echo $keywords;
增加完之后,输入搜索框内容,看命令还能不能正常工作,搜索框输入后,能正常显示搜索相关就没问题
这时候,对$keywords进行过滤,就是把<script>
替换掉,代码如下
<?php
$keywords = @$_GET['keywords'];
$keywords = str_replace("<script>","",$keywords);
echo $keywords;
?>
//str_replace是替换,他会搜索$keywords,把里面的<script>替换为空
这时候再去检索,没有xss弹窗,显示正常检索内容
但是浏览器对于html的大小写不敏感,通过查看网页源代码可以发现如下可能自己输入的<script>
消失了,可能被替换
所以将<script>
进行任意替换大写字母,比如替换为<sCRipt>alert(/xss/)</script>
发现又能弹窗,查看源代码如下,js代码被正确执行
所以要通过正则匹配,忽略大小写,preg_replace
本身是区分大写小的,要通过//i忽略大小写,然后通过\转义两边的尖尖,如下代码
<?php
$keywords = @$_GET['keywords'];
$keywords = preg_replace("/\<script\>/i","",$keywords);
echo $keywords;
?>
双写绕过
双写绕过的意思就是在<script>
中间再插入<script>
,这样中间的<script>
被过滤之后,外面的还能组成一个<script>
,如下代码,已久可以实现XSS攻击
<?php
$keywords = @$_GET['keywords'];
$keywords = preg_replace("/\<scr<script>ipt\>/i","",$keywords);
echo $keywords;
?>
那么,不论是大小写绕过,还是双写绕过,可以想办法做字符匹配,只要里面含有script,并且按照这个顺序,就会过滤掉,代码如下
其中.
表示匹配任意字符,*
表示匹配任意次数
<?php
$keywords = @$_GET['keywords'];
$keywords = preg_replace("/\<s(.*)c(.*)r(.*)i(.*)p(.*)t\>/i","",$keywords);
echo $keywords;
?>
为了避免误拦截,可以尝试把script倒过来输入<tpircs>
,在搜索框输入
<tpircs>alert(/dont /)</script>
结果如下
事件绕过
先尝试用事件绕过,比如用如下代码:
<input type = 'text' onkeydown = 'alert(/xss/)'>
可以正确弹窗,观察所有的事件都有on,可以处理on,把on替换为on_
,用如下代码进行过滤
$keywords = preg_replace("/on/i","on_",$keywords);
检查网页源代码,发现on已经被替换且页面无弹窗
伪协议转码
HTML编码:
字母 | ASCII码 | 十进制编码 | 十六进制编码 |
---|---|---|---|
a | 97 | a |
a |
c | 99 | c |
c |
e | 101 | e |
$#x65; |
如果采用如下编码,则无法进行过滤:
<a href=javascript:alert(/xss/)>click me!</a>
//原本代码为这个,对javascript进行十六进制编码
<a
href = 'javascript:alert(/xss/) '>click me!</a>
//该代码无法被过滤
htmlspecialchars
将特殊字符转换为普通字符
<?php
$keywords = @$_GET['keywords'];
$keywords = htmlspecialchars($keywords);
echo $keywords;
?>
最终就是搜索什么,显示什么
这个函数基本可以防御xss漏洞
如果想要完全防御,那可以参考DVWA里面的绝对防御
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
把xsschallenge放在www目录下面,最终目标就是让网站弹窗
下载地址:链接: https://pan.baidu.com/s/193DDfuoGxfNFjxcpsld02A?pwd=dugn 提取码: dugn
XSS漏洞防御
针对用户的输入进行过滤,以dvwa的command inject绝对防御为例,发现是检查点分十进制
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode( ".", $target );
// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
终极测试代码,只要提交就可以看到哪些被过滤,哪些转码,然后做针对性绕过
<sCr<ScRiPt>IPT>OonN'"\/(hrHRefEF)</sCr</ScRiPt>IPT>
至此跨站脚本攻击学习先告一段落。即将开始学习跨站请求伪造CSRF