用你的浏览器来静态分析网站源码——初级漏洞赏金猎人指南(入坑好文)

用你的浏览器来静态分析网站源码——初级漏洞赏金猎人指南(入坑好文)

source link

本文将教你如何用浏览器自带工具分析web应用的客户端源代码。这听上去有点怪,因为浏览器并不是做这活最好的选择。但在你开始用burpsuite抓包和到处注入alert(1)来测试XSS之前,好好研究下你的目标总是好的。

本文主要面向初级漏洞赏金猎人或者对HTML、Js代码分析缺乏经验的人,但我同样希望老鸟们能在这里有所受益。

近期我的一条介绍小技巧的推文在社区引来不少关注,于是我决定写本文:

twiiterpng

这条推文只是小技巧的冰山一角,我想与其发一堆容易错过的类似推文,不如发一篇汇总型的博文,希望对你们有用。那就开始吧!

工具集

每个现代浏览器都有一组内建工具集。要打开它们,你只需敲Ctrl+Shift+I、CMD+Option+I(macOS系统)、F12或在浏览器右边的菜单栏中找到。本文中我将使用最新版的Chromium,你们也可以使用Firefox、Safari、Chrome、Edge等,随你便啦,但我觉得Chrome的开发者工具是最强大的(该工具集集成在Chrome、Chromium、Brave、Opera和其他基于Chromium的浏览器中)。

另一样需要安装的工具是IDE(集成开发环境)或者任意带HTML、Js语法高亮的代码编辑器。随你喜好,我个人推荐Visual Studio Code,VSCode也是我日常工作中唯一使用的IDE。你可以在这里下载到https://code.visualstudio.com/

NodeJS也值得安装(并熟练使用它——英特网上有好几千的资源包),在这里下载https://nodejs.org/en/

Python解释器也是必装神器(如果你在用*nix系统,它已将预装了。如果是windows用户,还是要自己装一下)。会写Python是一个宝贵的技艺,我也建议没写过一行代码的人去学习一下。

在终端下用NodeJS测试JavaScript代码是很方便的(浏览器也能办到,我们随后讨论这一方法的优缺点)。Python是个好东西,你可以用它开发工具、写PoC和利用代码,下文将展示一些自写工具。如果你更熟悉其他解释型语言(Ruby、PHP、Perl、Bash等),你也可以使用它们。这类语言的优势在于无需编译、类似于命令行、跨平台、大量内建库和第三方模块。

分析HTML源代码

先回到我先前发的那条推特,你也许注意到了,截图里的网站看上去空白一片,但你若查看它的源代码,就会发现大量代码(没办法,我不能提供带网站URL的截图,因为这是个私人众测项目)。为什么浏览器上看不见这些元素?

重点是页面中的部分HTML标签没有渲染任何内容。最常见的是<html>,<head>,<body>,<style><script>。CSS同样能隐藏元素(例如,设置它们的宽、高属性为0或显示为none),例如:

<html>
<head>
    <title>Move along, nothing to see here!</title>
    <style>
    /* note to myself: add CSS from Bob's repo: https://verysecurecompany.com/__internal__/repo/bob/specs.git */
    * {
        font-size:16px;
        color: #c0c0c0;
    }
    </style>
</head>
<body>
    <iframe src="https://verysecurecompany.com/__internal__/loginframe.html" style="width:0;height:0" frameborder="0" id="you-cant-see-me"></iframe>
    <script>
        // a hidden feature
        console.log('Diagnostic message: username is admin and password is password :)');    
    </script>
</body>
</html>

如果你在浏览器中打开这个html页面,它不会渲染任何内容,你也不会看到任何内容。但当你查看源代码,就会发现一些有意思的东西:

在这里插入图片描述

里面有多出信息泄露:访问内部资源的URL、隐藏的包含登录表单的iframe、在控制台输出的凭据信息。这些信息不会显示在页面中,当然,别指望在每个网站里都发现这些信息,但带注解的Js代码很常见,有时它们会暴露一些app的服务端仍可用的API。

仅仅使用“View Source”功能无法揭露所有的内容,因为它只展示HTML文档。更有趣的内容通常由<iframe><script>等标签揭示,你可以在Chrome开发者工具的“Source”标签栏中看到它们。

在这里插入图片描述

左侧的目录树最底端的(index)节点就是你在“View Source”中看到的HTML主文档,其他资源保存在文件夹和文件树中。如果你点击这些文件,就会在右侧看到它们的内容。截图中是jquery.min.js文件的内容,它是所有Js文件的通用压缩版(从性能上说这么做很不错)。但如果你点击底部的“{}”小按钮,工具集会展开这些代码来方便阅读。

在这里插入图片描述

有些网站使用sourcemap特性(source map用来映射压缩版函数、变量、对象名称到它们在源代码中的真实名称及位置,更多详情)。sourcemap使用对象有意义的名称来增加格式化代码的可读性,而不是Js压缩软件产生的标识符。

