본문 바로가기

보안/시스템 보안

주통기 기반 윈도우즈 서버 취약점 점검(W-01, W-02, W-04, W-06)

https://www.kisa.or.kr/2060204/form?postSeq=12&lang_type=KO&page=1 

 

KISA 한국인터넷진흥원

 

www.kisa.or.kr

 

 

* 실습 환경 : Windows Server 2019

* 스크립트 코드 : ChatGpt의도움 받음 

 

[W01] Administrator 계정 이름 변경 또는 보안성 강화

취약점 개요

점검 내용
  • 윈도우즈 최상위 관리자 계정인 Administrator의 계정명 변경 또는 보안을 고려한 비밀번호 설정 여부 점검
⇒ 최상위 관리자 계정명을 Administrator로 사용 X  혹은 
사용하더라도 긴 비밀번호 사용. 
점검 목적
  • 윈도우즈 기본 관리자 계정인 Administrator의 이름을 변경 또는 보안을 고려한, 잘 알려진 계정을 통한 악의적인 패스워드 추측 공격을 차단하고자 함
보안 위협
  • 일반적으로 관리자 계정으로 잘 알려진 Administrator를 변경하지 않은 경우 악의적인 사용자의 패스워드 추측 공격을 통해 사용 권한 상승의 위험이 있으며, 관리자를 유인하여 침입자의 액세스를 허용하는 악성코드를 실행할 우려가 있음 
  • 윈도우즈 최상위 관리자 계정인 Administrator는 기본적으로 삭제하거나 잠글 수 없어 악의적인 사용자의 목표가 됨
참고 ※ 윈도우즈 서버는 Administrator 계정을 비활성화 할 수 있으나 안전 모드로 컴퓨터를 시작할 경우 본 계정은 자동으로 활성화 됨

점검 대상 및 판단 기준

대상 Windows NT, 2000, 2003, 2008, 2012, 2016, 2019 
판단 기준
  • 양호 : Administrator Default 계정 이름을 변경하거나 강화된 비밀번호를 적용한 경우

  • 취약 : Administrator Default 계정 이름을 변경하지 않거나 단순 비밀번호를 적용한 경우
조치 방법 Administrator Default 계정 이름 변경 및 보안성이 있는 비밀번호 설정

 

점검 스크립트 및 실행 결과

[알고리즘 설계 ]
if 최상위 관리자 명==Administrator: 
	if (pw_length <= 8 or
	pw = 소문자로만 or
	pw = 대문자로만 or
	pw = 숫자로만 ) :
	print (“비밀번호 혹은 계정명을 바꾸시오”)
else : 
“안전“출력

[출력]
상태  			자세한 설명 
—----			—-----	
안전			안전함
불안전			비밀번호 길이가 짧습니다.
[스크립트]
# 관리자 계정 이름 설정
$adminAccount = "Administrator"

# 현재 로그인된 계정 확인
$currentAccount = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name.Split('\')[-1]

# 사용자로부터 비밀번호 입력
if ($currentAccount -eq $adminAccount) {
    Write-Output "최상위 관리자 계정이 감지되었습니다: $currentAccount"
    
    # 비밀번호 입력 받기
    $password = Read-Host -AsSecureString "비밀번호를 입력하세요"
    $passwordPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))

    # 비밀번호 조건 검사
    $issues = @()  # 조건 위반 사항을 저장할 배열

    if ($passwordPlain.Length -le 8) {
        $issues += "비밀번호가 너무 짧습니다."
    }
    if ($passwordPlain -cmatch "^[a-z]+$") {
        $issues += "비밀번호가 소문자로만 이루어져 있습니다."
    }
    if ($passwordPlain -cmatch "^[A-Z]+$") {
        $issues += "비밀번호가 대문자로만 이루어져 있습니다."
    }
    if ($passwordPlain -cmatch "^[0-9]+$") {
        $issues += "비밀번호가 숫자로만 이루어져 있습니다."
    }

    # 결과 출력
    if ($issues.Count -gt 0) {
        Write-Output "불안전: 비밀번호 정책 위반 사항이 감지되었습니다."
        foreach ($issue in $issues) {
            Write-Output $issue
        }
    } else {
        Write-Output "안전: 비밀번호가 모든 조건을 충족합니다."
    }
} else {
    Write-Output "현재 계정($currentAccount)은 최상위 관리자 계정이 아닙니다."
    Write-Output "안전: 추가 검사가 필요하지 않습니다."
}

[실행 화면]

