升级错误日期以获取代码执行

什么网站可以推荐大学(用几个步骤破解大学)(1)

图片:乔什·索伦森

几周前,当我即将完成对萨尔大学的申请时,一杯新鲜的茶在我的桌子上等着。在我的初始申请被接受后,我被要求上传一些额外的文件,比如我的护照,以完成这个过程。因此,我被转发到一个上传平台,在那里我应该使用我的申请人ID和我的生日作为密码登录。但是,我的生日不起作用,我被拒绝登录。这是一个错误的出生日期如何导致在大学服务器上执行代码的故事。

你不可以过去?

在我的生日没有作为密码之后,我喝了一大口茶,思考接下来的步骤。最终,当网站不适合我时,我做了我经常做的事情:我分析了网站的流量!

什么网站可以推荐大学(用几个步骤破解大学)(2)

登录页面要求输入申请人 ID 和生日。

下面演示的流量显示,当我单击登录按钮时,应用程序会向 loginBewerber 端点发送一个请求,该端点在 URL 中包含申请人的 ID,在请求正文中包含生日。ID 和生日都是用户提供的输入,我们可以使用并尝试操作。我尝试的第一个操作是使用典型的 SQL 注入 (SQLi) 绕过日期检查:01.02.1999" OR "1"="1. 有了这种攻击,攻击者可以滥用 SQL 的语法。在这种情况下,我错误地验证了生日检查条件并希望该服务将我登录。令我惊讶的是,攻击在第一次尝试时就成功了,并且来自服务器的答案提供了一个包含我的许多个人信息的 XML,比如我的地址、性别和出生日期。后来,我还了解到日期检查只是客户端,任何密码都提供 XML。

登录请求在 URL 中包含申请人的 ID,在请求正文中包含生日。登录请求返回一个包含大量个人信息的 XML。

很快,我检查了这个 XML 中的所有信息,并找到了我最初的登录尝试失败的原因:不幸的是,管理员为我的帐户存储的生日日期错误。至少,绕过完美无缺地获得了正确的日期并通过了登录。

我对此有不好的预感

那时,我很好奇这个应用程序还能提供什么。毕竟,我被要求将我的护照上传到该服务。如果没有绕过身份验证,将重要文件上传到仅以申请人生日为保障的应用程序中,这已经是一种不安的感觉。我的意思是,强制一个标准学生的生日需要多长时间?但是现在,有了已知的脆弱性,这种感觉就更糟了。

当我在登录 URL 中查看申请人的 ID 时,这种感觉得到了进一步的证实。不需要专业的黑客就能看出申请人的身份证只是一个普通的号码。在我的示例中,数字是 45678。如果我从 ID 中减去 1 并再次发送请求会发生什么?答案来得很快,我差点被茶呛到:其他用户的个人信息显示在我的屏幕上。

我的屏幕显示了申请人 45677 的信息,同样的请求也适用于所有其他 ID。虽然我的真实ID不是45678,但号码在同一个地区。因此,这意味着任何人都可以自由访问近 50,000 个个人用户信息,例如家庭地址和电子邮件;作为这个平台的用户,我不是很高兴。

是时候上传一些文件了

现在我可以登录我的用户帐户,我可以开始上传请求的论文了。但是,我不想将个人文档上传到此服务,这不足为奇。尽管如此,我的好奇心还是被激起了,因为我想知道上传功能是如何工作的。所以我发了一些测试文件。

流量分析揭示了一个奇异的上传过程,由两个请求组成。首先,如下图,发送一个简单的post请求来上传一个文档。下面的示例请求显示 URL 包含文件名,并且正文包含内容。一旦第一个请求被接受,服务器就会以包含文档存储路径的纯文本进行响应。接下来,客户端发送另一个请求,将上传的文件链接到相应的应用程序。在下面的第二个示例请求中,我们在 URL 中找到申请人的 ID,在 file_renamed 参数中找到上一个请求的文件名。最终,该服务将上传的文档列为用户应用程序的一部分。

上传请求在其 URL 中包含文件名和部分路径。上传过程的第二部分发送一个请求,将文件与相应的申请人连接起来。

我以前见过类似的上传过程。因此,关于这个上传过程的两个方面引起了我的注意:第一个是初始 URL 包含文件名和服务器存储文件的路径的其他部分。如果我们分析 URL 参数并将它们的值与我们从服务器获得的响应文本进行比较,就可以看到这一点:文件保存为 /data/uploader/uploads/20221/45678_2022_01_31_22_21_18_2_Passport_Hantke_Florian.pdf。如果我们操纵这条路径会发生什么?

第二个奇怪的地方是,只要 file_renamed 参数不指向现有文件,createUploadFile 请求就会返回带有信息堆栈跟踪的错误消息。我们可以使用关键信息进行进一步分析!让我再喝一口茶,然后我们继续。

