Windows 攻擊 for Active Directory(AD) – 學習隨手筆記

寫在前面

這篇文章是先前學習Windwos攻防手法時的筆記。當時是針對AD/SMB/Windows提權等各種知識/技術/工具學習,但後來內容越來越多,決定將其切分,Active Directory(AD)自成一格。此篇內容純粹屬於隨手筆記,許多內容都是屬於自己學習時的memo,不能保證其知識正確性以及完整性。更多的內容是補上要了解該手法時可以參考的文章連結,或是轉貼其他人的文章內容,筆記中都有附上來源網址。雖然可能不夠嚴謹、齊全、正確,但也許能夠幫助到有在學習AD攻防的人。如果要更正確完整的深入了解AD,可以參考官方文件、相關書籍、知名網站的教學、資安專家開設的課程等等。

(PS: 此文章可能會滾動式更新)

Windows攻擊:Active Directory(AD)

What is AD

Ref:
https://kuang1984tw.pixnet.net/blog/post/152347486 https://searchwindowsserver.techtarget.com/definition/Active-Directory
http://120.105.184.250/peiyuli/network-1/Active Directory.htm

甚麼是AD

一個中大型企業,員工人數眾多,其中使用者帳戶、用戶端電腦、工作站、伺服器、儲存設備、印表機等數量與日俱增,為了方便統一集中控管、簡化管理工作、加強網路安全性,於是 Active Directory(簡稱 AD)這概念就出現。

AD 最小儲存單元為物件(Object),每個物件均有自己的 schema 屬性,可以儲存不同的資料,像是使用者、群組、電腦、信箱或其他的基本物件等。

所有 AD 物件均具有全域唯一識別元(GUID,Globally Unique Identifier)與存取控制清單(ACL,Access Control List)等兩項特性,物件的 GUID 永遠不會改變,無論物件的名稱或屬性如何變更,應用程式仍可透過 GUID 找到物件。

容器(Container)並不是一個實體,雖然他跟物件很類似,但容器可以包含一群物件,預設會有以下 5 種容器(Container):

Builtin:存放本機內建的帳戶群組
Computers,存放加入網域的電腦物件
Domain Controllers,存放網域控制站(簡稱 DC)
ForeignSecurityPrincipals:存放來自信任關係網域的物件
Users:存放網域內使用者帳戶與群組

工作群組 (Workgroup)

工作群組泛指一群以網路相連的電腦,彼此分享對方資源 (檔案或印表機),亦可稱「對等式 (peer-to-peer)」網路架構。在工作群組中,每一台電腦的地位皆平等, 它們的資源與管理分散在各台電腦,只有登記在電腦本機安全帳戶資料庫 (簡稱 SAM 資料庫) 的使用者, 才能合法登入使用該電腦的資源。每部電腦亦有權決定要開放那些資源給其他電腦使用者,不同的電腦採用同一個工作群組名稱,便可結合起來構成一個網路系統。

工作群組較適合小型的網路系統,在工作群組中,資料的傳送是採用每隔一段時間將資訊廣播出去, 其他電腦透過「檔案總管」或「網路上的芳鄰」來接收訊息;若是較大的系統使用工作群組架構,則可能會在廣播時碰到塞車情形,反而會造成資料的傳遞效能降低。 也因為帳戶管理分散在各電腦,安全管理也就較脆弱且繁瑣,如果有使用者密碼洩漏需要更改,此時必須將所有建立此使用者帳戶之電腦中的密碼全部更改,否則將造成無法登入或被他人侵入使用的情形。

網域 (Domain)

不同於工作群組,網域是由一群共用同一份 AD 資料庫的電腦所組成的集合 (如下圖),網域為 AD 的分割單位,AD 是由至少一個網域所構成的集合。在 Windows Server 2003 R2 的網路環境,各網域至少要有一部網域控制站 (DC, Domain Controller) 儲存此 AD 資料庫,並提供網域相關服務,例如:登入驗證、名稱解析等。 沒有 DC,就沒有所謂的網域。在一個網域中可設置多台 DC,以提高網域的容錯能力,彌補某一台 DC 故障時,還有其他 DC 可維持網域的運作,不致造成網域全面停擺;另外也可以改善使用者登入的效率,因為多台 DC 可以分攤驗證使用者身份的負擔。
 
由於網域中所有的 DC 具有相同的 AD 資料庫,網管人員可以在任一台 DC 上修改 AD 資料庫,DC 與 DC 之間會定期 (預設 5 分鐘) 進行資料庫資料複製,以確保 AD資料庫的一致性。網域內複寫的資料傳輸量會隨 DC 的數目增加,因此在新增 DC 時,必須考慮網路頻寬負荷的問題。

