* 사업 등 관련 문의: T) 02-322-4688, F) 02-322-4646, E) info@wikisecurity.net

Active Directory bad password 계정진단 Script(Powershell)

- Active Directory는 조직내의 자원에 대한 접근통제를 위해 기업이나 기관의 규모와 상관없이 많이 사용되고 있습니다.
- 그러나 Active Directory의 서비스 특성을 고려한 보안진단을 하는 곳은 아직까지 드문것으로 보입니다.
- Active Directory 보안진단의 중요 포인트는 Domain Controller, Group Policy, User Account, Event Log 등이 있습니다.
- 최근 글로벌 조직의 Active Directory를 운영하는 고객사에 대한 취약점 진단에는 Ad User 계정을 중점적으로 진단하였으며 주목할만한 문제점들이 발견되었습니다.
- AD User에는 주목할만한 Security Attribute 들이 여러개 있으며, 이를 이용한 점검 포인트(시나리오)들은 여러개 도출이 됩니다.
- 아래 간단한 스크립트는 Account Security Attribute 중 하나인 badPwdCount를 이용하여 지정한 횟수 이상의 bad password를 시도한 AD User를 조회하여 csv파일로 만드는 스크립트입니다.
- badPwdCount값이 높을수록 해당 Account는 password guessing공격을 당하고 있을 가능성이 높기 때문에 계정의 기본정보를 비롯하여 Last Logon 등을 예의주시할 필요가 있다.

[ PowerShell version 1 ]

 # BadPwdAccounts.ps1 
 Import-Module ActiveDirectory
 
 # badPwd 횟수(최소값) 입력
 $wiki = Read-Host -P ">>> Please INPUT ex)10 "
 
 # 현재 DC 정의
 $D = [system.directoryservices.activedirectory.Domain]::GetCurrentDomain() 
 $PDC = $D.PdcRoleOwner 
 $Domain = [ADSI]"LDAP://$D" 
 $csvFile = ".\the_Results.csv"
  
 # DirectorySearcher 속성 정의
 $Searcher = New-Object System.DirectoryServices.DirectorySearcher 
 $Searcher.PageSize = 200 
 $Searcher.SearchScope = "subtree" 
 $Searcher.Filter = "(badPwdCount>=" + $wiki + ")"
 
 # 필터링 속성 정의 
 $Searcher.PropertiesToLoad.Add("distinguishedName") > $Null 
 $Searcher.PropertiesToLoad.Add("sAMAccountName") > $Null 
 $Searcher.PropertiesToLoad.Add("badPwdCount") > $Null 
 $Searcher.PropertiesToLoad.Add("badPasswordTime") > $Null 
 $Searcher.PropertiesToLoad.Add("logonCount") > $Null  
 
 # Dataset 초기화
 $csvCont = @()
 $csvCont += "no;sAMAccountName;badPwdCount;logonCount;badPasswordTime;distinguishedName `r`n" 
 
 # Dataset 조회
 ForEach ($DC In $D.DomainControllers) 
 { 
     $Server = $DC.Name 
     $Results = $Null
 	$i = 0
 	$csvCont = "=== DC: $Server (PDCe) `r`n"
 	
     $Base = "LDAP://$Server/" + $Domain.distinguishedName 
     $Searcher.SearchRoot = $Base 
     $Results = $Searcher.FindAll() 
 	
 	If($Results) 
     { 
         ForEach ($Result In $Results) 
         {
 			$i += 1
 			$DN = $Result.Properties.Item("distinguishedName") 
 			$NTName = $Result.Properties.Item("sAMAccountName") 
 			$BadCount = $Result.Properties.Item("badPwdCount") 
 			$LogonCount = $Result.Properties.Item("logonCount") 
 			$Time = $Result.Properties.Item("badPasswordTime") 
 			$BadTime = ([DateTime]$Time.Item(0)).AddYears(1600).ToLocalTime()
 			$csvCont += "$i;$NTName;$BadCount;$LogonCount;$BadTime;""$DN"" `r`n"					
 		} 
     } 
     Else 
     { 
         Write-Host "ERROR: Connection fail($Server)"
         "<DC not found>" 
     } 
 	
 	# 엑셀파일로 출력
      $csvCont += ">> The number of AD User accounts that attempt to have bad password over " + $wiki + " times is " + $i + ". `r`n"
      $csvCont | out-file $csvFile -encoding UTF8
 }