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

Tho*_*mas 7 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!
}
Run Code Online (Sandbox Code Playgroud)

问题:有人可以将文件链接到我的一些短期文件,因此/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!
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Mar*_*rkR 2

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

你还没有确切地说出你想要阻止什么。当然,有一些内核补丁可以防止在世界可写目录(或粘性目录)中建立指向您不拥有的文件的(硬或符号)链接。

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

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

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