如何破解4个常见的安全问题 - 以及如何修复它们
我一直认为黑客攻击比它在电视上看起来更难。但在探索了两年的道德黑客世界后,我了解到,如果有足够的知识和创造性的思维,几乎任何人都可以黑掉任何东西。
实际上,我们每周都会听到一个大型组织的另一个数据泄露事件,或者一个广泛使用的软件包的新漏洞。这些漏洞中的许多都是对安全的误解造成的,而这些误解往往导致了安全的错误配置。在这篇文章中,我将介绍四个最常见的安全误解,并解释黑客如何利用它们来执行攻击。我还将解释MongoDB如何帮助你保护你的数据免受这些攻击。
1.NoSQL注入
安全网络开发的第一条规则是。永远不要相信用户的输入。这让我想到了第一个常见的误解:
MongoDB不使用SQL,所以我不需要担心SQL注入。
我曾与无数有这种错误安全感的开发者交谈过。事实是,随着NoSQL数据库在数据库市场上获得越来越多的份额,攻击者开始关注,新的攻击工具开始出现,比如NoSQLmap(SQLmap的NoSQL版本),它允许黑客在脆弱的应用程序和端点上执行自动的NoSQL注入。但理论已经足够了。让我们开始黑客行动吧(从道德角度)。
下面显示的是一个易受攻击的应用程序端点的例子。该应用程序使用用户提供的req.query.user 和req.query.pass ,作为名字和密码的值。查询字符串采用用户名和密码,建立一个查询,并检查用户是否存在:
app.get('/', async (req, res) => {
query = {name: req.query.user, password: req.query.pass}
user = await client.db("secret_bank").collection("users").findOne(query)
if (user){
res.send('Success')
} else {
res.send('Failed')
}
}
有漏洞的应用程序端点。
这是一个相当基本的认证方法,但用一些命令行工具很容易被利用。
如果我们输入正确的用户名和密码信息,我们会看到服务器上有字符串存在。(我增加了一些额外的日志记录,这样我们就可以看到服务器上发生的情况):

正常登录。
用户名和密码在服务器上得到确认,一切似乎都很正常。
MongoDB查询通常是用对象和数组建立的。从攻击者的角度来看,问题是,他们能不能把这些注入到服务器上?
URL查询参数的一个有趣且不太为人所知的特点是,如果你在URL中的参数上加一个方括号,它就会被转换成一个数组。正如你从这个例子中看到的,我们在服务器上把密码 "notRight "作为一个数组加入。

在参数上加上方括号,可以看到数组的存在。
假设你是一个攻击者,你想注入一个包含两个值的列表。你只需要用同一个参数做两次,你就会在服务器上得到一个数组的值列表。

如果你在命令行中对同一个参数加两次方括号,你就会在服务器上得到一个数组的值列表。
这对寻求将NoSQL注入应用程序的攻击者来说绝对是有用的。
攻击者可能会问的下一个问题是,他们能否在服务器上注入一个对象?在任何编程语言中,如果我们在方括号内设置一个字段名,就会得到一个对象。在这里,你会看到服务器上的一个对象也是如此。
.jpg?auto=format%252Ccompress)
如果你把字段名设置在方括号内,你会看到服务器上的对象。
因此,攻击者现在可以向服务器发送对象,但他们如何利用这一点?在SQL注入中,你可以做的最基本的认证绕过是引号(")或一等于一(1=1)的双破折号。这个查询结果每次都是true 。

绕过SQL中的登录。
上面的SQL查询将评估用户是否等于admin,在我们的例子中是真的。然后,它检查密码是否等于一个空字符串(由于我们的引号),或者一个等于一个,这总是真的。因此,该查询将总是返回用户名的ID,如果它存在的话。有一些NoSQL选项也会这样做。
如果你的密码真的被设置了,我们可以运行一个查询,检查它是否大于零,它总是如此,并使用它来绕过认证。

与SQL注入类似,黑客可以运行一些NoSQL查询来绕过应用程序认证。
这是一个应用程序的漏洞,而不是数据库的漏洞。应用程序假定用户发送的是密码和用户的字符串。如果应用程序用.toString()强制将密码和用户名变成一个字符串,无论用户给出什么输入,都不会被解析。
这其中有很多是很明显的,但让我们再往前走一步。下面显示的是几行Python脚本,它遍历了一些字符,玩了一下regex,然后做了一些盲目的NoSQL注入。通过这样做,我将演示我们如何从数据库中提取一些数据:
baseURI="http://localhost:3000/?user=admin&pass[$regex]=^"
chars=list(string.ascii_lowercase + string.ascii_uppercase + string.digits)
count=0
while (not found):
currentCharacter=chars[count]
url=baseURI + foundString + currentCharacter + ""
if requests.get(url).text == "Success":
count=0
foundString+=currentCharacter
url=baseURI+foundString+"$"
found = requests.get(url).text == "Success":
else:
count+=1
一旦我们启动了这个漏洞,这个脚本就会不断地迭代每个字符。
这个Python脚本执行了一个盲目的NoSQL注入来提取一个密码。
这里的主要目的是提取明文密码,因为在这种情况下这是我们易受攻击的参数。这个漏洞是13行代码,花了大约10分钟来写。有了NoSQLmap,这可能更容易。
现在,我知道你们所有的Java和C#开发人员都在那里认为你们的应用程序是安全的。你会惊讶地发现,你仍然很脆弱。它所需要的是一种非常有趣的查询构建方法,即把JSON字符串解析为查询,这是不应该做的。
在2021年,一个相当流行的开源聊天服务器发现了这个漏洞,使用regex盲注。在这种情况下,攻击者正在拔出用户的重置令牌。一旦他们能够重置密码,他们就能够提升用户的权限,使他们成为管理员。一旦成为管理员,他们就可以设置一个叫做整合的东西,这是一个花哨的词,用来在你的服务器上运行代码。而一旦发生这种情况,你就被骗了。
因此,需要重申的是。永远不要相信来自任何用户的任何输入,永远不要!
2.社会工程攻击
人类每天都会被黑掉。大多数安全攻击和数据泄露使用社会工程。伟大的黑客只有在他们想让你知道他们的存在时才会让你知道。这给我们带来了第二个常见的误解。
我不需要认证,因为数据库将总是在私人网络上运行。
认证是最基本的安全功能。无论你是使用SCRAM-SHA、LDAP、x509还是Kerberos,如果你不锁上前门,有人就会获得你的数据。如前所述,社会工程是首选方法。只需要有人无辜地点击一个恶意文件,就会产生一个宏观木马,让攻击者进入网络。一旦他们进入你的网络,他们可以扫描开放的端口,然后测试数据库的认证是否启用。

网络扫描。
一旦他们发现一个没有认证的数据库,你就已经被骗了。

你已经被骗了。
就这么简单。
3.TLS和网络流量
假设你现在已经启用了认证,你的数据现在被锁在了一个强密码(至少16个字符,使用大写和小写字母、数字和符号)后面。你甚至已经把凭证移到了一个秘密库中,以阻止攻击者从源代码或配置文件中读取它们。你很安全,对吗?好吧,这让我想到第三个常见的误解。
我们不需要TLS,MongoDB使用的是二进制协议。
不幸的是,随着 "自带设备 "的流行,员工经常在没有任何许可或IT部门监督的情况下从非官方商店安装软件。第三方软件的漏洞很容易导致恶意行为者未经授权访问网络。再一次,他们可以进行扫描,发现我们正在运行MongoDB数据库。

检查认证。
这一次,黑客们检查是否设置了认证,结果是。在这一点上,他们可以尝试蛮力攻击,但这是一个很大的工作,黑客们更喜欢更简单的方法。相反,他们开始嗅探网络,发现MongoDB数据库的多个数据包。

嗅探网络。
他们总是可以拦截流量并将其发送到自己的机器上。一旦他们的机器上有了数据,他们只需要很好地了解他们的工具。Tshark或Wireshark可以帮助你访问一个pcap文件。而且,如果你把它输出为JSON,你可以用jq来操作它。下面的例子显示了BSON的十六进制代码。

BSON转储。
有一个叫CyberChef的工具,有一个BSON的解码器。

解码BSON。
一旦攻击者截获并解码了BSON数据,你就再次被骗了。甚至不需要用户名。
因此,这里的教训是,所有服务器都需要TLS。这将确保两个系统之间传输的任何数据都是加密的,即使被拦截,没有私钥也无法解密。
在文件被删除后检索它们
所以,现在我们有了强密码的认证,我们已经得到了应用程序的安全,网络是安全的,而且我们在休息时使用加密。所以我们是完全安全的,对吗?这让我想到了第四个常见的误解。
静态加密会保护我免受黑客攻击。
2014年的一项研究发现,78%的硬盘在退役后被卖掉重新使用,上面仍然有数据,其中23%仍然有社会安全号码,21%有财务信息。这是个问题。如果你使用密钥文件进行静态加密,黑客可以从一个被丢弃的旧驱动器或没有被安全擦除的驱动器中检索到这些文件。然后再一次,你就被骗了。对这种漏洞的最好防御是始终使用KMIP(密钥管理互操作协议)服务器进行静态加密。
恶意的内部人员
重要的是要记住,如果攻击者在你的系统运行时进入你的系统,他们可以掌握你的数据,无论你使用什么系统。这让我想到了目前企业最大的风险之一的攻击载体,那就是恶意的内部人员。
根据最近的一项研究,70%的组织正看到内部攻击的增加。识别这些攻击可能需要长达200天。在全球范围内,35%的企业已经受到影响。
想象一下,一个受信任的员工接受了你的一个竞争对手的工作,在接受他们的职位的过程中,决定把你的数据库带走。他们不想用自己的凭证来访问它,因为害怕被发现。他们可以转储内存并获取缓存中的内容,但这是一个很大的工作。他们也可以转储内存并寻找加密密钥,这也是一项大量的工作。另外,他们可以直接使用密钥文件并转储数据。然后再一次,你就被骗了。

用KMIP运行主机。
内部攻击是一些最难防范的,因为员工的知识水平和访问权限。如果看起来没有人是安全的,这就是我想告诉你的。如果有人在你的服务器运行时进入了它,所有的赌注都被取消了,特别是如果他们有root权限。这就是客户端字段级加密的作用。因为它在应用服务器上对数据进行加密,然后再发送到数据库中,即使是你的DBA也不能读取这些数据。正在使用的密钥也在一个密钥管理系统(KMS)中。客户端字段级加密应该用于所有敏感信息。
默认情况下是安全的
让我们面对现实吧,安全配置是一项全职工作,而你已经有一个这样的工作了。MongoDB Atlas提供了一个默认安全的数据库。至少,它总是需要一个用户名和密码,它总是要求你使用TLS,并且有网络和IP访问列表来进一步限制对数据库的访问。MongoDB Atlas使用零信任设计,符合所有主要的组织监管框架。当你对mongoDB Atlas以外的应用程序使用客户端字段级加密,并将你的数据放在默认安全的Atlas内时,你在恶意的内部人员和你的数据之间又增加了一层。