XSS跨站脚本攻击
概要
1、反射型XSS
浏览器信息提交后,服务端没有做严格的过滤,可能会被当做一个标签执行JS代码
1.脚本准备
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name: <br>
<form action="reflect_xss.php" method="get">
<input type="text" name="name">
<input type="submit" value="submit">
</form>
</body>
</html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name <br>
<form action="" method="get">
<input type="text" name="name" value="">
<input type="submit" value="submit">
</form>
<?php
if (array_key_exists("name",$_REQUEST) && $_REQUEST["name"] != NULL ){ //判断是key name 是否存在,是否有值
$name = $_REQUEST["name"]; //变量name接受key值
}
echo 'welcome *' .$name. '*' ; //输出
?>
</body>
</html>
2.攻击方式1
1.在输入框中输入标签会改变页面效果
网页源代码
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name <br>
<form action="" method="get">
<input type="text" name="name" value="">
<input type="submit" value="submit">
</form>
welcome *<h1>hello*
</body>
</html>
2.可以通过在输入框内输入
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name <br>
<form action="" method="get">
<input type="text" name="name" value="">
<input type="submit" value="submit">
</form>
welcome *<script>alert(1)</script>* //脚本注入
</body>
</html>
3.防御1
为了防止攻击者通过运行脚本,把输入部分的
<?php
if (array_key_exists("name",$_REQUEST) && $_REQUEST["name"] != NULL ){ //判断是key name 是否存在,是否有值
$name = $_REQUEST["name"]; //变量name接受key值
// str_replace()直接替换函数;区分大小写
$name = str_replace('<script>','', $name);
}
echo 'welcome *' .$name. '*' ; //输出
?>
4.绕过防御1的手段,攻击2
1、用大小写躲避防御手段,就可以运行,不会被str_replace转化成空值
<Script>alert(1)</script>
2、再嵌套一层<scr,当
<scr<script>ipt>alert(1)</script>
5.防御2
运用正则替换把输入的字符中,符合的可能连起来的字母,如<script不管中间有多少间隔都会替换掉,/i会核实大小写
// preg_replace() 正则替换(i表示忽视大小写)
$name = preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i>','',$name);
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name <br>
<form action="" method="get">
<input type="text" name="name" value="">
<input type="submit" value="submit">
</form>
welcome *>*
</body>
</html>
6.攻击3
当
<img src=1 onerror=alert(1)>
7.防御大招:全部木大
把输入的一些字符作为实体,防止浏览器将其作为浏览器元素
//htmlspecialchars(string)把预定义的字符"<",">",&,转化为HTML实体,防止浏览器将其作为HTMl元素
$name = htmlspecialchars($name);
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS</title>
</head>
<body>
Please input your name <br>
<form action="" method="get">
<input type="text" name="name" value="">
<input type="submit" value="submit">
</form>
welcome *<img src=1 οnerrοr=alert(1)>*
</body>
</html>
2、存储型XSS
把攻击脚本存入数据库,当对方每次需要从数据库中批量调取数据时,调取到该脚本就会执行
1.脚本准备
store_xss.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Store XSS</title>
</head>
<body>
<form method="post" action="store_xss.php">
<table width="550" border="0" cellpadding="2" cellspacing="1">
<tr>
<td width="100">昵称 *</td>
<td><input name="txtName" type="text" size="30" maxlength="10"></td>
</tr>
<tr>
<td width="100">消息 *</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="添加留言" onclick="return validateGuestbookForm(this.form);"/>
<td><input name="btnClear" type="submit" value="清除留言" onclick="return confirmClearGuestbook();"/>
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
function validate_required(field,alerttxt){
while (field){
if (value==null||value==""){
alert(alerttxt);return false;
}
else {
return true
}
}
}
function validateGuestbookForm(thisform) {
while (thisform){
if (validate_required(txtName,"昵称不能为空。")==false){
txtName.focus();return false;
}
if (validate_required(mtxMessage,"消息内容不能为空。")==false){
mtxMessage.focus();return false;
}
}
}
function confirmClearGuestbook() {
return confirm("你确定清除留言么?")
}
</script>
</html>
<?php
//连接数据库
$conn = @mysqli_connect("localhost","root","rootroot") or die("file");
@mysqli_select_db($conn,"phpxsstest");
//@mysqli_query( $conn,"SET NAME UTF-8");
//btnClear的数据库操作方法 清除按键
if (array_key_exists("btnClear", $_POST)){
$query = "TRUNCATE guestbook"; //$query sql语句
$result = @mysqli_query($conn,$query) or die(mysqli_error()); //$result 搜索结果
echo "<script>alert(/清除成功!/)</script>";
}
//btnSign的数据库操作方法 添加按键
if (isset($_POST['btnSign'])){
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
}
$query = "INSERT INTO guestbook (name, message) VALUES ( '$name', '$message')";
$result = @mysqli_query($conn,$query) or die(mysqli_error());
echo "<script>alert(/添加成功!/)</script>";
//获取数据库内容动态显示
function GuestBook(){
$conn = @mysqli_connect("localhost","root","rootroot") or die("file");
@mysqli_select_db($conn,"phpxsstest");
//@mysqli_query( $conn,"SET NAME utf-8");
$query = "SELECT name,message FROM guestbook ";
$result = @mysqli_query($conn,$query) or die(mysqli_error());
$guestbook = "";
//遍历数据库信息显示
while ($row = mysqli_fetch_assoc($result)){
$name = $row["name"];
$message = $row["message"];
echo "<div> Name:" ,$name,"<br>";
echo "Message:",$message,"</div><br>";
}
}
GuestBook();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Store XSS</title>
</head>
<body>
<form method="post" action="">
<table width="550" border="0" cellpadding="2" cellspacing="1">
<tr>
<td width="200">昵称 *</td>
<td><input name="txtName" type="text" size="30" maxlength="10"></td>
</tr>
<tr>
<td width="200">消息 *</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="添加留言" οnclick="return validateGuestbookForm(this.form);"/>
<td><input name="btnClear" type="submit" value="清除留言" οnclick="return confirmClearGuestbook();"/>
</td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
function validate_required(field,alerttxt){
while (field){
if (value==null||value==""){
alert(alerttxt);return false;
}
else {
return true
}
}
}
function validateGuestbookForm(thisform) {
while (thisform){
if (validate_required(txtName,"昵称不能为空。")==false){
txtName.focus();return false;
}
if (validate_required(mtxMessage,"消息内容不能为空。")==false){
mtxMessage.focus();return false;
}
}
}
function confirmClearGuestbook() {
return confirm("你确定清除留言么?")
}
</script>
</html>
2.攻击方式1
在消息中输入攻击脚本存入数据库
<script>alert(10086)</script>
每次调用到该数据都会,执行该脚本,影响时间很长
可以把脚本放入到自己创造的网页,当人点进来获取数据时就自动获取该用户的信息,比如说cookie
3.防御方式1
用函数–strip_tags(addslashes($message))–在输入的数据添加上斜杆然后再除字符串中HTML,XML,PHP的标签
//btnSign的数据库操作方法
if (isset($_POST['btnSign'])){
$message = trim($_POST[ 'mtxMessage' ]); //trim 去除空格
$name = trim($_POST[ 'txtName' ]);
$message = strip_tags(addslashes($message)); //addslashes 添加反斜杆 strip_tags去除字符串中HTML,XML,PHP的标签
$name = strip_tags(addslashes($name));
}
用函数 n a m e = h t m l s p e c i a l c h a r s ( name = htmlspecialchars( name=htmlspecialchars(name);把标签符号转化为实体
//btnSign的数据库操作方法
if (isset($_POST['btnSign'])){
$message = trim($_POST[ 'mtxMessage' ]); //trim 去除空格
$name = trim($_POST[ 'txtName' ]);
//大招 把标签转化成实体码
$name = htmlspecialchars($name);
$message = htmlspecialchars($message);
}
<div> Name:君莫笑<br>Message:<script>alert(10086)</script></div>
在从数据库调取出来的输出上进行过滤
function GuestBook(){
$conn = @mysqli_connect("localhost","root","rootroot") or die("file");
@mysqli_select_db($conn,"phpxsstest");
//@mysqli_query( $conn,"SET NAME utf-8");
$query = "SELECT name,message FROM guestbook ";
$result = @mysqli_query($conn,$query) or die(mysqli_error());
$guestbook = "";
while ($row = mysqli_fetch_assoc($result)){
$name = $row["name"];
$message = $row["message"];
$name = htmlspecialchars($name);
$message = htmlspecialchars($message);
echo "<div> Name:" ,$name,"<br>";
echo "Message:",$message,"</div><br>";
}
3、DOM型XSS
:通过JavaScript操作document,实现DOM树的重构
1.脚本准备
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
var pos = document.URL.indexOf("name=")+5;
eval(document.URL.substring(pos, document.URL.length));
</script>
<br>
welcome to our website
...
</body>
</html>
2.攻击方式1
通过URL注入想要运行的脚本
区别:在客户端就可以完成,不用去到后端