检测数据库篡改,有可能吗?

很长时间的听众,第一次来电。

假设你有一个负责logging用户活动的数据库表。 这个日志的完整性很重要,所以你希望能够检测到有人修改了表中的任何数据。 为了使事情更有趣,还要考虑一下这样一个事实:你的系统可能由一个对这个可怜的系统有完全控制权的邪恶的SQLpipe理员操作。 让人惊讶…

你将如何保护你的数据?

如果有人篡改了您的数据,您将如何检测?

您可以使用无限制的工具。 (即哈希,encryption等)

如果您确实必须检测到发生了篡改,请在表中添加校验和字段。 每个新行的校验和必须包含前一行的校验和。 然后为了validation内容,在前进的时候通过计算校验和的数据集。 如果计算的校验和不匹配表中的值,则某个值已被篡改。

-麦克风

如果“evil admin”无权访问填充数据库的应用程序,则每个表上的额外列将由其他列的encryption签名组成。 需要“不能访问”的条件,使他们不能只提取你的私钥和签署他们的假数据。

编辑:啊,正如评论者指出,我不认为pipe理员只是删除一行。 为此,您需要每次更新一次encryption签名的行数(或者表格内容的其余部分的签名散列,或上次访问时间或您select的任何指标)。

如果你真的想要安全使用 – 为该表写入一次Read Many Media。

创build一个影子表,只有你和应用程序知道每个字段的散列值。 如果要检查数据篡改,请重新筛查用户表并与影子表进行比较。

只需用交易标识符运行纸质logging,并将打印机保存在只有一个密钥的房间中。 与财务系统一起工作,你会发现他们中的很多人仍然依赖他们的纸张备份。 几乎不可能无法用纸来“破解”纸张日志……这就是为什么人们不断推动纸币在投票机中的日志logging。

很多人都在说“只要添加一个数据库”,虽然我自己实际上是在练习这种logging,但我不相信它。 一个恶意的内部人员可能会以十几种方式剔除这种保护措施。

我们在这里所做的就是试图find一种方式来明确发生了什么事情。 你会失去你的日志。 你不能相信他们:如果我遇到了一个系统有一个万无一失的日志系统,我要么填写垃圾数据,要么完全擦除它。 不要陷入马吉诺路线的思维。

但是,如果你做好了足够的准备,太多的失败必须发生,你可以把破坏的范围缩小到一个内部来源。 你需要logging数据库,你需要保留大量的系统日志,你需要监视IPstream量,把相机放在服务器房间,在控制台上留下一个键盘logging等,即使是最好的将滑落到某个地方,如果你有足够的捕鼠器,你可能会偶然发现他们。

让我们清楚一点:如果你假设一个邪恶的系统pipe理员,没有encryption解决scheme,将阻止他们能够以一种难以追踪的方式修改系统上的数据 – 有解决scheme,将阻止他们能够解密信息,但没有可以防止他们以任何他们认为合适的方式写新信息。

这种情况需要以下条件:

  1. 这个系统必然是独立的。 如果您可以添加另一个系统,那么Evil Sysadmin将无法访问作为日志logging主机(例如系统日志服务器),那么问题突然间就会成为定期传输日志或哈希的简单情况。

  2. 该系统没有非软件一次写入组件。 正如其他人所build议的那样,最简单的就是打印机,但是您可以使用CD或自定义一次写入硬件来防止此问题。 如果邪恶的系统pipe理员可以物理访问机器,这些技巧就会变得棘手,但并不是无法克服的。

  3. 你需要确定性,而不是统计的可能性。 如果#1和#2是不可能的,那么你唯一剩下的解决scheme就是obscurification – 实施tricksy陷阱,如果邪恶的系统pipe理员不知道陷阱,那么这个陷阱就是为了防止被篡改的。

有效的#3的秘密是战术上的惊喜。 其目的是向攻击者传达这样的印象:他们知道所有的反措施,而实际上他们有更多的不知道的反措施。 一般来说,这需要至less两个级别的掩护 – 至less需要一层防护,恶魔系统pipe理员可能会妥协,因为他们会寻找它,如果他们没有find它,他们会得到可疑并深入挖掘,直到他们做到。

