python的HTMLParser解析模块是一个非常强大的HTML解析模块,他提供了回调函数来检测是否存在某个标签或者属性,具体使用方式不再说多,网上有很多:
https://www.cnblogs.com/masako/p/5868367.html
在输入payload后,我们需要考虑到几种情况:
在属性内容中
在注释中
在标签内容中
在script标签中
如果在属性中标签是否为a或者ifr这类可以使用伪协议的标签
对于检测流程我是这样设计的,先输入随机字符串,判断是否在返回中出现。如果在返回中出现则调用 Class.feed
进行检测出现在哪里。
出现在data中,则发送 <随机字符串>随机字符串
,来判断html页面中是否出现了该标签
url = urlparse(url).scheme + "://" + urlparse(url).netloc + urlparse(
url).path + "?" + utilClass.GetStringParam(query, utilClass.GetPayloadParam(query, RandomString),
"<" + RandomString + ">")
检测代码如下:
def handle_starttag(self, tag: str, attrs) -> None:
if self.startTag or self.att:
return None
if str(tag).lower() == str(self.randomString).lower():
self.startTag = True
for att in attrs:
self.ParserAtt(tag, att)
此时如果页面已经解析了该标签则说明存在漏洞,如果页面没出现该标签则考虑是否是出现在了 script、title、nosciprt、textarea
这几类中,分别闭合后在进行检测。
如果出现在html注释中则直接发送 -->随机字符串
判断在data中是否出现,如果出现则进入第一个流程
判断是否在属性中,需要先判断标签是否为可插入伪协议的标签:
def ParserAtt(self, tag, attr):
if self.att:
return True
if str(tag).lower() == str(self.randomString).lower():
self.att = True
return True
if str(attr[0]).lower() == str(self.randomString).lower():
self.att = True
return True
if str(attr[1]).lower().find(("javascript:" + self.randomString).lower()) == 0 and (
tag == 'a' or tag == 'iframe'):
self.att = True
return True
if tag == 'a' or tag == 'iframe':
if str(attr[1]).find(self.randomString) == 0:
self.attrValue1 = True
else:
if str(attr[1]).find(self.randomString) != -1:
self.attrValue2 = True
如果是的话则直接加入javascript为协议,不是的话则考虑闭合属性,闭合属性后在进行测试是否添加新属性成功,若成功则返回漏洞存在,不成功则直接闭合标签。标签闭合成功后进入第一流程
可以使用模块 esprima
,解析代码如下:
def ParserJs(jscode,payload):
ast = esprima.parseScript(jscode)
for node in ast.body:
if node.type== "VariableDeclaration":
for declaration in node.declarations:
if (declaration.id.name.find(payload) != -1) and (declaration.id.type == "Identifier"):
return 1
elif declaration.id.name.find(payload) != -1 and declaration.id.type == "Literal":
return 2
elif declaration.init.value.find(payload) != -1 and declaration.init.type == "Literal":
return 2
elif declaration.init.value.find(payload) != -1 and declaration.init.type == "Identifier":
return 1
elif node.type == "ExpressionStatement":
if (node.expression.name.find(payload) != -1) and (node.expression.type == "Identifier"):
return 1
elif node.expression.name.find(payload) != -1 and node.expression.type == "Literal":
return 2
return 3