如何解决写入文件并以原子方式执行
假设我在内存中有一个可执行文件(或 bat 脚本,无关紧要)的内容,并希望将它作为一个新进程运行。这很容易。
File.WriteallBytes(filePath,contents);
// gap
Process.Start(filePath)
但我想确保执行的文件没有被任何其他进程篡改。文件创建和执行之间存在差距。它提供了使用正确工具篡改文件的机会。
因此,我没有打开 File.WriteallBytes
,而是打开一个 FileStream FileShare.Read
并保持打开状态,直到执行完成。
using(var fileStream = new FileStream(filePath,FileMode.CreateNew,FileAccess.Write,FileShare.Read))
{
Process.Start(filePath)
}
但这行不通。 Process.Start
失败:
System.ComponentModel.Win32Exception (32):该进程无法访问该文件,因为它正被另一个进程使用。
This question and its answer explains why I think。简而言之,Process.Start
将尝试使用 FileShare.Read
打开文件并失败,因为打开的 FileStream 已经具有写入权限,因此进程的 FileShare.Read
尝试失败。
有没有办法干净利落地做到这一点?
一种解决方法我能想到的就是保存文件,关闭它,用FileShare.Read
和FileAccess.Read
打开一个新的FileStream,确保内容还是一样的在执行之前。但这并不漂亮。
解决方法
您所描述的是一个典型的 Time of check to time of use 漏洞案例。
任何涉及检查某些内容然后执行它的解决方案,并且这两个操作不是原子的,仍然会让您容易受到攻击。例如:
在执行之前确保内容仍然相同。但这并不漂亮
“确保内容仍然相同”和“执行它”之间仍然存在(较小的)差距(时间窗口)。
2004 年发表了一个不可能的结果,表明没有可移植的、确定性的技术来避免 TOCT-TOU 竞争条件
-https://web.cecs.pdx.edu/~markem/CS333/handouts/tocttou.pdf
你可以做一些事情来缓解它:
-
不要使用文件!你说你的内存中有一些代码需要执行:你能在同一个进程中自己执行吗?
-
减少时间窗口。
-
使文件名随机且难以预测其他进程。
-
在攻击者(或恶意程序)运行的可能性较小的情况下,以单独的用户身份运行您的程序,并将文件读/写限制为仅限新用户。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。