从提供堆栈跟踪的第二个请求开始,我首先考虑了进一步升级此缺陷的各种方法。堆栈跟踪不仅揭示了有用的信息,例如源代码的结构,而且还回复了 file_renamed 参数的值。由于 file_renamed 参数是 XML 结构的一部分,我尝试的下一个攻击是XML 外部实体 (XXE) 注入。这种攻击滥用 XML 中的外部实体来发送服务器端请求,或者像我在我们的例子中所做的那样,将文件内容或目录列表加载到 XML 结构中。如以下请求所示,我将实体 x 定义为包含来自/etc/passwd的文件内容. 然后,服务器将此实体用作 file_renamed 参数的内容。由于此内容不是有效的文件名,服务器会以包含无效文件名的错误消息响应 - /etc/passwd的内容。因此,这意味着,我们可以读取用户被允许访问的所有目录和文件——不仅是标准的 Linux 文件,还包括应用程序的源代码或用户上传的文件。

上传请求易受 XXE 攻击。易受攻击的请求在错误消息中返回 /etc/passwd 的内容。

接下来,我继续分析第一个讨论的奇怪之处,即来自上传请求的路径参数。如前所述,来自服务器的响应会提供有关文件存储位置的反馈。有了这个提示,我很快发现端点容易受到路径遍历攻击。路径遍历攻击允许黑客在没有服务器检查有效性的情况下操纵路径。在这种情况下,它允许我将上传的文件存储在服务器上我想要的任何位置。但这只是冰山一角,因为我发现了一个更具破坏性的事实:服务器从未检查过文件内容和文件扩展名。因此,服务器对更关键的漏洞利用敞开了大门。

糟糕,我执行代码了吗?

当我喝完最后一口茶时,我想到了利用任意文件上传漏洞的方法。当然,我可以覆盖配置文件或上传 HTML 文档来触发 XSS。然而,我有一个更好的主意。

从上面提到的错误信息中,我们知道网络服务器是基于 Java 的。因此,我猜想一定可以执行 JavaServer Pages (JSP) 文件。JSP 允许 Web 开发人员编写包含在服务器端执行的动态 Java 部分的 HTML 代码。这意味着,控制由服务器加载的 JSP 文件的攻击者也可以在服务器端执行任意代码。

由于我已经找到了上传任意文件的方法,所以我也可以上传 JSP 文件。然而,一个问题仍然不清楚:我如何诱使服务器执行文件?通常,要触发 JSP 文件,必须用浏览器打开文件路径。在这种情况下,初始上传目录位于 webroot 之外,这意味着我不能简单地请求文件路径。幸运的是,我可以使用文件上传请求中的路径遍历将文件存储在我想要的任何位置,因此也可以存储在 web 目录中。除此之外,该应用程序还提供了一个更直接的解决方案来加载任意文件——一个容易被路径遍历的链接,这样我就可以从任意路径加载文档:https : //www.lsf.uni-saarland.de/uploader/upload?文件=../../../../etc/passwd&folder=uploads&sem=20221. 实际上,我可以自由加载上传的 JSP 文件并执行它。

为了测试我的想法,我上传到服务器的第一个(也是唯一一个)JSP 文件是漂亮而隐秘的名称9187b2b784c1298​7bpnwoleivsal.jsp(见下文)。然而,这不是 007,这只是一个测试,一个证明代码执行有效的数学函数。当然,它确实有效,理论上我能够在服务器上执行任意代码。至此,你们可能都知道这意味着什么:我不仅可以读取用户上传的所有文件,还可以尝试进一步提升权限、获取 root 权限并超越服务器,或者从内部进一步探索大学网络。这对我来说已经足够了,因为我不想在第一天之前让任何人生气——是时候开始报道了。

上传请求不检查文件扩展名或内容。该请求上传一个 JSP 测试文件。

什么网站可以推荐大学(用几个步骤破解大学)(3)

加载 JSP 文件时,会在服务器端生成随机数。

报告!

在我开始写报告之前,我总是进行同样的心理锻炼。我向后靠,想一想一群犯罪分子会在发现此类安全漏洞后获得哪些潜在利润,以及对用户和组织的影响。在这种情况下,犯罪分子可以利用第一个发现的漏洞绕过初始身份验证检查并使用任何用户登录,即使他们没有任何有效的申请人帐户。一旦他们打开门,他们就可以上传一个 JSP 文件来打开一个反向 shell。那时他们已经中了大奖:他们不仅可以窃取近 50,000 人的个人信息,还可以接管整个应用程序甚至服务器。

鉴于这些明确的事实,我在当天晚上很快就完成了漏洞报告,因此我在第二天向大学的数据中心发送了一封电子邮件。我告诉他们我的发现,不久之后,该应用程序处于脱机状态,只提示我一个 403 页面。最终,我收到了来自 Hochschul-IT-Zentrum (hiz) 的电子邮件,告诉我他们可以确认调查结果并正在调查问题。此外,我们就情况进行了友好且内容丰富的电话。

什么网站可以推荐大学(用几个步骤破解大学)(4)

报告错误一天后,文件上传器无法再访问。

