关于有漏洞的抽象(或关于不可预测的环境)

因此,这是Windows程序的相当简单的一部分。 有一个包含多个条目的文件。 而且它们需要以某种方式进行过滤。

解决方案非常简单-打开文件,逐一读取记录,然后将必要的记录写入临时文件。 关闭文件。 我们将其删除。 重命名为原始临时文件。 一切都很简单,我什至不提供代码。 这真的是这篇文章足够的理由吗?

尽管一切正常,但实际上没有理由对此进行撰写。 但是后来突然有一天“一切都掉了”,因为 由于访问被拒绝错误,未发生重命名。 这种情况很少发生,但怀疑宇宙射线的可能性仍然更高。

我们开始挖掘。 找到的第一个线索:在进行挖掘的过程中,Microsoft文档中的这句话提醒:
DeleteFile函数在关闭时将文件标记为要删除。 因此,在关闭文件的最后一个句柄之前,不会发生文件删除。 随后对CreateFile的调用以打开文件失败,并显示ERROR_ACCESS_DENIED。
就症状而言,它们非常相似,但是这些“其他处理程序”来自哪里,如果除了我们之外,没有人对这个文件做任何事情,也应该不做任何事情? 而且我们没有其他线程可以对该文件进行处理的线程吗?

正是由于SysInternals及其ProcessMonitor才找到了罪魁祸首。 我们启动它,将过滤器安装在我们长期受苦的文件上,并尝试长期持久地重现它。 我们复制。 我们看。 我们在那看到什么?
01.2:30:28.3162097 PM our_prog.exe 1288 CreateFile our.file成功所需访问权限:通用读取/写入
02.2:25:28.3164513 PM our_prog.exe 1288 WriteFile our.file成功偏移量:0,长度:898,优先级:正常
...
34.2:25:28.3173405 PM our_prog.exe 1288 WriteFile our.file成功偏移量:35,290,长度:1,113
35.2:25:28.3173493 PM our_prog.exe 1288 WriteFile our.file成功偏移量:36,403,长度:1,128
36.2:25:28.3173736 PM our_prog.exe 1288 FlushBuffersFile our.file成功
37.2:25:28.3174212 PM our_prog.exe 1288 WriteFile our.file成功偏移量:0,长度:40,960,
38.2:25:28.3175927 PM Explorer.EXE 1884 QueryBasicInformationFile our.file成功
39.2:25:28.3176144 PM Explorer.EXE 1884 CloseFile our.file成功
40.2:25:28.3263642 PM Explorer.EXE 1884 CreateFile our.file成功所需访问权限:读取属性,
41.2:25:28.3294990 PM our_prog.exe 1288 CloseFile our.file成功
42.2:25:28.3351356 PM our_prog.exe 1288 CreateFile our.file成功所需访问权限:读取属性,删除,
43.2:25:28.3351856 PM our_prog.exe 1288 QueryAttributeTagFile our.file成功属性:A,ReparseTag:0x0
44.2:25:28.3352020 PM our_prog.exe 1288 SetDispositionInformationFile our.file成功删除:True
45.2:25:28.3352218 PM our_prog.exe 1288 CloseFile our.file成功
46.2:25:28.3358275 PM our_prog.exe 1288 CreateFile our.file DELETE PENDING所需的访问权限:通用读取/写入,
47.2:25:28.3362207 PM our_prog.exe 1288 CreateFile our.file DELETE PENDING所需的访问权限:通用读取/写入,
48.2:25:28.3367696 PM Explorer.EXE 1884 QueryBasicInformationFile our.file成功
49.2:25:28.4279152 PM Explorer.EXE 1884 CloseFile our.file成功
50.2:25:28.4282859 PM Explorer.EXE 1884 CreateFile our.file名称未找到所需的访问权限:读取属性,
...
83.2:25:29.3497760 PM our_prog.exe 1288 CreateFile our.file成功所需访问权限:通用读取/写入,
我们在那里看到了以下内容(删除了多余的数据,以免造成混乱)。 第1至36行-我们创建一个文件,写入该文件,进行刷新。 最有趣的是从38-40行开始。 Explorer.exe无处不在,并开始读取我们的文件。

在第41行,我们关闭文件。 第42行-删除。 并且由于explorer.exe仍在读取它,因此不会删除该文件。 当我们尝试将临时文件重命名为主要文件时(在DELETE PENDING状态而不是SUCCESS),我们在第46和47行上看到了什么。

Explorer.exe仅在第49行完成读取。仅在此刻,文件才被物理删除(正如第50行间接告诉我们的那样,我们的永久explorer.exe再次尝试打开该文件以进行读取,但是由于该文件而失败不再)。

随之而来的是什么? 多亏了Microsoft Windows,现在甚至需要采用偏执编程的方式来完成简单的文件删除操作。 他们调用了delete函数,确保它返回OK,然后进入等待周期“直到文件已被物理删除为止”。 是的,是的,在不知道“她的内部有霓虹灯”的情况下,几乎什么也做不了...

但是现在,令人怀疑的是,这种方法是一种普遍接受的做法。 为了在使用Windows中的文件进行操作时牢记,操作系统随时会在您不知情的情况下决定对文件进行某些操作,并编写可抵抗这种情况的代码。 就此而言,调查较低。

Source: https://habr.com/ru/post/zh-CN450700/


All Articles