在 Windows Server 2003 網域中的電腦,可依使用功能區分為下列三種類型:

網域控制站:儲存、維護 AD 資料庫的電腦。換句話說,網域控制站必須安裝 Active Directory。

成員伺服器 (Member):安裝 Windows 2000 Server 或 Windows Server 2003 系統,但並非網域控制站 (沒有安裝 Active Directory)。

※ 未加入網域的伺服器級電腦統稱作獨立伺服器。

用戶端:安裝 Windows 95/98/XP/2000 Professional 等系統之電腦,可以存取網域中的資源。

Difference between LDAP and Active Directory

LDAP是目錄數據的協議規範。

Active Directory是基於LDAP的目錄伺服器的微軟實現。

Active Directory不僅僅是微軟的LDAP實現,它只是AD的一小部分,Active Directory是(以一種過於簡化的方式)提供基於Kerberos授權的基於LDAP的身份驗證的服務。

Kerberos

Ref:
https://linux.vbird.org/events/kerberos.php
https://hackmd.io/@Uc4Mk1KjQrGM9Bv1DoK8Cw/r1tKZ_ITg?type=view
http://www.tsnien.idv.tw/Security_WebBook/第十四章 Kerberos 認證系統.html
https://www.geeksforgeeks.org/kerberos/

基本概念 Kerberos六個步驟

  1. AS_REQ
  2. AS_REP
  3. TGT_REQ
  4. TGT_REP
  5. AP_REQ
  6. AP_REP

kerberos 就是一種計算機網路的授權協議,可以用在非安全的網路環境中, 對個人通信以安全的手段進行身份認證。同時,客戶端與伺服器端均可向對方進行身份認證,因此可用於防止竊聽,保護資料完整性的應用中。 基本上, kerberos 是透過對稱式金鑰的方式來進行資料加密的,與 ssh 的非對稱式金鑰不同喔!不過,至少都有加密的用途!

在 kerberos 的運作中,首先整個 kerberos 系統就需要一部『可信賴的第三方』,這一台 server 是大家都信任的, 這是一個大前提!也就是說,大家都得要承認,只要是這部 server 驗證成功的,那就是合法的一個成員。 這部大家都公認的第三方 server 定義上被稱為金鑰分發中心 (Key Distribution Center, KDC)。

那麼在整個架構裡面,到底是如何達成資料加密的呢?首先有個大前提,就是所有的主機 (不論是 server 端還是 client 端) 都需要加入 kerberos 服務內, 所有的主機都必須要向 kerberos KDC 請求一個票據 (ticket),且 KDC 必須要針對這個要求的來源設定好相對應的規則設定 (principal), 因此所有的主機就能夠根據這個對應的票據來跟 KDC 驗證後,並要求給予加密的金鑰資料了。

流程

現在有一個client 以及server,client要如何去做驗證呢?
kerberos提出一個authentication server 以下簡稱AS
這個在這邊是個很重要的腳色,他處於第三方幫忙認證,
client會將三樣資料交給AS,
client ID ,client password,server ID,
而AS做了以下的檢查

  • client 的ID password是否正確
  • 他是否有權利可以access 他提出的server

如果都有的話,AS將會回傳一個ticket給client, 此ticket包含了以下資訊

  • client ID
  • network address
  • server ID

而AS與server,有一隻他們獨有的key(因為可能這個AS同時有很服務很多個server),而這個ticket將會被加密藉由這支key

當有了這ticket,client將能把ticket以及自己的ID送至server

  • client ID
  • ticket

由server解密後(只有server能解密)看裡面的認證以及client的ID是否吻合,是的話接著就能提供服務

TGS概念

但是其實還是有很多問題存在

舉一個例子,假設A想要access Mail server但ticket有效次數只有一次(用完即失效),等於是他每次要access一次就需要再輸入一次密碼,很不方便!!
好這時你會說,那就讓AS跟server說好ticket的有效期限為一天,這一天中你都可以任意使用服務阿~
下個問題就來了,那如果有各種其他的服務要使用我是不是也都要各輸入一次帳密(沒錯…人類的意見就是這麼多)
為了解決這個問題,我們將引入ticket-grating server(TGS
)的概念,AS仍然需要喔!

首先client將自己的ID以及某一台TGS的ID,送出給AS,AS收到後,根據自己的資料庫(他當然會有client的帳密對照表),利用client的密碼去加密回傳的ticket.tgs(這邊特別強調是TGS的ticket),這樣一來,正常情況下只有client能查看這個ticket.tgs(因為client一定知道自己的密碼XD 用密碼去解密)
此ticket.tgs包含了以下的東西

  • client ID
  • network address of c
  • tgs ID
  • timestamp1(紀錄產生的時間)
  • lifetime1(有效期限)