重要的一点是,这个封面应该是非常有说服力的,以便满足邪恶的系统pipe理员,一旦他们find了,他们就不用再看了。 第二层然后使用替代技术识别篡改,并产生适当的警报。 在这个线程可以实现的交易等有各种各样的build议。 解决scheme的级别越低,成功的可能性就越大(例如,修补数据库源代码比执行连接和查询的标准进程更不明显,修补内核不太可见,修改固件。 )。

强调这是非常重要的,这不是一个完美的解决scheme。 无论你的设置如何复杂,有人可能已经find/妥协了足够的信息来实施对策。 #1和#2的情况并非如此(正确完成)。 也就是说,如果你所保护的信息的价值足够低,那么具有必要技能的人就不会有兴趣去获得这些信息,它应该提供可行的辩护。

您可以使用触发器来审计插入,更新和删除操作。 现在,如果“邪恶的SQLpipe理员”禁用触发器,那么你有一些更难的问题。 如果我想保护我的数据,我不会允许一个邪恶的pipe理员完全控制系统。

我认为这是一个很好的问题! 但是你的情况违背了数据库的devise原则。

行校验和,触发器导出到其他数据库 – 你做的任何事情都是妥协!

我只能build议一些东西,如果你要应用某种types的标准,如PCI合规性,它会有帮助吗?

如果失败了,我会build议找另一份工作! 在我们这个行业有足够的工作,你不需要与这些types的人一起工作。

考虑创build一个滚动,快速,异地,自动备份您的数据。 现在S3是如此便宜,以至于我们可能会经常使用一个mysqldumptypes的进程来将整个数据存储库转移到跨大西洋备份存储中。 多久才会取决于DBA的恶意。

为了使这个过程成为可能,只要在你的networking中find或者build立一台机器,那么这个邪恶的pipe理员一无所知,如果她怀疑任何东西,也不会去关心它。 插头电脑的简单和高雅在这里不能被夸大。

注意实际的输出机制:对于你的特定系统一无所知,我build议mysqldump或Oracle exp是最简单和最笨的解决scheme。 如果您的应用程序有一种以本机格式导出数据的方式(例如XML,JSON甚至协议缓冲区 – 换句话说,SOA应用程序的某些部分用于彼此交谈的任何格式),那么格式可以用作滚动转储的格式。

我已经在我的gitosis框中实现了这个方法。 每三个小时内容被转储到一个欧洲S3桶。 这是另一个VCS的穷人VCS。

设置您的系统将日志logging数据写入恶意SQLpipe理员无法控制的远程系统。 这不会阻止pipe理员删除或篡改您的日志程序,但会阻止他在事后修改它们。

这是一个常见的数据安全问题。 简单的答案是,如果你处于一个单一的“邪恶的SQLpipe理员”可以访问你的整个环境的情况下,你没有办法保护你的数据。

关键任务数据的一个常见做法是login到多个备份,并通过确保没有单个人拥有权限来进行保护。

如果你的应用程序一直在运行,你可以在数据库上启动一个事务处理,直到你的应用程序closures,才会释放它…这种方式甚至都不能查看表格,但是你的应用程序…

也是的,如果你有时间这样做,encryption进出你的程序的所有文本string数据…

我还是喜欢BobbyShaftoe的回答,但是请稍微深入一点,看看你是否可以在几分钟后触发“睡眠”或所有的logging,所有logging回到他们是什么…所以我们的邪恶pipe理员认为他做出了改变,但他们只会恢复。

首先,非常小心你雇用谁来pipe理你的系统。

下一个由触发器填充的审计表。 即使他绕过触发器进行更改,至less可以在更改之前查看数据(特别是从备份中)。

第三个自动备份被移除异地。 这样,即使坏人丢弃了数据库并删除了现场备份,你也有一个备用的位置。 确保数据库pipe理员不能访问异地备份,只有其他人拥有权限,而不具有数据库服务器的生产权限。

接下来,除了pipe理员以外,没有任何人的直接权限。 这意味着使用没有dynamicSQL的存储过程。 这至less可以防止他人以未经授权的方式更改数据。 现在你的会计人员很难进行欺诈。

没有生产pipe理员权限,除了pipe理员和其他人作为备份。 这样,如果你发现触发器发生了变化,你知道是谁做的。 现在出了什么问题,你只有两个嫌疑犯。

