我如何证明该站点存在巨大的安全漏洞?

信息安全 密码破解 md5
2021-08-11 20:11:54

免责声明:我是一名计算机程序员,不是安全分析师或任何与安全有关的人。我在密码学领域的经验为零,所以请多多包涵。

情况:我的任务是将客户的站点与数据托管站点集成。在处理这个问题时,我偶然发现了一个转储所有用户数据的查询。要进行此查询,用户必须“验证”以获取会话并使用该会话代码进行此查询,然后在完成查询和响应之前检查用户是否具有管理员权限。

但是……这对我来说似乎有点可怕。特别是因为这是在成功运行查询时发回的一些数据:

"username": "testemail@testemail.blerg",
"firstname": "Test",
"lastname": "Name",
"userpassword": "$1$te000000$qMpAriadAHuRyDkK58YKS0"

返回的数据更多是可怕的暴露,但这不是我主要关心的问题。

显然,从来没有人被命名为“测试名称”,并且“testemail.blerg”不是一个注册域,更不用说“blerg”是一个可能的顶级域。即使是这样,该帐户也已从数据托管站点中删除并且无法登录。使用的密码是一个弱密码,测试用例密码,并且没有被任何人使用。

我是否有可能使用暴力/彩虹表(虽然我没有经验,但我知道一些闪词:P)或从中获取密码的东西?我知道的一点(我认为)userpassword是 MD5 盐的第一部分,但我什么都不知道。

如果有人能解释它是多么容易,我可以向我的老板证明这个网站非常糟糕,并说服我们的客户从这个数据托管网站迁移。

关于加盐,我确实知道更多(即它是如何获得盐的,它使用什么语言/功能等),但我想看看那些无法访问该信息的人是多么容易理解它出去。希望我还有另一件事可以去找我的老板。

编辑:由于法律/等原因,我故意在描述中含糊不清似乎有点混乱,部分是为了防止任何迹象表明这是哪个 CRM。我也意识到我称它为“数据托管”可能会产生误导,所以我的错。希望这可以澄清:

我们团队正在做的工作是为公司创建一个基本网站来展示他们的产品。我与 CRM 的唯一互动是:

  1. 当一个人填写了联系我们表格时,我们POST向 CRM 中的一个Contacts对象提供了用户的信息。
  2. 做一个GET在销售他们产品的清单上Dealers展示。

我从 #2(GETAPI 调用)开始,在那里我发现我可以查询Users表。我没有创建 API,我只是向它发出请求。

GET调用需要一个参数query=,其中值是SELECT系统查询语言中的语句,然后将其转换为 SQL(可能防止 SQLI 攻击,但我不知道它如何解释/转换为 SQL,所以我没有触及那个用一根 10 英尺长的杆子)。通过在查询中更改SELECT * FROM Dealers;SELECT * FROM Users;,我能够看到每个用户的数据。

CRM 处理用户的方式是在其站点上使用门户。在门户中创建了一个用户,其中有一个“是管理员”复选框。这可以随时通过门户进行编辑。这是发出 API 请求的过程:

  1. 用户向包含用户名的 CRM 请求令牌。

  2. 该令牌与该用户的“秘密”访问密钥连接,生成的字符串经过 MD5 散列,然后发送回请求会话令牌。

  3. 这个会话令牌包含在每个请求中,作为查询字符串参数,以“验证”请求是否“授权”。

其中一个问题是,如果“管理员”用户向Users发出请求,则响应是每个用户的列表,其中包含我上面列出的信息以及用户的“秘密”访问令牌(和其他信息)。因此,这比仅仅暴露密码更糟糕,它实际上是通过冒充任何人来授予任何人访问权限。

4个回答

userpassword 属性中的密码格式看起来像各种 unix 服务使用的标准格式,例如默认的系统密码服务将散列密码存储在/etc/shadow. 格式基本上是:

$ type $ salt $ hash

在您的示例中,类型为 1,表示 md5 哈希。还有其他众所周知的类型,例如各种大小的 sha 系列散列函数。

今天打破 md5 哈希几乎是微不足道的,即使它是加盐的,因为 md5 是如此之快。它不是一个可以安全地用于散列密码的散列函数;hashcat 和其他密码破解器每秒可以散列数百万甚至数十亿个候选密码。

所以这个数据存储服务不仅可怕,因为它会发回用户密码哈希,它甚至更可怕,因为它实际上使用 md5 哈希来存储密码。