重要的是,ticket.tgs還被加了一層密,用只有AS跟TGS知道的K密鑰(也就是說當你拿到手上的ticket.tgs被加了兩層拉~一層是用你的密碼,一層就是用這個key),用以確保只有你本人能用這支ticket
這時client會在將以下送至TGS獲取ticket.service(要用來access server用的)

  • client ID
  • Server ID
  • ticket.tgs

TGS在驗證你的client ID以及ticket.tgs裡面的client ID是否吻合,還有timestamp,與lifetime(他要先解密),會回傳
ticket.service給client,這裡面包含

  • client ID
  • network address of c
  • server ID
  • timestamp2
  • lifetime2

一樣,TGS會利用他與server共用的key去加密,只有server能解密,之後client再將這隻ticket.service送去server 讓server解密後並看看裡面的資料是否都吻合,是的話就能提供服務囉~

timestamp

那至於為何要timestamp?這是在client用自己的密碼解密後送出,這之中有人設法取到你的ticket.tgs(client已解密)他就能假裝成是你,利用他,所以利用timestamp就能查看說,你怎麼在過了這麼久之後才來找我?你可能不是本人,就會拒絕你,但因此你需要注意時間同步問題

然後我們討論一下lifetime的議題,若lifetime時間太長,攻擊指很有可能竊聽你的ticket用來access你的server,但太短,使用者又必須一直輸入密碼

這時我們必須加入最後一項認證機制 除了驗證這個ticket之外,你還必須驗證是誰在用這ticket

所以認證步驟再重新更新一遍(筆者覺得好累…)

第一步一樣
Client->AS送出了

  • client ID
  • TGS server ID
  • TS1(timestamp)

而AS->Client 回傳了

  • E(K_c [K_c,tgs | TGS server ID |TS2 |lifetime2 | ticket_tgs])這邊第一個K_c指的是以下都用K_c加密(Kc為client的password)後面有相關的以此類推
  • 其中 ticket_tgs裡含了
    E(K_tgs,[K_c,tgs | clientID | network address | TGS server ID |timestamp2| lifetime2])

好到這邊,是不是有點亂了,大家麻煩手邊還是有個紙筆慢慢看會比較好,其中這k_c,tgs這支key等等才會用到,只有當client解密了
K_c才看到到,
好接下來再繼續將ticket送到TGS

  • Client->TGS
    • server ID
    • ticket_tgs
    • Authenticator(用來說明自己真的是這個ticket的主人)
      • 其中Authenticator裡面包含了
      • E(K_c,tgs [client ID | netwrok access | timestamp3 ])

這邊就注意到,剛剛的K_c,tgs被用來加密,只有tgs知道這是來自於哪個client,再加上timestamp可以防禦有人拿你的ticket來假冒你,等於是做到雙重保護(1.你就是本人2.時間過太久會不讓你access)

  • TGS->Client
    • E(K_c,tgs[K_c,v | Client ID | timestamp3 |ticket_v])
      • 其中ticket_v裡面有
        • E(K_v,[K_c,v | client ID | network address | TGS ID | timestamp4| lifetime4])
          這邊的K_c,v的概念就跟K_c,tgs一樣,我就不重覆再說一次了,往上找就可以看到了

最後

  • Client->Server
    • Ticket_v|Authenticator
      • 其中Authenticator為
      • E(K_c,v[client ID|network access | timestamp5])
  • Server->Client
    • E(K_c,v[Timestamp5])

這樣就大功告成了,雖然這樣真的很複雜,但就是安全度跟方便性都在提升一個層次,透過一階段一階段說明也會比較能搞清楚為何要這樣去跑流程,比起一開始直接看最後一個XD

LM, NTLM, Net-NTLMv2

LM-hashes 早期儲存密碼的HASH演算法

  1. Convert all lower case to upper case
  2. Pad password to 14 characters with NULL characters
  3. Split the password to two 7 character chunks
  4. Create two DES keys from each 7 character chunk
  5. DES encrypt the string “KGS!@#$%” with these two chunks
  6. Concatenate the two DES encrypted strings. This is the LM hash.

容易crack

  • NTHash (A.K.A NTLM)
    MD4(UTF-16-LE(password))
  • NTLMv1 (A.K.A Net-NTLMv1)
    challenge/response
  • NTLMv2 (A.K.A Net-NTLMv2)
    整個概念跟 NTLMv1 一樣,只有送回伺服器的演算法與回應不同。

發佈留言