[W02] Guest 계정 비활성화

취약점 개요

점검 내용
  • Guest 계정 비활성화 여부 점검 
점검 목적
  • Guest 계정을 비활성화 하여 불특정 다수의 임시적인 시스템 접근을 차단하 기 위함
보안 위협
  • Guest 계정은 시스템에 임시로 액세스해야 하는 사용자용 계정으로, 이 계정을 사용하여 권한 없는 사용자가 시스템에 익명으로 액세스할 수 있으므로 비인가자 접근, 정보 유출 등 보안 위험이 따를 수 있음
참고 ※ 윈도우즈 Guest 계정은 삭제가 불가능한 built-in 계정으로 보안 강화 목적으로 반드시 비활성화 처리 하여야 함



점검 대상 및 판단 기준

대상 Windows NT, 2000, 2003, 2008, 2012, 2016, 2019
판단 기준
  • 양호 : Guest 계정이 비활성화 되어 있는 경우 
  • 취약 : Guest 계정이 활성화 되어 있는 경우
조치 방법 Guest 계정 비활성화





점검 스크립트 및 실행 결과

[알고리즘 설계]
value = “ ”
if 게스트 계정 == 활성화 : 
	value = ‘O’ 
else:
	value =’X’

print( “  name           접근 가능 /\”)
print (account , value)


[출력 ]
name            접근 가능 
—------	-	—------
guest		O
[스크립트]
# 게스트 계정 이름
$guestAccount = "Guest"

# 게스트 계정 상태 확인 함수
Function Check-GuestAccountStatus {
    try {
        # Get-LocalUser 명령을 사용하여 계정 정보 가져오기
        $guest = Get-LocalUser | Where-Object { $_.Name -eq $guestAccount }

        # 상태 확인
        if ($guest -ne $null) {
            if ($guest.Enabled -eq $true) {
                return "O"  # 활성화 상태
            } else {
                return "X"  # 비활성화 상태
            }
        } else {
            return "계정 없음"  # 게스트 계정이 삭제된 경우
        }
    } catch {
        Write-Output "오류: Get-LocalUser 명령을 실행할 수 없습니다."
        return "점검 필요"
    }
}

# 게스트 계정 상태 확인
$status = Check-GuestAccountStatus

# 출력
Write-Output "name            접근 가능"
Write-Output "---------------------------"
Write-Output "$guestAccount       $status"

 

[실행 결과]

 

[W04] 계정 잠금 임계값 설정

취약점 개요

점검 내용
  • 계정 잠금 임계값의 설정 여부 점검
점검 목적
  • 계정 잠금 임계값을 설정하여 공격자의 자유로운 자동화 암호 유추 공격을 차단하기 위함
보안 위협
  • 공격자는 시스템의 계정 잠금 임계값이 설정되지 않은 경우 자동화된 방법을 이용
→ 모든 사용자 계정에 대해 암호 조합 공격을 자유롭게 시도할 수 있으므로 사용자 계정 정보의 노출 위험이 있음
참고 ※ 계정 잠금 임계값 설정은 사용자 계정이 잠기는 로그인 실패 횟수를 결정하며 잠긴 계정은 관리자가 재설정하거나 해당 계정의 잠금 유지 시간이 만료되어야 사용할 수 있음 

계정 잠금 정책: 해당 계정이 시스템으로부터 잠기는 환경과 시간을 결정하는 정책으로 ‘계정 잠금 기간’, ‘계정 잠금 임계값’, ‘다음 시간 후 계정 잠금 수를 원래대로 설정’ 의 세가지 하위 정책을 가짐 

※ 관련 점검 항목 : W-47(중)

 

점검 대상 및 판단 기준

대상 Windows NT, 2000, 2003, 2008, 2012, 2016, 2019
판단 기준 양호 : 계정 잠금 임계값이 5 이하의 값으로 설정되어 있는 경우 취약 : 계정 잠금 임계값이 6 이상의 값으로 설정되어 있는 경우
조치 방법 계정 잠금 임계값을 5번 이하의 값으로 설정

 

점검 스크립트 및 실행 결과

[알고리즘]
1. 시스템의 모든 계정 불러오기
2. 각각의 계정마다 임계값 점검


if ( 계정 임계값 <=5) :
	result = '양호'
else : 
	result = '취약'



