關於PHP安全配置繞過問題的一些說明

  前幾天在wooyun上發佈了個漏洞:WooYun: PHP safe_mode等安全配置繞過
  這裏有一些有意思的地方,主站不方便討論,發到zone裏做一些補充說明。
  1、這個問題不是個新問題,其實就是我去年在zone裏發的“PHP FastCGI 的遠程利用”這 個問題。只是去年的問題場景是遠程利用,需要管理員將其配置在外網。當時這個問題提交PHP官方,官方認爲這是個個人配置錯誤的問題,無需修補。這一點我 也承認,但是官方沒有關注到問題本質,實際上這是兩個問題的複合造成的漏洞,一個是fpm本身不知道發起請求的另一方是否真的是webserver,另一 個是fpm允許通過這個請求傳遞參數修改php.ini中的配置。於是這一次我換了一種場景,也就是在雲平臺或者其他共享主機平臺中,允許運行客戶提交的 腳本,而這個fcgi雖然是在本機的9000端口,不對外,但是也可以利用此問題繞過原本進行安全限制的safe_mode/open_basedir等 限制。
  2、disable_functions/disable_classes無法通過此方法進行繞過。這個問題本來想在漏洞提交時候就寫明的,但是修改漏洞後不知到爲什麼wooyun沒有審覈通過,因此現在的版本中沒有附加這個說明。
  在php-fpm.conf中,我們可以看到這樣一段話:
  
  也就是說,如果你通過fpm進行修改disable_functions/disable_classes的值,是不會覆蓋原有的配置,而只是在原有配置基礎上再disable你所添加的函數或者類。
  是不是PHP預先考慮到了這裏存在安全問題,纔會做的限制?實際上並不是這樣。這個和 disable_functions/disable_classes的實現方式有關。如果你願意閱讀一下PHP的源代碼,會發現在php的實現中,內置 函數和內置類其實都是在內存中維護了兩個hash列表,存放着函數的地址。在php進程剛開始運行時,就讀取了php.ini的配置。
  這時候就會按照disable_functions/disable_classes的配置,去函數和類的hash列表中刪除對應的內容。
  
  因此,如果你後續再用fpm的php_value等方式之類內容去修改disable_functions/disable_classes的值,這時候原有的函數已經被刪除了,無法再進行恢復,因此新來的值只能附加上去,而不是恢復->替代。
  3、正如我在1中所說,這個問題的本質是在於“fpm本身不知道發起請求的另一方是否真的是webserver”和“fpm允許通過這個請求傳遞參數修改php.ini中的配置”。因此這其實是一個架構的問題。由 於fcgi守護進程和webserver分離,這是爲了架構上增加可伸縮性,方便前端集羣和後端PHP解析集羣的分離和擴展,這種架構必然存在兩端互不知 曉和信任的代價(之前那個memcached其實也是類似的架構和問題)。我在發現漏洞的過程中就思考過,如果PHP需要修補這個漏洞,要麼只能限制 fcgi參數修改php.ini這項功能,或者白名單可以修改的參數。但這是個臨時的方案,而且只能解決一個問題。另一個問題也就是“fpm本身不知道發 起請求的另一方是否真的是webserver”,最好的解決方法是在fpm中實現對webserver的認證。從而確定請求來源是webserver。但 是這涉及到修改fastcgi協議,而協議本身也不是php官方可以去幹涉的內容。因此這可能就進入了一個兩難的境地。
  於是我把這個問題提交官方後,看到fat提出的修復方法,果不其然也就是這兩種方式。可是這是否真的能起效果?我們拭目以待。
  4、關於漏洞中使用到的exp將暫緩公佈。由於提交官方後,看起來這一次官方是有修補的意願,因此暫時不會公佈使用的exp代碼。待後續官方公佈最終處理方式後再行決定。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章