SQL Server 2008有DDL触发器告诉你谁做了结构性的改变。 同样,如果触发器没有logging更改,则默认由admin创build。

encryption备份和某些个人数据使其更难以窃取。 现在,非现场备份交付人员将更难以窃取您的数据。

即使不是他不值得信任的数据,也会触发任何被certificate不可信的pipe理员。 如果他会伪造时间表或盗取办公用品,他会窃取数据。 如果他因为一些严重的犯罪行为(不是交通违法行为)而被逮捕,那么如果需要certificate这个指控是否被证实的话,你可以让他停职。

当pipe理员决定转到另一个工作时,不要让他从他告诉你要去的那一刻开始访问你的系统。 如果你正在解雇他,这一点尤其重要。

我发现这篇文章 ,看起来很有趣,可能是一个可能的解决scheme,尽pipe我还没有花时间来尝试和考虑利用。


在我头顶,我可以想象有两个单独的数据库,“邪恶的”系统pipe理员只能访问一个。

一个数据库将提供一次性的垫到另一个数据库和日志谁请求垫和什么时候。 这个pad,以及当前时间和行数据可能被散列。

这样,如果恶意的系统pipe理员改变了哈希不会检查出来的东西,如果他试图重新散布,你会logging事情应该发生的时间。

如果系统pipe理员可以存储时间和一次性密码,那么整个系统就会崩溃。

这是一个看似难以解决的问题,我不确定任何协议是否真的有效,但增加物理安全性和审计日志将是一个好主意。

如果您需要自动化方法,您首先必须知道用户types允许的操作和上下文。 这是相当困难的,因为在正确的情况下,降幅是可以接受的,但不适用于日常用户。

我喜欢纸备份的想法,但是,由于庞大的用户群和繁重的数据库使用情况,产生的信息量会很快变得很大。

每隔几个小时,对表格内容进行散列。 同时logging开始和结束行。 对于第二个哈希和向前,对整个表的内容做一个哈希,并将这些行散列在前一个哈希(检查哈希)中。 如果前面的散列和检查散列不匹配,数据库表就被篡改了。 我会把这些哈希邮件发送给你,所以你可以检查是否stream氓pipe理员已经通过,并重新生成所有的哈希值。 我意识到存在差距,但是我认为没有比这个或者已经提到的更多的事情了。

我喜欢MikeMontana的解决scheme,但我认为可能值得添加一个附录。 可悲的是我不能留下评论,所以我把它发布在一个新的答案,原来引述如下:

如果您确实必须检测到发生了篡改,请在表中添加校验和字段。 每个新行的校验和必须包含前一行的校验和。 然后为了validation内容,在前进的时候通过计算校验和的数据集。 如果计算的校验和不匹配表中的值,则某个值已被篡改。

-麦克风

有几个人指出:系统pipe理员可以重新计算校验和(如果你想要在他的服务器上运行代码,更是一个问题)。

当数据被插入到表中时,它将被公钥encryption,因此任何人都可以添加到数据库中(假设有多人使用它)。 定期使用私钥解密数据并计算校验和。 如果不同意味着数据库已经被修改(你想testing什么)。 然后重新计算校验和并将其插入表中(当然,公钥也是encryption的)。

如果恶意的系统pipe理员尝试重新计算新的校验和,他正在使用encryption的数据。

此外,如果您正在远程访问这些数据,则通过在本地盒子上进行解密和校验和计算,这种方法对中间人攻击是免疫的。 截获的数据将保持encryption,因此无法使用。

这个系统唯一的缺陷是检测到数据库的任何事务。 你可以通过抽象解决这个问题,并说:

  • validation校验和
  • 插入数据
  • 重新计算校验和

但是这消除了让你想要访问数据的任何人没有给你的私钥的好处。

现在有可能以不同的方式来解决这个问题,我build议你:

解决网格计算中的信任不对称问题

Peter Dinda

http://portal.acm.org/citation.cfm?id=1066656

但是实现细节会变长。

虽然这里有一些非常好的build议,但他们都会咬上灰尘。

因为你有一个“不信任”的演员,邪恶的pipe理员,作为你的数据保pipe你不能保护自己。 networking协议和现实世界中有各种各样的scheme,使您能够保护您的数据免受不可靠的运输/信使的篡改。 但据我所知,没有任何东西可以保护你免受不可信赖的保pipe人的困扰,如“我是麦道夫先生,我曾经是纽约证券交易所主席,你可以信任我……”。

