前言
前几天在网上冲浪的时候,无意间发现了一个 Edu 站点。这是一个很常见的类似 MOOC 的在线学习系统,对外开放,同时提供注册和登录功能。对于我这种常年混迹低危榜单的人来说,这恰恰是最理想的测试目标——一个 Web 网站只要具备登录功能,就必然涉及权限划分,而权限划分的实现一旦不够严谨,开发过程中就容易暴露出各种问题,越权便是其中最常见的一类。
经过测试,这个站点确实存在越权问题:A 账号可以通过发包修改 B 账号内的数据。不过这些数据并不是密码、个人信息等敏感内容,而是平台上的评论、收藏和点赞数据。虽然听起来危害不算太大,但这些行为已经构成了水平越权,最终提交 EduSRC 后被评为中危。下面我就回到当时的角度,跟大家完整复盘一下这次挖洞经历。
发现过程
访问网站之后,映入眼帘的是一个常见的在线学习平台首页(各位师傅请原谅我厚码处理,因为这个首页 banner 恰好是该学校的全景图)。

右上角可以看到登录和注册入口,于是果断注册了一个账号,进入系统看看都有哪些功能。在个人信息修改处先做了一些常规的 XSS 测试,看看能否构成存储型 XSS;在头像上传处也尝试了文件上传测试,看看是否存在任意文件上传漏洞。说起来也奇怪,现在的新系统里任意文件上传似乎越来越少见了。侧边栏可以看到「点赞」「收藏」「评论」「笔记」等功能模块。

随便点开一个视频,可以看到视频右下角有一个「记笔记」的功能入口。我们随手写点内容,添加一条笔记,同时在 Burp 中观察这个笔记究竟是如何创建的,并分析返回包里的数据。

抓到的包内容如下:请求采用 JSON 格式传输,包含三个参数——第一个是笔记内容,第二个是资源 id,第三个是视频 id。返回包则包含操作成功状态和时间戳。其中比较让人疑惑的是第二个参数 resourceId,它的值不是从 1 开始的,而是直接跳到了 133。由此我怀疑:每当用户创建笔记时,这个 id 会自动加一,与具体用户无关,只跟全站笔记总数挂钩。换句话说,这个参数实际上就是用户笔记的「标识码」。想到这里,我马上进入个人中心,测试删除笔记功能。

删除操作的抓包内容如下,同样是向一个接口发起 POST 请求,数据格式为 JSON。可以看到删除功能的请求包中确实包含了与创建笔记请求包相似的字段,但多出了一个 id 参数。这是怎么回事?这篇笔记是我账号下的第一篇笔记,按道理 id 应该从 1 开始才对,但它的值却不是从 1 开始的。结合刚才的分析,这个 id 看起来更像是全站所有用户累计的笔记总数——每次有用户创建笔记,这个 id 就加一,而这个 id 似乎只有在删除功能的抓包中才能直接看到。

综合以上分析可以发现,删除接口的参数中并没有任何用于判断权限的字段,只有一些与删除内容本身相关的参数。经过测试,只要更改 id 后发包,响应包与删除成功的响应包完全一致,因此初步判断这里可能存在越权问题。继续观察其他功能的请求包,发现情况基本类似:删除操作几乎都是 POST 请求,表单中携带 id 即可完成删除。
接下来开始验证!再注册一个账号,暂且称它为 B 账号。我们用 B 账号发表一条评论。

为了方便测试,进入个人中心查看已发表的评论,抓包发现这条评论的 id 是 46。

直接回到 Repeater 中,这里还保留着之前用 A 账号测试删除评论时的请求包,把 id 修改为 46,发包。从返回包可以看到,删除评论成功。

此时登录 B 账号,进入个人中心,发现之前发表的评论和笔记都已经被删除了。

成因分析
综合请求包和返回包的内容来看,以笔记功能为例,可以大致推断出后端的创建和删除逻辑分别是:
-
创建:POST 请求接口,直接携带笔记内容。后端会为这条笔记分配一个 id,这个 id 与具体用户无关,也不受前端控制,直接强制取全站笔记总数加一。举例来说,A 账号发布了一条笔记,它的 id 是 47,那么无论下一个笔记是谁发的,其 id 都会是 48。
-
删除:POST 请求接口,携带要删除的笔记 id。实际上,从上面的请求包可以看到,评论的删除确实是 POST 请求只携带了 id,而笔记的删除请求中还携带了「笔记内容」和「视频 id」等参数。但实际测试发现,这些参数后端根本没有校验,后端拿到 id 后直接对相应的笔记执行删除操作,没有进行鉴权。因此,只要将 id 从 0 遍历到当前最大值,理论上就能把全站所有用户的笔记全部删除。
总结复盘
在此之前,我也挖掘过类似的逻辑漏洞。那一次是越权删除图片库中其他用户上传的图片,实际成因与这次几乎如出一辙:都是因为平台对用户的个人「资产」没有进行有效的鉴权。在类似平台的开发过程中,不少开发者为了图方便,后端会直接处理请求中的关键信息(比如上面笔记的 id),并据此执行相应操作,而不去校验这个资源是否真的归属于当前登录用户,这就导致了水平越权问题的出现。
作为安全测试人员,在日常挖洞时可以多关注目标资产中的这类功能点——收藏、点赞、评论、笔记、观看记录等用户内容管理模块,往往是权限校验容易疏漏的地方。如果大家对这类逻辑漏洞的挖掘思路感兴趣,也欢迎到云栈社区一起交流讨论。