Pass-the-Hash is Dead: Long Live Pass-the-Hash

简介: http://www.harmj0y.net/blog/penetesting/pass-the-hash-is-dead-long-live-pass-the-hash/You ma...

http://www.harmj0y.net/blog/penetesting/pass-the-hash-is-dead-long-live-pass-the-hash/


You may have heard the word recently about how a recent Microsoft patch has put all of us pentesters out of a job. Pass-the-hash is dead, attackers can no longer spread laterally, and Microsoft has finally secured its authentication mechanisms. Oh wait:

pth_kali

This is a fully-patched Windows 7 system in a fully-patched Windows 2012 domain. So what’s going on here, what has Microsoft claimed to do, what have they actually done, and what are the implications of all of this? The security advisory and associated knowledge base article we’re dealing with here is KB2871997 (aka the Mimikatz KB ;)

Besides backporting some of the Windows 8.1 protections that make extracting plaintext credentials from LSASS slightly more difficult, the advisory includes this ominous (to pentesters, at least) statement “Changes to this feature include: prevent network logon and remote interactive logon to domain-joined machine using local accounts…. On the surface, this looks like it totally quashes the Windows pivoting vectors we’ve been taking advantage of for so long, [insert doom and gloom here]. Microsoft even originally titled their original advisory, “Update to fix the Pass-The-Hash Vulnerablity”, but quickly changed it to “Update to improve credentials protection and management”

pass_the_hash_difference

http://www.infosecisland.com/blogview/23787-Windows-Update-to-Fix-Pass-the-Hash-Vulnerability-Not.html

It’s true, Microsoft has definitely raised the bar: accounts that are members of the localgroup “Administrators” are no longer able to execute code with WMI or PSEXEC, use schtasks or at, or even browse the open shares on the target machine. Oh, except (as pwnag3 reports and our experiences confirm) the RID 500 built-in Administrator account, even if it’s renamed. While Windows 7 installs will now disable this account by default and prompt for a user to set up another local administrator, many organizations used to standard advice and compliance still have loads of RID 500 accounts, enabled, all over their enterprise. Some organizations rely on this account for backwards compatibility reasons, and some use it as a way to perform vulnerability scans without passing around Domain Admin credentials.

If a domain is built using only modern Windows OSs and COTS products (which know how to operate within these new constraints), and configured correctly with no shortcuts taken, then these protections represent a big step forward. Microsoft has finally start to wise up to some of its inherent security issues, which I seriously applaud them for. However, the vast majority of organizations are a Frankensteinian amalgamation of security/management products, old (and sometimes unpatched) servers, heterogenous clients, lazy admins, backwards-compatibility-focused engineers, and usability-focused business units.

Regardless, accounts with this security identifier are almost certainly going to be enabled and around for a while. Additionally, Windows 2003 isn’t affected (which will surely linger around organizations significantly longer than Windows XP), and domain accounts which maintain Administrative access over a machine can still have their hashes passed to your heart’s content. Also, these local admin accounts should still work with psremoting if it’s enabled. Some organizations will leave the WinRM service still running as an artifact of deployment, and while you can’t use hashes for auth in this case, plaintext credentials can be specified for a remote PowerShell session.

But let’s say everything’s set up fairly well, the default Administrator account is disabled, and you end up dumping the hash of another local admin user on a box. How is this going to look in the field when you try your normal pivoting, and what options are still open? Your favorite scanner will still likely flag the credentials as valid on machines with the same account reused, as the following examples with the local admin of ‘mike:password’ demonstrates:

smb_login medusa_hydra_scan

However, when you try to use PSEXEC or WMIS to trigger agents or commands, or use Impacket’s functionality to browse the file shares, you’ll encounter something like this:

metasploit_psexec_fail pth_toolkit_fail smbclient_fail

The “pth-winexe” example above shows the difference between invalid credentials (NT_STATUS_LOGON_FAILURE) and the new patch behavior. If you happen to have the plaintext, through group policy preferences, some Mimikatz luck, or cracking the dumped NTLM hashes, you can still RDP to a target successfully with something like rdesktop -u mike -p password 192.168.52.151. But be careful: if you’re going after a Windows 7 machine and a domain user is currently logged on, it will politely ask them if they want to allow your remote session in, meaning this is probably best left for after-hours. Also, interesting note: if you have hashes for a domain user and are dealing with the new restricted admin mode, you might be able to pass-the-hash with rdp itself! The Kali linux guys have a great writeup on doing just that with xfreerdp.

So here we are, with the RID 500 local Administrator account, as well as any domain accounts granted administrative privileges over a machine, still being able to utilize Metasploit or the passing-the-hash toolkit to install agents or execute code on target systems. Seems like it would be useful to be able to enumerate what name the local RID 500 account is currently using, as well as any network users in the local Administrators group. Unfortunately, even if you get access to a basic user account on some target machine and get in a position to abuse Active Directory, you can’t query local administrators with WMI as you might like:

