回归最本质的信息安全

详解Bypass UAC 过程中踩过的坑(第二部分)

2017年6月14日发布

9,980
1
2

导语:在第1部分完成后,我们知道普通用户在拆分令牌管理登录中处理可以获得对升级进程的Terminate,QueryLimitedInformation 和 Synchronize进程访问权限的访问。

在第1部分完成后,我们知道普通用户在拆分令牌管理登录中处理可以获得对升级进程的Terminate,QueryLimitedInformation 和  Synchronize进程访问权限的访问。这是由于正常的用户和管理员具有默认DACL,该默认DACL授予对同一桌面上所有令牌设置的当前登录会话的执行访问权限。我们接下来的问题是如何才能提升你的权限?

在我们拥有的3个访问权限中, Terminate 和 Synchronize 都不是那么有趣。当然,你完全可以按照你自己的想法来。而在我看来QueryLimitedInformation可能会提供更多有趣的内容,比如我们可以获得哪些访问权限?这里会有一个快速跳转,跳转到MSDN是顺序的。以下是进程安全性和访问权限页面:

PROCESS_QUERY_INFORMATION (0x0400)
Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken).

PROCESS_QUERY_LIMITED_INFORMATION (0x1000)
Required to retrieve certain information about a process (seeGetExitCodeProcess, GetPriorityClass, IsProcessInJob,QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATIONaccess right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
Windows Server 2003 and Windows XP:  This access right is not supported.

这至少证实了第一部分的一点,如果你有QueryInformation访问,你也会自动获得QueryLimitedInformation。所以  QueryLimitedInformation 只是给你一个可以从完整的QueryInformation访问的一个子集。看起来这些文件可以访问的所有东西都很无聊,但  QueryInformation凸显了一些东西,非常有趣的东西——进程令牌。这里我们可以仔细检查一下,我们来看看OpenProcessToken的文档,看看有关所需访问的内容。

访问令牌打开进程,该进程必须具有PROCESS_QUERY_INFORMATION访问权限。那么不如就密封它,什么都没有看到,继续向前?等等,永远不要相信你读的任何东西。也许这真的是“伪造文档”呢(当然如果你在2020年从核辐射避难所那里读到这个,那么你就真的可以忽略它)。为什么我们不尝试一下看看(请确保您以前升级的副本MMC.EXE仍在运行):

Use-NtObject($ps = Get-NtProcess -Name mmc.exe) {
    Get-NtToken -Primary -Process $ps[0]
} | Format-List -Property User, TokenType, GrantedAccess, IntegrityLevel

然后我们替换掉之后可能会看到一条错误消息:

User : domain\user 
TokenType : Primary 
GrantedAccess : AssignPrimary, Duplicate, Impersonate, Query, 
QuerySource, ReadControl 
IntegrityLevel : High

这表明我们已经打开了进程'主令牌,被授予了许多权限,并确保我们打印了IntegrityLevel属性来证明它是一个真正的特权令牌(或多或少的原因将会变得清楚)。

这是怎么回事? 其实是因为文档是错误的,你不需要QueryInformation来打开进程令牌QueryLimitedInformation。 如果你不相信我,你可以在内核中反汇编NtOpenProcessTokenEx:

NTSTATUS NtOpenProcessTokenEx(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, DWORD HandleAttributes, PHANDLE TokenHandle) { EPROCESS* ProcessObject; NTSTATUS status = ObReferenceObjectByHandle( ProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION, PsProcessType, &ProcessObject, NULL); ... }

回到Vista,你会发现一直是这样的情况,只有 QueryLimitedInformation是需要的,与文档相反。虽然您仍然需要通过它的DACL访问令牌,但事实证明,令牌对象还使用默认DACL,因此它授予读取和执行对登录会话SID的访问权限。但令牌不是与进程有相同的强制性政策吗?好吧,我们来看看,我们可以修改第1部分的IL Policy转储脚本来使用令牌对象:

# Get current primary token's mandatory label $sacl = $(Get-NtToken -Primary).SecurityDescriptor.Sacl Write-Host "Policy is $([NtApiDotNet.MandatoryLabelPolicy]$sacl[0].Mask)"

结果是:“ Policy is NoWriteUp ”。所以当我们无法修改令牌(我们不能因为默认DACL而无法实现),我们至少可以读取它。但这样看来,这似乎并不是特别有趣,读取访问有什么用?如前所述,Read会给你一些有趣的权利,AssignPrimary,Duplicate和Impersonate。现在阻止你创建一个新的进程,还是假冒令牌吗?为了缩短创建新进程的过程,我试图通过内核函数SeIsTokenAssignableToProcess(和缺少SeAssignPrimaryTokenPrivilege)的限制,以及模拟时采用不同的方法来调用SeTokenCanImpersonate,但结果却仍然是不可能的。如图所示:

1496935608590043.png

该图是用于确定进程是否可以模拟另一个令牌的粗略流程图(假设您没有我们没有的那个SeImpersonatePrivilege)。我们可以满足每一个标准,除了有一个——内核检查当前进程的IL是否大于或等于被模拟的令牌。如果进程IL小于令牌的IL,则模拟令牌将被删除到标识级别,从而阻止我们使用它来提升我们的权限。虽然我们不能增加令牌的IL,但我们可以减少它,所以我们需要做的是将令牌IL设置为与模拟之前的过程“IL”相同,理论上我们应该成为中型IL管理员。 在我们这样做之前,需要处理一个小问题,设置IL是一个写操作,而且我们没有对令牌的写访问权限。

然而,事实证明,由于我们有Duplicate,我们可以调用DuplicateToken来克隆整个令牌。我们需要得到一个假冒令牌,需要重复,所以这不是主要的问题。重要的事实是得到的重复的令牌并且给我们读取,写入和执行对令牌对象的访问。由于Token对象的Mandatory Label被设置为调用者的IL(它是Medium),而不是令牌内的IL。这导致内核能够授予我们对新令牌对象的完全访问,这一点令我感到困惑。请注意,这不是给我们写入访问原始令牌,只是一个副本。时间的PoC || GTFO:

$token = Use-NtObject($ps = Get-NtProcess -Name mmc.exe) { Get-NtToken -Primary -Process $ps[0] -Duplicate ` -ImpersonationLevel Impersonation ` -TokenType Impersonation ` -IntegrityLevel Medium } Use-NtObject($token.Impersonate()) { [System.IO.File]::WriteAllText("C:\windows\test.txt", "Hello") }

你应该看到它创建一个文本文件C:Windowstest.txt,内容是Hello。或者,您可以使用New-Service cmdlet来创建一个将以LocalSystem运行的新服务,即使在Medium IL中运行,您仍然是管理员。您可能会尝试仅启用SeDebugPrivilege并直接迁移到系统进程,但如果您的尝试发生了奇怪的事情:

# Will indicate SeDebugPrivilege is disabled $token.GetPrivilege("SeDebugPrivilege").Enabled # Try enabling the privilege. $token.SetPrivilege("SeDebugPrivilege", $true) # Check again, will still be disabled. $token.GetPrivilege("SeDebugPrivilege").Enabled

 您会发现,无论您怎么尝试SeDebugPrivilege(和SeBackupPrivilege,SeRestorePrivilege等)它的功能都无法启用。这是UAC设计师选择的另一个安全措施,实际上并没有什么区别。如果令牌的IL小于High,则无法启用一小组GOD权限。但是,您仍然可以启用像SeMountVolumePrivilege(可能会有一些乐趣)或  SeCreateSymbolicLinkPrivilege的东西。 我们稍后会回到这个行为,因为它是重要的。最重要的是,此行为不会自动禁用Administrators组,这意味着我们仍然可以作为特权用户进行模拟。 只要在Windows Vista,7,8或8.1上运行示例,它就会工作的非常好。但是在Windows 10上,您将收到以下错误:

Use-NtObject : Exception calling "WriteAllText" with "2" argument(s): "Either a required impersonation level was not provided, or the provided impersonation level is invalid.

此错误消息意味着,  SeTokenCanImpersonate  检查检查失败和模拟令牌得到恢复到一个识别标记。很显然,微软知道我们做的一切。所以这就是为什么会有第三部分的原因,让它在Windows 10上工作,并绕过新的安全检测。 

本文翻译自:https://tyranidslair.blogspot.ru/2017/05/reading-your-way-around-uac-part-2.html,如若转载,请注明来源于嘶吼: http://www.4hou.com/info/news/5347.html

点赞 2
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

Change

Change

嘶吼编辑

发私信

发表评论

    llopppp
    llopppp 2017-06-14 16:10

    这坑还是值得的,毕竟一来,别人可以少绕弯路,二来,我觉得下一篇很值得期待啊