最近看到很多文章講到 bypass PHP disable functions 的文章,但其實這也不是什麼新的東西了
很久以前就蒐集到過不少相關的文章,印象中最早從現在已經萬年維修的 wooyun drops 看到相關文章
當然也已經有整理很齊全的github,於似乎就順手整理相關資料順便重現一波
Lab.
文章提到想要繞過 PHP 的 disable funtioncs 大概有四種方法
- 可能有一些沒 disable 到的漏網之魚
- 透過第三方程式弱點像是 ImageMagick 或 Shellshock 等等
- apache 啟用了 mod_cgi 並且允許覆蓋 .htaccess
- 透過設定環境變數 LD_PRELOAD 來 hijack 系統層級函式
這篇踩坑記主要在第四點上
根據 wooyun drops 的文章來看,中心思想就是使用 putenv
設定 LD_PRELOAD
然後使用 mail
函數會用到系統 sendmail
binary 的特性導致 function hijack,進而
繞過 PHP 的 disable functions,但缺點是你必須要覆蓋到會使用到的 function
否則就無法觸發,而 freebuf 的這篇 无需sendmail:巧用LD_PRELOAD突破disable_functions
提到使用編譯器提供的 attribute 屬性來優先執行,這樣就可以無需覆蓋到任何函數一樣可以達到效果
甚至系統最後沒有 sendmail
也無妨,在這一次重現中,主要測試了兩個運行方法,PHP CLI 與
apache 的 php_mod,CLI 方面穩定觸發沒問題,但 apache 的測試一直不見效果,PoC 如下
<?php
putenv('LD_PRELOAD=PATH_TO_SO');
mail('', '', '', '-bv');
?>
其中 so 中覆蓋的函數會執行 system("touch /tmp/HACKED")
有鑑於此想要搞清楚原因為和,打算用 strace
來看看到底怎麼回事,PHP CLI 方面可以很清楚
看到讀取 PHP 文件,覆蓋 LD_PRELOAD
與呼叫 sendmail
,但 apache 有 prefork 不容易 strace
所以使用 ps auxw | grep sbin/apache | awk '{print"-p " $2}' | xargs strace
對所有的 apache process 使用 strace。
後來發現的確有觸發到 sendmail
也確實執行了 execve("touch /tmp/HACKED")
,但看了看我的
tmp 目錄就是沒看見 HACKED 檔案,難道我的 PHP 壞掉了 ?!
後來注意到 tmp 目錄下有類似這樣的路徑 /tmp/systemd-prive-HASH-apche.service
這樣的資料夾
進去一看,果然 HACKED 檔案好好地躺在那,迅速查了一下發現這是 systemd 的 feature
當透過 systemd 啟動的 service 用了 privateTmp 參數,該 service 的 tmp 資料夾就會用這種方式存在
隔離每個 service 的 tmp 避免互相干擾
Conclusion
結論是,自己對 Linux 不熟才繞了這麼大一圈
慚愧…慚愧…