Přesně tak. PowerShell remoting - tedy příkazy jako je Enter-PSSession, nebo Invoke-Command - je možné provozovat s obyčejnou Kerberos delegací. Tedy delegací s volbou Trust this computer for delegation to any service (Kerberos only). Zatímco s těmi dalšími dvěma možnostmi to nejede.
Nemůže to fungovat ani s Kerberos constrained delegation - Trust this computer for delegation to specified services only (Kerberos only), ani s protocol transition - Trust this computer for delegation to specified services only (Any authentication protoocl).
Proč Kerberos delegace?
PowerShell remoting je k tomu, aby spouštěl příkazy na vzdálených počítačích. Vlastně něco jako telnet. Pripojíte se ke vzdálenému stroji přes HTTPS (obvykle na portu TCP 5985 přes WinRM - Windows Remote Management) a všechno co píšete do konzole se prostě spouští na vzdáleném počítači a k vám se zpátky stahuje už jenom textový výstup.
Ověřovat se do vzdálené sešny jde pomocí Kerberosu, takže nemusíte zadávat žádné přihlašovací údaje a jste prostě tam (SSO - single sign on). Nebo samozřejmě můžete použít nějakou Basic autentizaci, nebo/li CredSSP. To ale znamená, že byste museli při připojení zadávat login a heslo a to třeba nechcete.
Takže se přihlašujeme bez zadávání hesla pomocí Kerberos. Co když na tom vzdáleném stroji potřebujete spouštět příkazy, které chodí ještě na další vzdálený stroj. Tipicky do Active Directory, nebo prostě přes WMI ještě do nějakých vzdálených počítačů? Tak to máte ve výchozím stavu smůlu. To se nazývá double-hop (jeden hop od vás na Enter-PSSession kde běží příkazy a pak druhý hop na ten ještě vzdálenější server). Potřebujete k tomu povolit Kerberos delegaci. Nebo právě zadávat přihlašovací údaje při připojení ručně a to já v tomto scénáři nechci.
Kerberos delegace (Kerberos delegation) je potřeba povolit v Active Directory pomocí výšezmíněných voleb. Ale funguje jenom s tou první - která je relativně horší, než ty dvě další. Kdybych to měl seřadit podle nevhodnosti, tak takto:
- zadávání přihlašovacích údajů při připojení (Basic, nebo CredSSP) - to nejhorší, protože prostřední server může vykrádat hesla z paměti.
- Kerberos un-constrained delegation, neboli Trust this computer for delegation to any service - o něco lepší, protože jdou vykrást jenom Kerberos tikety, které mají přecejenom poněkud časově omezenou platnost a nelze je použít jinde, než uvnitř sítě
- Kerberos protocol transition (S4U2Self), neboli Trust this computer for delegation to specified services only with Any authentication protocol - sice se omezují double-hop (delegované) služby a zadní počítače, ale zase si prostřední stroj může "přihlásit" kohokoliv úplně bez znalosti hesla
- Kerberos constrained delegation (Service-for-User, S4U2Proxy), neboli Trust this computer for delegation to specified services only with Kerberos only - tohle je to nejlepší. Zadní služby jsou omezeny a prostřední útočník pracující jako lokální admin na serveru v podstatě nic nezmůže
Takže pokud si delegaci povolíme, tak to bude lepší, než zadávat plná hesla, ale pořád to nebude tak krásné, jako Kerberos constrained delegation.
Některé další moje články ohledně Kerberos delegace najdete zde, zde a třeba i zde, nebo tady.
Proč to nefunguje s jinou, než s un-constrained delegation?
Pomocí Enter-PSSession se připojujete na vzdálený server, který budu odteď nazývat prostřední server. Na tomhle serveru se připojujete ve skutečnosti do služby Windows Remote Management, která teprve spouští PowerShell plug-in (jenom DLL modul do WinRM), který teprve spouští přes COM proces WSMPROVHOST.exe. Až tento WSMPROVHOST proces ve vykonává vaše PowerShell příkazy.
Proces WSMPROVHOST běží tedy na prostředním serveru, běží pod vaším účtem. To by vypadalo pěkně. Jenže tu je právě ta chyba. Tento WSMPROVHOST proces na prostředním serveru nemá ani vaše heslo, ani žádný váš ani svůj Kerberos TGT tiket. Stačí se podívat pomocí KLIST do jeho logon session. Není asi ani jak mu ho předat přes tři služby.
Kerberos delegace potřebuje, aby prostřední proces (prostřední server) měl v ruce nějaký TGT Kerberos ticket. A to tenhle proces nemá. Nějaký TGT znamená buď TGT toho přistupujícího uživatele, nebo TGT servisního účtu, pod kterým běží ten prostřední server. Bez TGT delegace nefunguje.
Jediná metoda jak mu ho dodat je právě ta Kerberos un-constrained delegace. Tahle metoda totiž do prostředního serveru posílá forwarded TGT (tiket krbtgt s příznakem forwarded) a tím pádem ho prostřední server má k dispozici.
Zatímco ostatní Kerberos delegační metody žádný TGT tiket do prostředního serveru nedodávají. Posílají tam jenom TGS, což k delegaci nestačí. Sám proces WSMPROVHOST si svůj vygenerovat neumí, protože běží přímo pod identitou přistupujícího uživatele a nikoliv pod nějakým servisním účtem. Kdyby běžel normálně pod servisním účtem, měl by svůj TGT a mohlo by to fungovat.