为了向你的老板证明这确实不安全,你可以下载 hashcat 和一些密码列表(你可以很容易地在网上找到它们),然后在一台具有非常强大的 GPU 的计算机上运行你从那里获得的所有密码的 hashcat服务。记下 hashcat 可以破解多少个密码(无需查看密码本身 - 它们可能会泄露有关选择密码的人的私人信息,而您并不想真正知道他们的密码),并告知密码的人妥协,他们需要选择一个新密码。您可能需要先获得许可才能执行所有这些操作,因为根据您的居住和工作地点,这实际上可能被视为恶意攻击,甚至是非法的。

旁白:如果您在表达了疑虑后仍坚持使用此服务,我建议您设置一个自动密码破解程序,该破解程序无需人工干预即可运行,并在设法破解他们时通知人们(通过向他们发送电子邮件)密码将是一种保护您的用户免受这种不良设计影响的方法。这将有助于清除弱密码并增加真正的攻击者破解密码所需的时间。

编辑:扎克指出,旁白不是常见的做法,不应该由无法评估风险的人尝试。我完全同意这一点。至少,如果你做了这样的事情,你应该让管理层同意。

尽管如此,不这样做并不会使生成的系统更安全。这相当于把头埋在沙子里,因为害怕如果你真的采取了一些措施来提高密码安全性,它可能会适得其反。我们知道人们会选择错误的密码,并且我们知道md5 不是散列密码的好方法。如果我们不能改变这两个事实,并且我们能够清除弱密码,那么我们可能应该这样做以使我们的用户更安全。

一个重要的原因是我们通常没有能力实施它。好的系统不会使用快速散列函数来散列密码,而且我们通常无法访问整个散列密码数据库。

这个密码哈希似乎使用了这种crypt()格式(尽管它的名称和一些文档所说的,包括那个手册页,它与加密完全无关;它是hashing)。当它以 开头时$1$,这意味着它是一个基于 MD5 的密码散列函数。它的确切规范是“无论 glibc 做什么”。查看源代码显示了一些启发性的段落:

 201   /* The original implementation now does something weird: for every 1
 202      bit in the key the first 0 is added to the buffer, for every 0
 203      bit the first character of the key.  This does not seem to be
 204      what was intended but we have to follow this to be compatible.  */
 205   for (cnt = key_len; cnt > 0; cnt >>= 1)
 206     md5_process_bytes ((cnt & 1) != 0
 207                        ? (const void *) alt_result : (const void *) key, 1,
 208                        &ctx, nss_ctx);
 209 
 210   /* Create intermediate result.  */
 211   md5_finish_ctx (&ctx, nss_ctx, alt_result);
 212 
 213   /* Now comes another weirdness.  In fear of password crackers here
 214      comes a quite long loop which just processes the output of the
 215      previous round again.  We cannot ignore this here.  */
 216   for (cnt = 0; cnt < 1000; ++cnt)
 217     {

由此,我们可以得出结论,这个散列函数没有很好的文档记录。

无论如何,作为密码散列函数,它不是很好。它使用salt,这很好,因为它应该防止攻击者使用预先计算的表(包括彩虹表)。它还包括一个包含许多(1000)次迭代的循环,试图使密码散列变慢,从而使攻击者更难尝试许多潜在的密码,直到找到匹配项(称为“蛮力”或“字典攻击”的过程”)。

不幸的是,它也不是很好。MD5 很快,一千个嵌套的 MD5 虽然慢了 1000 倍,但仍然很快。具有基本面向游戏的 GPU 的现成 PC 每秒可以计算数百万个此类哈希值;普通用户密码不会持续很长时间;我的意思是,攻击者在每个散列密码上花费一分钟的计算时间仍然会破解其中的一半。


除了散列密码之外,简单地透露用户的电子邮件地址已经是一种非常可恶的罪行——我的意思是从法律上讲。例如,在加拿大,这被称为“个人信息”,所有用户都有权起诉您。

停止。不要再进一步了。在您被书面明确要求这样做之前,不要再进行测试、演示等,即使这样,也不要再请求并建议有比您更多的合格人员来进行审计/渗透测试/等

我知道几个月前有两个人用较少的信息(没有密码,只是他们不需要访问也不应该访问的详细信息)做了类似的事情,他们仍在经历处理的过程重罪指控。

该格式看起来像标准的 unix 风格的密码哈希。字段由美元符号分隔,首先是算法,然后是盐,然后是实际哈希。假设它是 Linux 系统,$1$ 表示 md5 密码算法(比纯 md5 稍微复杂一点)。字段长度也与 MD5 密码哈希算法一致。

有许多用于攻击 Linux 密码哈希的工具。您是否使用这些工具取得了成功,很大程度上取决于密码的强度。

我还注意到你的盐里面有很多零。如果您有静态盐或相对较小(与用户数量相比)范围的盐,那么这可能会为预先计算的攻击打开选项。

最后我要指出,攻击真实密码可能会带来法律问题。