print(계정명        임계 값           양호/취약)
print("===========================")
print(계정이름     value              result)
[스크립트]
# 출력 인코딩 설정
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 함수: 계정 잠금 임계값 확인
Function Get-AccountLockoutThreshold {
    # 계정 잠금 임계값 확인 (로컬 보안 정책에서 가져옴)
    $lockoutThreshold = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "LockoutThreshold" -ErrorAction SilentlyContinue).LockoutThreshold

    if ($null -eq $lockoutThreshold) {
        return 0 # 임계값이 설정되지 않은 경우 기본값 0 반환
    } else {
        return $lockoutThreshold
    }
}

# 함수: 모든 로컬 계정 목록 가져오기
Function Get-AllAccounts {
    Get-LocalUser | Where-Object { $_.Enabled -eq $true } # 활성화된 계정만 가져옴
}

# 계정 잠금 임계값 가져오기
$lockoutThreshold = Get-AccountLockoutThreshold

# 결과 테이블 출력
Write-Output "계정명           임계 값           양호/취약"
Write-Output "========================================="

# 각 계정에 대해 결과 출력
foreach ($account in Get-AllAccounts) {
    # 임계값 평가
    if ($lockoutThreshold -le 5 -and $lockoutThreshold -gt 0) {
        $result = "양호"
    } else {
        $result = "취약"
    }

    # 출력
    Write-Output "$($account.Name)           $lockoutThreshold               $result"
}

 

[실행 결과]

  • 0이라는 것은 임계값이 비설정 되어있음을 의미

 

[W06] 관리자 그룹에 최소한의 사용자 포함 

취약점 개요

점검 내용
  • 관리자 그룹에 불필요한 사용자의 포함 여부 점검
점검 목적
  • 관리자 그룹 구성원에 불필요한 사용자의 포함 여부를 점검하여, 관리 권한 사용자를 최소화 하고자 함
보안 위협
  • Administrators와 같은 관리자 그룹에 속한 구성원은 컴퓨터 시스템에 대한 완전하고 제한 없는 액세스 권한을 가지므로, 사용자를 관리자 그룹에 포함 시킬 경우 비인가 사용자에 대한 과도한 관리 권한이 부여될 수 있음
참고 ※ 관리 권한의 오남용으로 인한 시스템 피해를 줄이기 위해서 관리 업무를 위한 계정과 일반 업무를 위한 계정을 분리하여 사용하는 것이 바람직함

 ※ 시스템 관리를 위해서 관리권한 계정과 일반권한 계정을 분리하여 운영하는 것을 권고

 ※ 시스템 관리자는 원칙적으로 1명 이하로 유지하고, 부득이하게 2명 이상의 관리 권한자를 유지하여야 하는 경우에는 관리자 그룹에는 최소한의 사용자만 포함하도록 하여야 함



점검 대상 및 판단 기준

대상 Windows NT, 2000, 2003, 2008, 2012, 2016, 2019
판단 기준
  • 양호 : Administrators 그룹의 구성원을 1명 이하로 유지하거나, 불필요한 관리자 계정이 존재하지 않는 경우 

  • 취약 : Administrators 그룹에 불필요한 관리자 계정이 존재하는 경우
조치 방법 Administrators 그룹에 포함된 불필요한 계정 제거

 

 

점검 스크립트 및 실행 결과

if Admingroup_Num > 1 : 
	result = "취약"
	print ="사용자 수가 너무 많습니다. 조치권고"
else : 
	result = "양호" 


print("계정명           취약/조치")
print("=================")
print(계정명      result)
[스크립트]
# 관리자 그룹 이름 설정
$admin_group = "Administrators"  # Windows의 기본 관리자 그룹 이름

# 관리자 그룹에 포함된 사용자 수 확인
$admin_group_members = Get-LocalGroupMember -Group $admin_group
$admin_group_num = $admin_group_members.Count

# 사용자 수에 따른 결과 처리
if ($admin_group_num -gt 1) {
    $result = "취약"
    Write-Output "사용자 수가 너무 많습니다. 조치권고"
} else {
    $result = "양호"
}

# 결과 출력
Write-Output "계정명           취약/조치"
Write-Output "================="
Write-Output "$admin_group      $result"

 

 

[실행 결과]

 

 

 

 

 

참고 : https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/get-localuser?view=powershell-5.1 

 

Get-LocalUser (Microsoft.PowerShell.LocalAccounts) - PowerShell

The Get-LocalUser cmdlet gets local user accounts. This cmdlet gets default built-in user accounts, local user accounts that you created, and local accounts that you connected to Microsoft accounts. Note The Microsoft.PowerShell.LocalAccounts module is not

learn.microsoft.com