logo

路径劫持安全问题分析

作者:JC2021.06.23 17:37浏览量:307

简介:路径劫持被广泛地利用于恶意软件的传播手法中。准确的说他并不是操作系统的漏洞,他的利用条件和危害也并不

我是JC,一个干净利索富有艺术气质的技术宅,欢迎一起探讨安全问题。

我们常说的路径劫持(Path Interception)通常指:在Windows系统中的exe可执行文件,由于放置在特别的路径下,在被调用时由于调用语法不规范,导致被其他程序取代的问题。
此漏洞被广泛地利用于恶意软件的传播手法中。准确的说他并不是操作系统的漏洞,他的利用条件和危害也并不很直观,今天我们就来探究一下这个安全问题。

0x 01 漏洞原理

当我们在程序中调用另一个exe时,如下的命令调用会产生歧义:


C:\Program Files\foo bar\file.exe

我们知道,在Windows中可以只输入文件名而不输入.exe来启动一个可执行程序。
基于此,如上命令就可以理解为:
运行C:\Program.exe后面跟着的是参数,
或者还可以理解为:
运行C:\Program Files\foo.exe 后面跟着的是参数,
或者理解为:
运行C:\Program Files\foo bar\file.exe 后面没有参数。
对于这三种可能,Windows系统会按照如上顺序遍历这三种理解方式,那么此时,如果真的有一个C:\Program.exe或C:\Program Files\foo.exe存在,就会导致错误的理解程序员原本的意图,调用非预期的程序。

0x02 利用场景

对于恶意软件来说,他只需要把自己放在一些敏感的目录中,并进行特别的命名,然后等着被触发就可以了。

但这有一个前提条件,就是需要把自己释放在相应目录中。这可能需要一些社会工程学,诱导用户自己这样做,才能达到目的。可是如此看来,这和诱导用户直接打开恶意软件又有什么区别呢。如果利用前提真的是处在同一个威胁高度,这甚至不能算是个漏洞了。真的是这样鸡肋吗?

其实,除了考虑前提条件,我们还要考虑运行之后的效果。

这里,用户直接打开和利用漏洞触发,有一个区别,就是触发运行的主体不一样,也就是恶意程序调用的父进程不一样。我们假设,用户并没有系统最高权限,而存在此漏洞的程序则拥有比用户权限更高的运行环境,那么利用这个漏洞,对攻击者来说就可以达到一个权限提升的效果。

下面我们通过具体实验来证明这一点。
我们模仿一个存在此漏洞的程序通过jack用户创建一个Service服务。


sc create "Vultest Service" binPath= "C:\Program Files (x86)\executable.exe" start= a

从命令中可以看到,我们创建了Vultest Service这个服务,服务启动时应该调用C盘Program Files (x86)目录下的executable.exe(我将记事本程序notepad.exe放在这里并命名为这个文件)。

然后,我在C盘根目录下,模拟攻击者放一个Program.exe(我将计算器程序calc.exe放在这里并重命名为该文件)。

如下图,当我在服务里启动这个服务时(服务启动方式设置为auto,系统每次重启都会启动此服务,这里为了方便不重启,就直接手动启动了),可以在进程中看到,调用的是攻击者放的Program.exe,并且是SYSTEM系统最高权限。
如下图,当我在服务里启动这个服务时(服务启动方式设置为auto,系统每次重启都会启动此服务,这里为了方便不重启,就直接手动启动了),可以在进程中看到,调用的是攻击者放的Program.exe,并且是SYSTEM系统最高权限。

0x03 发现与规范

那么怎么防范呢。
还以我们的实验为例,这个漏洞是由系统中的“CreateProcess”函数引起的。
(参考微软官方API文档https://docs.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa?redirectedfrom=MSDN)

那么我在创建服务的时候,在binPath参数中加入双引号(通过反斜杠转义),将路径包裹

sc create "Vultest Service1" binPath= "\"C:\Program Files (x86)\executable.exe\"" start= auto

这时再启动服务,我们可以看到启动的进程就是executable.exe了。
我们通过右键查看服务属性,也可以直观的看到区别。
通过如下命令,也可以自动筛选出所有存在漏洞的服务:


wmic service get name,displayname,pathname,startmode|findstr /i "Auto" |findstr /i /v "C:\Window

我们知道,路径劫持漏洞从根源上讲,是由操作系统API中的“CreateProcess”函数引起的。所以,除了创建服务这个攻击点,任何调用CreateProcess函数的程序,都可能由于没有处理好引号包裹的问题,导致同样的路径劫持漏洞。

所以在安全测试中,我们可以在C盘根目录放入测试用的program.exe,或在Program Files目录放入common.exe,或在任何带有空格路径的上级目录中放入相关测试exe(比如计算器程序calc.exe)。
然后你就正常使用PC,当哪天在无意中触发了计算器时,你就知道是触发漏洞了!

这时我们先通过如下命令定位是哪个路径触发了计算器:


wmic process where name="program.exe" get commandline
wmic process where name="common.exe" get commandline

然后通过如下命令查找调用命令的父进程id:

wmic process where name="program.exe" get parentprocessid

通过如下命令查看进程路径,进而找到漏洞程序:

wmic process where processed=xxxx get commandline

这时,恭喜你,就发现了相关应用程序的0-day漏洞!

0X04 写在最后
从以上案例我们可以发现,路径劫持并不像其他高危漏洞那样可以直观的看到其危害,拥有路径写权限的前提条件看起来也非常的苛刻,但从攻击角度出发,攻击者通常是通过一些小众软件的漏洞获得一个低权限的shell,所以权限提升是黑客继续攻击所不可或缺的重要一步。

权限提升问题看似前提条件苛刻,但并不足以让我们忽略他。
在中危和低危的漏洞世界中,类似的安全问题还有很多。在开发人员的日常工作中,切不可忽略这些看似不痛不痒的漏洞,虽然即便不改,这些问题也不会马上甚至永远不会变成安全事件。但,作为有自我追求的开发者,规范我们的编码习惯,编写出安全性更高的符合安全标准应用程序,不是更好吗!

相关文章推荐

发表评论