wmi_local_admins

But all hope is not lost, with backwards-compatibility, the bane of Microsoft’s existence, once again coming to our aid. The Active Directory Service Interfaces [ADSI] WinNT provider, can be used to query information from domain-attached machines, even from non-privileged user accounts. A remnant of NT4 domain deployments, the WinNT provider in some cases can allow a non-privileged domain user to query information from target machines, including things like all the local groups and associated members (with SIDs and all). If we have Powershell access on a Windows domain machine, you can try enumerating all the local groups on a target machine with something like:

  • $computer = [ADSI]“WinNT://WINDOWS2,computer”
  • $computer.psbase.children | where { $_.psbase.schemaClassName -eq ‘group’ } | foreach { ($_.name)[0]}

wintnt_local_groups

If we want the members of a specific group, that’s not hard either:

  • $members = @($([ADSI]“WinNT://WINDOWS2/Administrators”).psbase.Invoke(“Members”))
  • $members | foreach { $_.GetType().InvokeMember(“ADspath”, ‘GetProperty’, $null, $_, $null) }

winnt_local_admins

These functions have been integrated into Veil-PowerViewGet-NetLocalGroups and Get-NetLocalGroup respectively:

get_net_localgroupsget_net_localgroup

Another function, Invoke-EnumerateLocalAdmins, has also been built and integrated. This will query the domain for hosts, and enumerate every machine for members of a specific local group (default of ‘Administrators’). There are options for host lists, delay/jitter between host enumerations, and whether you want to pipe everything automatically to a csv file:

enumerate_local_admins

This gives you some nice, sortable .csv output with the server name, account, whether the name is a group or not, whether the account is enabled, and the full SID associated with the account. The built-in Administrator account is the one ending in *-500:

admins_csv

And again, this is all with an unprivileged Windows domain account. If you just have a hash and want the same information without having to use PowerShell, the Nmap scripts smb-enum-groups.nse and smb-enum-users.nse can accomplish the same thing using a valid account for the machine (even a member of local admins!) along a password or hash:

  • nmap -p U:137,T:139 –script-args ‘smbuser=mike,smbhash=8846f7eaee8fb117ad06bdd830b7586c’ –script=smb-enum-groups –script=smb-enum-users 192.168.52.151

nmap_user_group_enum

If you want to use a domain account, set your flags to something like –script-args ‘smbdomain=DOMAIN,smbuser=USER,smbpass/smbhash=X’. You’ll be able to enumerate the RID 500 account name and whether it’s disabled, as well as all the members of the local Administrators group on the machine. If there’s a returned member of the Administrator group that doesn’t show up in the smb-enum-users list, like ‘Jason’ in this instance, it’s likely a domain account.  This information can give you a better idea of what credentials will work where, and what systems/accounts you need to target.

If you have any issues or questions with PowerView, submit any issues to the official Github page, hit me up on Twitter at @harmj0y, email me at will [at] harmj0y.net, or find me on Freenode in #veil, #armitage, or #pssec under harmj0y. And if you’re doing the Blackhat/Defcon gauntlet this year, come check out the Veil-Framework BH Arsenal booth and/or my presentation on post-exploitation, as well as all the other awesome talks lined up this year!

目录
相关文章
|
自然语言处理 算法 数据挖掘
浅谈Single-Pass算法
Single-Pass算法又称单通道法或单遍法,是流式数据聚类的经典方法。对于依次到达的数据流,该方法按输入顺序每次处理一个数据,依据当前数据与已有类的匹配度大小,将该数据判为已有类或者创建一个新的数据类,实现流式数据的增量和动态聚类,适合对流数据进行挖掘,而且算法的时间效率高;不足之处主要表现在该方法具有输入次序依赖特性,即对于同一聚类对象按不同的次序输入,会出现不同的聚类结果。
179 0
【1113】Integer Set Partition (25分)
【1113】Integer Set Partition (25分) 【1113】Integer Set Partition (25分)
84 0
|
关系型数据库 MySQL PHP
laravel5.5报错:1071 Specified key was too long; max key length is 767 bytes
laravel5.5报错:1071 Specified key was too long; max key length is 767 bytes
|
缓存 NoSQL Redis
|
缓存 NoSQL Redis
BITCOUNT key [start end]
统计字符串被设置为1的bit数. 一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。 start 和 end 参数的设置和 GETRANGE 命令类似,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,以此类推。
1308 0
1113. Integer Set Partition (25) 简单题
#include #include #include #include using namespace std; int main() { int n; cin >> n; vector ...
763 0
|
关系型数据库