分离电源/双电源控制。

我喜欢到目前为止提出的想法。 我想添加我自己的2美分。

在金融业,权力分立是保持一个人完全邪恶的关键。 我们的核心处理解决scheme由我们的簿记部门pipe理(保佑他们的心),所以我们的程序员并没有真正获得大量的访问我们的实时数据。

此外,第三方还会logging与系统关键部分的交互。

总的来说,没有一个人有足够的控制力来影响所有的制衡,使得收益减less到足以(不希望)协调。

除了审计和校验和触发器之外,还可以将数据库复制到另一个从属数据库 – 没有人能够直接对其执行任何操作。

你仍然有可能会碰到触发器等,但是当它们混淆时,它会非常明显,所以你能够检测到复制在哪一点被破坏。

你可以添加一个触发器来发送数据的一个副本,因为它是input到非生产数据库,邪恶的pipe理员也无法访问。 pipe理员可以停止触发function,但问题是如何检测操作,而不是阻止它。

由于您的pipe理员完全控制了服务器,您可能需要一个外部审计解决scheme来监视特权SQL Server用户的活动。

Guardium使networking设备可以logging数据库或服务器上的所有查询活动,并在networking级别(包括本地连接)执行此操作,因此您无法在SQL Server级别执行任何操作来干扰该活动。

这并不妨碍你的邪恶pipe理员改变表格,但是由于它是一个locking的装置,邪恶的pipe理员不能改变表格,然后劝说装置说他没有这样做。

有两个关于这个主题的有趣的研究论文其中之一提出了HMAC alogrith的使用。 另一种提议使用Condensed-RSAscheme和BGLS签名scheme。

外包数据库中的身份validation和完整性

http://www.isoc.org/isoc/conferences/ndss/04/proceedings/Papers/Mykletun.pdf

关系数据库的通用失真水印技术

~cortesi/paperi/iciss09.pdf

我觉得这两种解决scheme都是基于大量风险的解决scheme。 –Kiran.Kumar

我在研究如何实现这样一个解决scheme时发现了这个线程。 我想到的一个(非常理论上的)解决scheme就像使用一个完美的前向密钥系统。

我想如果你有一个私钥 – 公钥对(称为Kpr和Kpb)和一组algorithm(A和B),那么:

A(K_pr)= K'_pr

B(K_pb)= K'_pb

(其中K'pr和K'pb是与Kpr和Kpb不同的有效私钥 – 公钥对)

使用这个,你可以签署数据库中的每一行,在使用后丢弃每个私钥,但是保存公钥和签名。 然后,您可以将第一个公钥保存在恶意pipe理员无法更改的位置(即,将其发送给您认识的所有人,将其印刷在报纸上,将其纹于脸上,以上全部)。

因为没有私钥,所以没有办法重新签名每一条logging,并且可以检查公钥是否都是顺序的。 我能想到的只有两个缺陷:

  • 如果恶意pipe理员获得一个私钥的副本,他将能够从那一刻起改变任何logging。 这可以通过使用硬件模块创build签名来规避,所以私钥不能从软件访问
  • 邪恶的pipe理员将能够将数据附加到您的表。

问题是,我不知道一套algorithm,如我所描述的。 但是,我不是一个密码学家,所以它可能是可能的。

编辑:

经过一番思考,我可能已经想出了一种方法来使现有的工具成为可能。 如果你在第(n-1)条logging中包含第n条logging的公钥和它的签名(你可以这样做,因为在写logging的时候你可以访问下一个私钥) d保证每一个logging与前一个logging。 删除私钥后,签名不能被重新创build,只要你有第一个公钥,你总是可以validation整个表。 这也消除了需要“顺序”的私钥,你可以简单地为每一行生成一个新的私钥(尽pipe这将是非常昂贵的)。 同样的缺点仍然适用。

这个问题的2016年答案将是使用区块链数据库。 根据Wikipedia:

块链主要是防篡改的,通过将最近有效事务批量的散列时间标记为“块”,certificate数据必须在当时存在。 每个块包括先前的时间戳,形成一个块链,每个附加的时间戳强化之前的时间戳。