另一个有用特性是全局搜索。假设你已注意到一些有趣的函数并想知道是否存在于源码中其他地方。也许它是个eval()函数参数来自url(这很可能造成Js代码执行)。为了对“Source”标签中文件做全部搜索,你可以用CTRL+Shift+F快捷键(MacOS中:CMD+Option+F)。下例中,我试着在AppMeasurement.js中查找getAccount()的所有引用。如你所见,该函数在同一文件中调用了一次。但若在其他文件中有出现搜索关键词,就会被列出:

在这里插入图片描述

有时你会发现搜索结果是一条非常长的字串(尤其是在压缩过的Js文件中)。点击字串,工具集就会打开它,点击“{}”按钮就会在右侧演示扩展版的Js版本(有时会有几千行),搜索结果也会出现。

另一个查看源代码的标签叫“Elements”。“Sources”标签的(index)文件(或“View Source”功能)与它看似相同,实则差别不小。前者展示的来自服务器的HTML文档,后者展示的当前DOM树,所有的节点有Js代码添加。为了明白这一区别,我先介绍些原理,然后展示个小示例。

DOM(文档对象模型)代表真个网页的HTML节点,它由单个根节点(<html>)和两个主要子节点(<head><body>)构成。所有其他节点都是二者的子节点,如:<title><meta><head>的子节点,<div><p><img>等是<body>的子节点。

当你在浏览器打开一条URL,首先会加载HTML文件,代码会由浏览器引擎执行。当浏览器发现<script><style>标签(或其他带有src属性的标签,如image、video),它会停止解析并加载src所指文件。如果该文件是可执行的Js,它就会被执行。如果是样式表,CSS规则就会被CSS解析器解析应用。整个过程如下图示:

在这里插入图片描述

但“Elements”和“Sources”标签又不同在哪里呢?考虑一下情形,Js添加元素到DOM中:

<html>
<head>
    <title>Dynamic P Application</title>
    <style>
    * {
        font-size:18px;
        font-weight:bold;
        color: #2e2e2e;
    }
    </style>
</head>
<body>
    <div id="container">

    </div>
    <script>
        const el = document.getElementById('container')
        const dynamic_paragraph = document.createElement('p')
        const dp_content = document.createTextNode('Hello from dynamically added <P>aragraph!')

        dynamic_paragraph.appendChild(dp_content)
        el.appendChild(dynamic_paragraph)
    </script>
</body>
</html>

当你打开这一页面并查看源码,你会看到如下的内容:

在这里插入图片描述

这是Js添加DOM新元素最简单的示例,当使用“Elements”标签时会看到:

在这里插入图片描述

当你比较“Elements”版本和“View source”版本的区别,你会轻易看到区别:前者有个可见的<p>标签,作为<div id="container">的子节点。之前的“Source”中并无该节点,因为它并不是源码的一部分。

如果你用AngularJs,React,Vue.js,Ember.js等处理过单网页应用。你会在“Elements”中看到大量动态生成的内容。这些内容各有不同,但在表单、动态分页排序列表、搜索项等大量元素中,很容易发现DOM型XSS漏洞,用户输入也常在模板表达式中解析(如:AngularJS的{{}})。

原因在于这类应用经常用GET、POST请求,或Cookies、浏览器Storage的内容来构建网页。当然,它们自己会生成大量内容。这里也容易发现一些薄弱点。

在查看JavaScript之前值得一说的是:一定要读一读HTML注解,你会发现不少没有渲染进页面的元素,里面常有意外之喜。

分析cookies和浏览器Storage

DevTools也可以用来检查网站保存在客户端的信息。有几处可被web应用利用。最常见的就是cookies——它是一段以名称定义的数据(你可以认为它的结构是键值对)并在服务器和浏览器的HTTP交互中交换。

浏览器Storage是另一处你能发现有用信息的地方。有两种Storage:本地Storage和会话Storage,区别在于会话Storage在关闭应用时(关掉浏览器标签页或浏览器时)会注销掉。本地Storage将留存很长时间,除非被手动清理(数据没有过期一说)。

想看到所有的存储信息,你只需使用工具集的“Application”功能:

在这里插入图片描述

使用“Application”功能不仅能看到内容,还能修改、删除和添加自己的键值对,这能引起意想不到的响应甚至发现漏洞。这也是检查水平越权最容易的办法,你可以替换会话token或更改cookie中保存身份信息的值来伪装成其他用户(这只是个例子,现在的web应用大多用多种方法认证用户,在多数情况下,更改一个cookie的值不足以劫持其他用户的会话):

在这里插入图片描述

这里还有另一处可以查看与web应用关联的Js源码的地方:“Service Workers”。在网上可以找到该功能更多的介绍https://developers.google.com/web/fundamentals/primers/service-workers/。该功能比较新,没有很多的web应用使用它。但它们的有些信息还是能揭示应用的工作流程,特别是下线后的行为。

猜你喜欢

转载自blog.csdn.net/nuaa_llf/article/details/86131594