在写这篇文章的时候,情况还是一样,我还是看到了 403 页面。但是,我知道 hiz 致力于解决上述问题,并且已经下令进行渗透测试以检查应用程序,然后再将其重新上线。此外,为了避免类似的问题,未来将由一个已建立的外部程序取代自行实现的服务。

一个深刻的问题

现在,报告已完成,案件已结案。我拿起茶杯走进厨房,同时还在思考这个案子,想知道这些基本的安全问题怎么会一直存在。当然,将错误归咎于某些开发人员总是很容易的,但是,在我看来,问题比编写糟糕代码的人更严重。本文中概述的事实以及许多其他事实(Zerforschung,CCC),向我们表明,问题在于德国普遍缺乏对 IT 安全的了解,并且继续远远落后。仅单独清理每个应用程序是无法解决的,例如一次又一次地清洁茶杯。从长远来看,这种清洁程序对茶杯的效果非常好,但显然不适用于应用程序。由此可见,这个深奥的问题只能通过政治手段来解决!曾经,亚瑟·温·皮内罗写道:“在英国社会,有茶就有希望”。所以,我相信这也适用于德国社会。由于我已经在泡下一杯茶,我希望像本文所讨论的这些基本问题在未来几乎不会存在。因此,我想在最后一节中就如何提高德国的总体 IT 安全性以及如何促进对这一重要问题的更多了解提出我的想法。

正如我之前所说,编写容易出错的软件不仅是开发人员的错。通常,项目截止日期的压力会导致开发人员优先考虑其应用程序的关键功能,而不是应用程序的安全性。例如,在 COVID-19 大流行期间,许多公司希望成为市场上第一个拥有特定产品或服务的公司,因此可能忽略了其产品的安全性(即电晕测试中心)。由于进入成本低,行业竞争异常激烈,产品流失越来越快,错过新趋势的成本远远超过糟糕软件的成本。当前联盟协议的 IT 安全部分的一句话试图控制这种肆意的行为:“制造商必须对其产品中的 IT 安全漏洞因疏忽造成的损害承担责任”。以 IT 安全人员的身份阅读本文一开始听起来很有希望,但更多地思考它就会让人失望。该声明表明只有在最坏的情况下,如果犯罪黑客成功攻击应用程序并造成损害,制造商可能会付出非常高昂的代价。在我作为法律和政治的业余爱好者看来,这种思维方式似乎是错误的,并且不可避免地会让应用程序的用户付出代价。如果我们总是等待最坏的情况,损害已经发生。当然,我们也有 GDPR,但老实说,以我有限的法律知识,我不知道漏洞的存在是否应受到惩罚,我也从未听说过任何此类先例。我认为,政府需要对独立安全研究人员报告的安全漏洞甚至它们开始被犯罪分子滥用之前提出严格执行和更好定义的处罚。

话虽这么说,错误不必仅由独立研究人员或犯罪分子发现。公司显然也可以而且应该检查自己的安全性。此外,他们应该依赖专业的外部渗透测试,因为测试人员经常从另一个角度查看应用程序。事实上,正如联盟协议的 IT 安全部分所述,政府机构已经计划进行频繁的测试。但是,在我看来,这也应该包括所有公共机构,例如大学,因为人们相信它们是安全的。更重要的是,它应该进一步包括所有在德国经营的公司。

渗透测试之外的另一个方面是提高一般的 IT 安全知识。在开发软件之前,人们至少需要对软件开发中的安全最佳实践有一个简单的了解。例如,在您担任厨师之前,您需要获得官方健康证明,以便您知道如何不毒害您的客人。在为您的公司驾驶卡车之前,您需要一个特殊的许可证,这样您就不会撞毁您的车辆。为什么您不需要开发人员许可证,这样您就不会毒害您的应用程序的用户或使您的软件崩溃?虽然这样的许可证对于软件开发来说是不现实的,但安全教育却是!IT 安全课程必须是每个 IT 教育的重要组成部分。而且,

最后,我的最后一个想法是联盟协议的另一个方面:“在负责任的过程中识别、报告和关闭安全漏洞,例如在 IT 安全研究中,应该在法律上是可行的”。这是一个非常重要的事实!目前,即使您的个人数据存在风险,在应用程序中寻找漏洞也是一个灰色地带。幸运的是,我还没有遇到任何问题,公司总是很高兴我报告他们的漏洞。但是,情况并非总是如此,如其他示例强调将安全专业人员视为罪犯的虐待。漏洞测试的法律方面并不完全清楚,这一事实使人们不敢去研究他们使用的产品。如果流程定义明确且合法,更多人会检查产品并报告漏洞。我们刚刚见证了一个很好的例子:我的意思是,为什么将近 50,000 名大学生登录到一个上传门户(已经看起来很可疑)而没有人发现或报告这些基本问题?负责任的漏洞研究是一项公共服务,必须合法化!

通过最后的声明,我希望你能同意我们的教育和法律机构必须改变一些东西,以创造一个更安全的互联网和世界。感谢您的阅读。现在,喝杯茶,为你余下的一天带来一点希望。

,