Privaten Schlüssel eines Zertifikat aus dem Windows Zertifikatsspeicher exportieren der als „nicht exportierbar“ markiert ist

Manchmal findet sich ein Zertifikat im Windows-Zertifikatsspeicher (Cryptostore), welches man einschliesslich des zugehörigen privaten Schlüssel benötigt.

Beispielsweise kommt das vor bei einer Migration (IIS, Webserver), einem VPN-Service (RRAS) oder Software, die selber eine Schlüsselprüfung durchführen möchte. Windows verbietet allerdings den Export direkt aus dem Cryptostore, unabhängig von den Berechtigungen auf dem Schlüssel.

Die zugehörige Option im Zertifikatsmanager-Assistenten ist daher auch ausgegraut:

Lösung

  1. Windows Defender ausschalten
  2. mimikatz herunterladen (https://github.com/gentilkiwi/mimikatz/releases), am besten den aktuellen trunk
  3. mimikatz „Als Administrator“ ausführen

In mimikatz Ausführen:

privilege::debug

crypto::cng

crypto::capi

crypto::certificates /systemstore:local_machine /store:my /export

Die Ausgabe sollte in etwa wie folgt aussehen:

mimikatz # privilege::debug
 Privilege '20' OK

mimikatz # crypto::cng
 ERROR kull_m_patch_genericProcessOrServiceFromBuild ; kull_m_patch (0x00000000)

mimikatz # crypto::capi
Local CryptoAPI RSA CSP patched
Local CryptoAPI DSS CSP patched

mimikatz # crypto::certificates /systemstore:local_machine /store:my /export
 * System Store  : 'local_machine' (0x00020000)
 * Store         : 'my'

 0. [IIS] <CERTNAME>
    Subject  : CN=<CERT-CN>
    Issuer   : C=<CERT-DATA>
    Serial   : <CERT-SERIAL>
    Algorithm: 1.2.840.113549.1.1.1 (RSA)
    Validity : <CERT-VALID>
    Hash SHA1: <CERT-HASH>
        Key Container  : {<CNG-ID>}
        Provider       : Microsoft RSA SChannel Cryptographic Provider
        Provider type  : RSA_SCHANNEL (12)
        Type           : AT_KEYEXCHANGE (0x00000001)
        |Provider name : Microsoft RSA SChannel Cryptographic Provider
        |Key Container : {<MACHINE CNG ID>}
        |Unique name   : <CERT-NAME>
        |Implementation: CRYPT_IMPL_SOFTWARE ;
        Algorithm      : CALG_RSA_KEYX
        Key size       : 3072 (0x00000c00)
        Key permissions: 0000003b ( CRYPT_ENCRYPT ; CRYPT_DECRYPT ; CRYPT_READ ; CRYPT_WRITE ; CRYPT_MAC ; )
        Exportable key : NO
        Public export  : OK - '<PATH TO DER>'
        Private export : OK - '<PATH TO PFX>'

Und schon findet man die (alle) Zertifikate aus dem lokalen Speicher im Ausführungsverzeichnis.

„Der neue Edge“ Browser von Microsoft download

Microsoft hat den Download des neuen Edge Browsers … versteckt? Oder zumindest wirkungsvoll eingeschränkt. Man kann den Browser auf seiner eigenen Webseite nicht mehr wie gewohnt herunterladen sondern der Button will seinerseits nur noch Edge (?) öffnen (?!?).

Wir sind nicht sicher, ob diese Aktion der Verbreitung des neuen Browser wirklich zuträglich ist 🙄

Wie auch immer, mach ein Admin würde trotzdem gerne Edge auf Windows 10 oder Windows Server 2019 installieren und benötigt daher weiterhin den „MicrosoftEdgeSetup.exe“ Installer. Oder das Edge MSI zur Verteilung im Netzwerk.

Download Microsoft Edge (Setup/MSI)

MicrosoftEdgeSetup.exe (Windows 10/Server 2019) Download: https://go.microsoft.com/fwlink/?linkid=2069324&Channel=Stable&language=de

Microsoft Edge Offline-Installer X64.msi oder X86.msi

IIS ARR Reverse Proxy mit Redirects und Ausnahmen für Let’s Encrypt

Problem

Man möchte einen Webserver hinter einem IIS als „Frontend“ Reverse Proxy via ARR (Application Request Routing) betrieben und dem IIS das SSL-Offloading überlassen.

Der reverse Proxy ist schnell eingerichtet, aber wie vermeidet man, das ein ACME-Tool (beispielsweise win-acme) an der Validierung des Zertifikates scheitert, weil der IIS die Requests an /.well-known/acme-challenge/* ebenfalls an den Webserver weiterleitet?

Lösung

Man verwendet verschiedene Regeln um das zu verhindern. Entweder erstellt man diese im wundervollen IIIS GUI oder bearbeitet die zugehörige web.config:

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />


<!-- Letsencrypt-Ausnahme -->
                <rule name="LetsEncryptException" stopProcessing="true">
                    <match url=".well-known/acme-challenge/*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                    <action type="None" />
                </rule>


<!-- Redirect auf HTTPS -->
                <rule name="Redirect-HTTPS" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="^OFF$" />
                    </conditions>
                    <action type="Redirect" url="https://DEINEDOMAIN.COM/{R:1}" appendQueryString="false" redirectType="Found" />
                </rule>


<!-- Redirect root "/" in Verzeichnis (oft hilfreich bei Tomcat Apps) -->
		<rule name="redirect-to-subdir" stopProcessing="true">
			<match url="^$" />
			<action type="Redirect" url="https://DEINEDOMAIN.COM/DEINVERZEICHNIS/WHATEVER" />
		</rule>


<!-- Reverse Proxy -->
                <rule name="ReverseProxy" stopProcessing="false">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
                    <action type="Rewrite" url="http://INTERNERSERVER:8059/{R:1}" />
                </rule>


            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Word/Excel Fehlermeldung bei Nutzung mehrere OneDrive Konten auf einem Computer

Problem

Verwendet man mehrere OneDrive-Konten auf einem Computer, kommt es gelegentlich zu diesem Fehler, wenn man Dateien aus dem „zweiten“ OneDrive Ordner öffnet. Die Meldung kommt immer, unabhängig ob man die Dateien „on demand“ nutzen möchte oder vollständig synchronisiert hat.

Ihre Änderungen können nicht hochgeladen oder heruntergeladen werden, weil ihre zwischengespeicherten Anmeldeinformationen abgelaufen sind.

Wenn man sich dann anzumelden versucht, wie von Excel so prominent vorgeschlagen, erhält man die Fehlermeldung:

Leider ist an diesem Computer bereits ein anderes Konto aus Ihrer Organisation angemeldet.

Lösung

Das Problem sind die Office-Apps, die direkt versuchen mit dem angemeldeten Benutzer in das „fremde“ OneDrive zu schreiben. Das schlägt natürlich fehl, aber Office ignoriert hier scheinbar (äußerst penetrant) die erfolgte und korrekte Einrichtung als zweites OneDrive.

Glücklicherweise kann man dem OneDrive Client abgewöhnen, die Office-Apps zu konfigurieren. Die Option ist nur etwas seltsam benannt.

OneDrive-Symbol > Einstellungen > Office > „Office-Dateien, die ich öffne, mit Office-Anwendungen synchronisieren“ abschalten

Und schon funktrioniert der Zugriff wieder fehlerfrei – es ist nicht einmal ein Neustart notwendig (außer von den Office-Apps).

Allerdings gehen durch diese Umstellung die synchronen Online-Features verloren, wie die gleichzeitige Bearbeitung einer Datei durch mehrere Benutzer oder das automatische Online-Speichern.

Sonicwall FRITZ!Box Site-to-Site VPN einrichten

Das VPN mit einer Fritz!Box aufzubauen war irritierend umständlich. Die Fritz!Box kann überraschend viel, zeigt das nur leider nicht und ist zumindest in Richtung VPN-Settings nicht wirklich gut dokumentiert. Zugegeben, die Box ist kein „Unternehmensrouter“, aber in Corona-Homeoffice Zeiten muss man nehmen was man kriegen kann 🙂 Auf die Details was und warum ehe ich nicht ein, das hier ist nur die „working config“, wie von uns gewohnt.

In diesem Fall: Sonicwall NSA 3650 und eine aktuelle Fritz!Box. Welche genau weiss ich nicht, aber das ist in weiten Teilena auch egal.

Wichtig: Keines der zu verbindenden Netze darf identisch oder ein Subnetz des anderen sein. Die Fritzbox mag sowas nicht routen und für ein Homeoffice dann noch NAT-Pools einrichten ist … übertrieben.

  • Unternehmen: 192.168.0.0 /16
  • Homeoffice: 10.0.178.0 /24

Sonicwall Seite

Ich nutze der Einfachheit halber eine VPN-Policy, kein Tunnelinterface. Das schöne daran ist, das der Tunnel seine SA’s sofort in die Routingtabelle einträgt, wenn also der Tunnel steht direkt das IP-Netzwerk verfügbar ist.

Ich gehe davon aus, das alle beteiligten Netzwerkobjekte bereits als solche angelegt sind.

VPN Policy auf der Sonicwall hinzufügen

Manage > VPN > Base Settings > Add

  • Security Policy
    • Policy-Type: Site to Site
    • Authentication Method: IKE using Preshared Secret
    • Name: FBox-VPN-42
    • Psec Primary Gateway Name or Address: <IP/DNS der Homeoffice FBox>
  • IKE Authentication
    • Shared Secret: <Supergeheimeskennwort>
    • Local IKE ID: Domain Name : <IP/FQDN der Sonicwall>
    • Peer IKE ID: Domain Name : <IP/FQDN der Fritz!Box>
  • Network
    • Local Networks
      • Choose local network from list: <Objektgruppe der/des Unternehmens-Netzwerke>
    • Remote Networks
      • Choose destination network from list: <Objektgruppe des Homeoffice-Netzes>
  • Proposals
    • IKE (Phase 1) Proposal
      • Exchange: Aggressive Mode
      • DH Group: Group 2
      • Encryption: AES-256
      • Authentication: SHA1
      • Life Time (seconds): 28800
    • Ipsec (Phase 2) Proposal
      • Protocol: ESP
      • Encryption: AES-256
      • Authentication: SHA1
      • Enable Perfect Forward Secrecy Einschalten (!)
      • DH Group: Group 2
      • Life Time (seconds): 3600

FRITZ!Box Seite

Man nutze nicht den „Firmen“ Assistenten, sondern lade die Konfiguration vie „Datei importieren“ hoch. Das geht unter Internet > Freigaben > VPN.

Eine laufende CFG Configfile sieht so aus:

 vpncfg {
        connections {
                enabled = yes;
                conn_type = conntype_lan;
                name = "Tunnel to Northkorea";
                always_renew = yes;
                reject_not_encrypted = no;
                dont_filter_netbios = yes;
                localip = 0.0.0.0;
                local_virtualip = 0.0.0.0;
                remoteip = 0.0.0.0;
                remote_virtualip = 0.0.0.0;
                remotehostname = "<IP/FQDN Sonicwall>";
                localid {
                        fqdn = "<IP/FQDN FRITZ!Box>;
                }
                remoteid {
                        fqdn = "<IP/FQDN Sonicwall>";
                }
                mode = phase1_mode_aggressive;
                phase1ss = "all/all/all";
                keytype = connkeytype_pre_shared;
                key = "<Supergeheimeskennwort>";
                cert_do_server_auth = no;
                use_nat_t = no;
                use_xauth = no;
                use_cfgmode = no;
                phase2localid {
                        ipnet {
                                ipaddr = <NetzID FritzBox-Netzwerk>;
                                mask = <Subnetzmaske FritzBox-Netzwerk>;
                        }
                }
                phase2remoteid {
                        ipnet {
                                ipaddr = <NetzID Unternehmensnetzwerk>;
                                mask = <Subnetzmaske Unternehmensnetzwerk>;
                        }
                }
                phase2ss = "esp-all-all/ah-none/comp-all/pfs";
                accesslist =    "permit ip any <NetzID FritzBox-Netzwerk> <Subnetzmaske FritzBox-Netzwerk>",
                                "permit ip any <NetzID Unternehmensnetzwerk> <Subnetzmaske Unternehmensnetzwerk>";
        }
        ike_forward_rules = "udp 0.0.0.0:500 0.0.0.0:500", 
                            "udp 0.0.0.0:4500 0.0.0.0:4500";
} 

Debian 10 apt-get update „Hash-Summe stimmt nicht überein“

Problem

Es tritt „auf einmal“ der folgende Fehler auf:

Hash-Summe stimmt nicht überein
......
Es wurden 42,42 MB in 42 s geholt (42 MB/s).
Paketlisten werden gelesen... Fertig
E: Fehlschlag beim Holen von ..... Hash-Summe stimmt nicht überein
E: Einige Indexdateien konnten nicht heruntergeladen werden. Sie wurden ignoriert oder alte an ihrer Stelle benutzt.

Lösung

Sofern die Eintröge in der /etc/apt/sources.list korrekt sind, kann es nur apt’s cache sein. Aufräumen hilft in der Regel:

sudo apt-get clean
sudo rm -R /var/lib/apt/lists
sudo mkdir -p /var/lib/apt/lists/partial
sudo apt-get update

Ursache

Die möglichen Ursache sind zwar techinsch vielfältig, lassen sich aber in aller Regel auf eine dieser vier Möglichkeiten eingrenzen:

  1. APT hat andere Metadaten als der server. In den meisten Fällen ist das wegen der Verwendundung von TLS eher unwahrscheinlich, aber möglich.
  2. Der Metadatensatz stimmen aufgrund eines Fehlers beim kopieren/extrahieren/widerherstellen nicht (mehr) überein.
  3. Das Repository wurde von APT genau dann aktualisiert, wenn APT ein Update ausführen wollte, oder APT hat eine veraltete Metadatei zwischengespeichert (die wegen dieses Zugriffskonfliktes nicht entfernt werden konnt).
  4. Die Debian repositories wurden gehackt und der lokale, korrekte, Hash passt nicht zur gehackten Version (unwarscheinlich)

Exchange Abwesenheitsbenachrichtigung (Out of office reply) nur an bekannte Absender zuslassen

Problem

Exchange-Absenheitsbenachrichtigungen (Out of Office replys) sind traditionell ein schwerwiegender Punkt interessanter Diskussionen. Technisch simpel umgesetzt, birgt das Konzept viele Gefahren für schweren Mißbrauch (Amplification-Attack, Spam, Datenschutz, Überwachung, Einbruch …).

Ein oft eingesetzer Kompromiss ist der Versand nur an „bekannte“ Absender. Da dem Exchange aber nicht alle Absender „bekannt“ sind (Exchange kann nachvollziehbarerweise nicht in Echtzeit alle Kontakte in allen Mailboxen durchsuchen) muss das pro Mailbox passieren. Outlook sieht diese Möglichkeit sinnvollerweise auch (als Mailboxsetting) vor. Leider bleibt die Auswahl weiterhin dem „fehleranfälligen“ Benutzer überlassen.

Nur in Outlook: „Jeder außerhalb meiner Organisation“ ist weiterhin anwählbar

Lösung

Die die Einstellung Serverseitig, also pro Mailbox, definiert ist, hilft hier eine Gruppenrichtlinie (GPO) nicht weiter. Diese würde vielleicht Outlook betreffen, aber von OWA und allen anderen E-Mail-Clients ignoriert werden.

Da diese Einstellung aber Pro-Exchange-Mailbox gesetzt wird, kann man via Powershell die gesetzte Einstellung relativ einfach „korrigieren“. Wir haben dazu dieses Script erstellt, das nebenbei auch den „Powershell state: busy“ Fehler umgeht, der auftritt wenn man zu viele Requests an die Exchange-API gleichzeitig sendet (foreach statt einfach |set).

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://MEINSERVER.MEINFQDN/PowerShell/ -Authentication Kerberos
Import-PSSession $Session -AllowClobber
Import-Module ActiveDirectory -ErrorAction STOP

Function ChangeMailboxListWithExternalAudience {
    $MailboxListWithExternalAudience = Get-Mailbox | Get-MailboxAutoReplyConfiguration | where { ($_.AutoReplyState -eq "Enabled") -AND ($_.ExternalAudience -eq "All") }

    foreach ($eintrag in $MailboxListWithExternalAudience) { 
        Set-MailboxAutoReplyConfiguration $eintrag.Identity -ExternalAudience "Known"
    }
}

ChangeMailboxListWithExternalAudience

Das Script wird einfach regelmäßig via „Geplante Aufgaben“ ausgeführt und rediziert so die Angriffsfläche auf einen (relativ) kleinen zeitlichen Versatz.

Bein Einsatz des Scripts auf die ExecutionPolicy achten!