zabbix身份驗證流程解析&繞過身份驗證的方法


由於實驗室產品的監控模塊的需求,需要繞過zabbix的驗證模塊,實現從二級平台到zabbix的無縫接入。
測試發現,zabbix的身份驗證並不是想象的那么簡單,為了實現功能,遂進行源碼分析。


zabbix常規登陸驗證流程:

分析./include/classes/user/CWebUser.php中的login和logout可以了解到zabbix的常規驗證流程。
主要邏輯如下:

login

  1. 查詢出對應用戶名密碼的user對象
  2. 檢查該用戶登陸嘗試次數是否超出限制
  3. 根據查詢的userid驗證用戶權限,將頁面是否允許訪問存入guiAccess
  4. 登陸方式選擇(ldap、數據庫)
  5. 開始新的session: 生成sessionId,將(sessionId、userid、當前時間、激活狀態)插入數據庫
  6. 根據第3步的guiAccess判斷是否結束並拋出異常
  7. 成功登陸后,清除訪客的session
  8. 將新的sessionId存入cookie
  9. 對該次用戶登錄做審計

logout

  1. 從cookie里得到sessionId
  2. 從數據庫里刪除該登出用戶對應的所有狀態為PASSIVE的session記錄
  3. 將cookie中得到的這個sessionId對應的session記錄的狀態修改為PASSIVE
  4. 從cookie里刪除該sessionId

然而,從一個靜態URL想要繞過登陸直接跳轉到zabbix的某個監控頁面,肯定是不能走這個常規流程,所以,我們以zabbix的監控圖表界面對應的charts.php代碼來理清zabbix對於URL跳轉這類請求的驗證流程。

URL跳轉驗證流程

包括chart.php的幾乎每一個zabbix的展示頁面的php代碼都會在開頭包含一個config.inc.php,且並無其他驗證相關代碼存在,config.inc.php中只有一行主要代碼Z::getInstance()->run(),追蹤到這個run函數里,就能找到疑似的驗證流程入口$this->authenticateUser()
該函數位於 ./include/classes/core/ZBase.php 中。

checkAuthentication

ZBase.php中的函數,是對./include/classes/user/CWebUser.php中同名函數的封裝,CWebUser.php中的checkAuthentication又是對zabbix API即./include/classes/api/services/CUser.php中的同名函數的封裝。

具體流程如下:

  1. 從cookie中取出zbx_sessionid的值存入sessionId
  2. 如果該sessionId不為空,根據這個sessionId查詢出對應的用戶userid、autologout字段和處於ACTIVE狀態session的lastaccess字段,如果sessionId為空,以訪客模式調用login函數並得到新的sessionId,該sessionId對應的GUEST特殊用戶將不能通過后面的權限認證
  3. 如果步驟2沒有查出記錄,那么會報錯Session terminated, re-login, please
  4. 調用check_perm2system檢查該用戶的權限,若有問題,報錯No permissions for system access
  5. 如果查出的記錄的autologout > 0, 刪除數據庫中對應用戶的過期的session
  6. 更新數據庫中當前sessionId和userId對應的session記錄的最近訪問是時間(lassaccess)字段
  7. 檢查該用戶的頁面訪問權限(檢查gui_access,與login流程的驗證guiAccess一樣)
  8. 將userid,sessionid,gui_access存入data變量中
  9. 如果gui_access為GROUP_GUI_ACCESS_DISABLED,即禁用,拋異常,退出。
  10. 將sessionId保存到cookie中
  11. 用sessionId為API設置驗證令牌

分析得出結論,如果要實現在任何環境下的一次URL跳轉都能成功以管理員的權限進入zabbix,關鍵在於以上流程的第2步,不能以訪客模式進入zabbix,即需要讓sessionId不為空且可用,自然得出的辦法就是,提前保存好一個可用的sessionId到cookie中。

多番測試后,證實了以上方案是可行的,於是,實施方案如下:

手動在zabbix增加一個session記錄,每次直接請求URL的時候,先調用一個自定義php,存入這個session的id,再繼續訪問,bingo!


后續發現問題,會回來更新。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM