Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lockout / Denial of Service Risks #78

Open
joshfinley opened this issue Nov 8, 2024 · 0 comments
Open

Lockout / Denial of Service Risks #78

joshfinley opened this issue Nov 8, 2024 · 0 comments

Comments

@joshfinley
Copy link

Description:

The tool currently executes password spraying attacks without checking the domain’s bad password count or respecting the observation window. These features are essential to prevent account lockouts and to conduct password spraying safely within domain policies.

Expected Behavior

When performing a password spray:

  1. The tool should retrieve the domain’s bad password count and observation window settings from the Active Directory domain object.
  2. It should check the number of failed login attempts for each user and only attempt a login if it won’t exceed the domain’s bad password count policy within the observation window.

Current Behavior

The tool does not currently check:

  • The bad password count threshold, which could result in unintended account lockouts if exceeded.
  • The observation window for monitoring failed attempts, potentially triggering domain security controls.

Impact

Without these checks:

  • Accounts may get locked due to excessive failed login attempts, representing a significant denial of service risk.
  • The tool risks causing account lockouts and alerting domain security systems to potential brute-force attempts.
  • This behavior reduces the tool's effectiveness in stealthily testing passwords while staying within security thresholds.

Suggested Solution

  1. Implement a pre-check that queries the domain’s password policy (specifically LockoutThreshold and ObservationWindow).
  2. Use this information to throttle attempts per user to stay within domain lockout limits.
  3. Optionally, add a configurable delay or dynamic scheduling based on the observation window.

Example Code

func (k *KerbruteSession) CheckDomainLockoutPolicy(username string) (bool, error) {
	// Example LDAP connection and policy retrieval
	conn, err := ldap.DialURL("ldap://domain-controller")
	if err != nil {
		return false, fmt.Errorf("LDAP connection failed: %s", err)
	}
	defer conn.Close()

	// Bind if needed
	err = conn.Bind("user@domain", "password")
	if err != nil {
		return false, fmt.Errorf("LDAP bind failed: %s", err)
	}

	searchRequest := ldap.NewSearchRequest(
		"dc=domain,dc=com", ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
		"(&(objectClass=domain))",
		[]string{"lockoutThreshold", "lockoutObservationWindow"},
		nil,
	)

	res, err := conn.Search(searchRequest)
	if err != nil || len(res.Entries) == 0 {
		return false, fmt.Errorf("Failed to retrieve lockout policy: %s", err)
	}

	lockoutThreshold := res.Entries[0].GetAttributeValue("lockoutThreshold")
	observationWindow := res.Entries[0].GetAttributeValue("lockoutObservationWindow")
	
	// Convert observation window to time duration
	observationDuration, err := time.ParseDuration(observationWindow + "m")
	if err != nil {
		return false, fmt.Errorf("Failed to parse observation window: %s", err)
	}

	// Implement logic to track failed attempts
	// For example, store a map with username -> failed attempts and timestamps
	// If count exceeds lockoutThreshold within observationDuration, return false

	// Example result if user meets lockout criteria
	return true, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant