我该如何防范硬链接攻击?

时间:2010-03-31 06:01:17

标签: c linux security

  • 我想将数据附加到/ tmp。
  • 中的文件
  • 如果文件不存在,我想创建它
  • 我不在乎别人是否拥有该文件。这些数据并非保密。
  • 我不希望有人能够在其他地方或其他文件中进行竞赛。

这样做的最佳方式是什么?

这是我的想法:

fd = open("/tmp/some-benchmark-data.txt", O_APPEND | O_CREAT | O_NOFOLLOW | O_WRONLY, 0644);
fstat(fd, &st);
if (st.st_nlink != 1) {
    HARD LINK ATTACK!
}

问题:有人可以将文件链接到我的一些短期文件,因此/tmp/some-benchmark-data.txt与我的另一个脚本正在使用的/ tmp / tmpfileXXXXXX相同(和使用O_EXCL和所有这些正确打开。然后我的基准数据被附加到这个/ tmp / tmpfileXXXXXX文件,当它仍然被使用时

如果我的其他脚本碰巧打开了它的临时文件,那么删除它,然后使用它;然后我的基准数据会破坏该文件的内容。然后,这个其他脚本必须在上面代码的open()和fstat()之间删除它的文件。

换句话说:

This script          Dr.Evil        My other script or program
                                    open(fn2, O_EXCL | O_CREAT | O_RDWR)
                     link(fn1,fn2)
open(fn1, ...)
                                     unlink(fn2)
fstat(..)=>link is 1
write(...)
close(...)
                                    write(...)
                                    seek(0, ...)
                                    read(...) => (maybe) WRONG DATA!

因此上述解决方案不起作用。很可能还有其他攻击。

什么是正确的方法?除了不使用世界可写目录。

修改: 为了防止恶意用户使用他/她的所有权和权限创建文件的结果,或者只是错误的权限(通过硬链接文件然后删除原始文件,或者硬连接你的短文件)我可以检查nlink检查后的所有权和权限位。

不存在任何安全问题,但也可以避免意外。最糟糕的情况是,我从我的其他文件复制的文件开头得到了一些我自己的数据(来自另一个文件)。

编辑2 : 我认为几乎不可能防止某人将名称硬链接到打开,删除然后使用的文件。例如EXE打包程序,有时甚至可以通过/ proc / pid / fd-num执行删除的文件。与此竞争会导致打包程序的执行失败。 lsof可能会发现是否有其他人打开了inode,但它似乎比它的价值更麻烦。

2 个答案:

答案 0 :(得分:2)

无论你做什么,你通常会遇到竞争条件,其他人创建一个链接,然后在你的fstat()系统调用执行时删除它。

你没有准确说出你想要阻止的东西。肯定有内核补丁可以防止在世界可写目录(或粘性目录)中创建您不拥有的文件(硬或符号)链接。

将它放在一个非世界可写的目录中似乎是正确的做法。

SELinux,它似乎是标准的增强型安全性Linux,可能能够配置策略禁止用户做坏事而破坏你的应用程序。

通常,如果您以root用户身份运行,请不要在/ tmp中创建文件。另一种可能性是使用setfsuid()将文件系统uid设置为其他人,然后如果该文件不能被该用户写入,则操作将失败。

答案 1 :(得分:1)

除了你刚刚说明的内容之外,我尝试过的唯一另一件事最终几乎同样具有竞争性且更昂贵,在/ tmp 之前创建inotify手表来创建文件,这样可以捕获在某些情况下发生硬链接。

然而,它仍然非常具有竞争性和低效率,因为您还需要完成广度优先搜索/ tmp,至少达到您要创建文件的级别。

据我所知,除了不使用单词可写目录之外,没有“确定”方法可以避免这种竞争。有人通过硬链接拦截你的i / o会有什么后果......他们会得到什么有用的东西,或者只是让你的应用程序表现出不明确的行为?