源代码:
if(isset($_GET['submit']) && $_GET['message'] != null){
//这里会使用正则对<script进行替换为空,也就是过滤掉
$message=preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/', '', $_GET['message']);
// $message=str_ireplace('<script>',$_GET['message']);
if($message == 'yes'){
$html.="<p>那就去人民广场一个人坐一会儿吧!</p>";
}else{
$html.="<p>别说这些'{$message}'的话,不要怕,就是干!</p>";
}
}
<div id="xssr_main">
<p class="xssr_title">阁下,请问你觉得人生苦短吗?</p>
<form method="get">
<input class="xssr_in" type="text" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<?php echo $html;?>
</div>
preg_replace -- 执行正则表达式的搜索和替换
preg_replace(pattern, replacement, subject)
pattern
:必需。正则表达式的模式,用于匹配和替换文本。replacement
:必需。替换模式,用于替换匹配到的文本。subject
:必需。要被替换的文本或数组。
括号里的内容涉及到正则表达式,我简单解释一下
'/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/'
单括号:
1.命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
2.命令替换。等同于cmd,shell扫描一遍命令行,发现了( c m d ) 结 构 , 便 将 (cmd)结构,便将(cmd)结构,便将(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。有些shell不支持,如tcsh。
3.用于初始化数组。如:array=(a b c d)
.:
匹配除\n之外的任意的一个字符
*:
匹配前面子表达式0次或者多次
.*:
一起使用就表示任意字符出现零次或多次,没有?表示贪婪模式。
例如,模式 `a.*b` 会匹配以 `a` 开头,以 `b` 结尾的最长的字符串,即使 `a` 和 `b` 之间有其他字符。如果用它来搜索 `aabab`,它会匹配整个字符串 `aabab`。这与贪婪匹配相对应,即在匹配尽可能多的字符的同时,尝试找到下一个符合条件的字符。
另一种模式 `.*{n}` 表示复制 `.` 任意次,至少 `n` 次,这可以用于匹配特定长度的字符串。例如,模式 `.*{3}` 会匹配至少三个字符长的字符串。
,这是为了为匹配被尖括号包围的单词"script",但(.*)意味着它会匹配任何位于"s"、"c"、"r"、"i"、"p"和"t"字母之间的字符,而后被替换为空格,以达到破坏标签结构的作用。
试着输入1"><script>alert("xss")</script>
不见了,也就是说script被过滤了。
怎么办呢?
很简单,将script大写即可,毕竟它只过滤了小写的script
poc:1"><SCRIPT>alert("xss")</SCRIPT>
成功!