在測驗繞過 WAF 執行遠程代碼之前,首先構造一個簡單的、易受攻擊的遠程代碼執行腳本,內容如圖:
第 6 行是一個比較明顯的命令執行代碼,第 3 行嘗試攔截 system、exec 或 passthru 等函式(PHP 中有許多其他函式可以執行系統命令,這三個是最常見的),
這個腳本部署在 Cloudflare WAF 和 ModSecurity + OWASP CRS3 之后,對于第一個測驗,嘗試讀取 passwd 的內容;
/cfwaf.php?code=system("cat /etc/passwd");
可以看到,被 CloudFlare 攔截了,我們可以嘗試使用未初始化變數的方式繞過,比如:
cat /etc$u/passwd
Cloudflare WAF 已被繞過,但是由于腳本檢查敏感函式,所以被腳本攔截,那么如何繞過腳本的函式檢測呢?我們看看關于字串的 PHP 檔案:
https://secure.php.net/manual/en/language.types.string.php
PHP 字串轉義序列:
-
[0–7]{1,3} 八進制表示法的字符序列,它會自動溢位以適應一個位元組(例如“\400”===“\000”)
-
\x[0–9A-Fa-f]{1,2} 十六進制字符序列(例如“\x41”)
-
\u{[0–9A-Fa-f]+} Unicode 代碼點序列,將作為該代碼點的 UTF-8 表示輸出到字串(在 PHP 7.0.0 中添加)
不是每個人都知道 PHP 表示字串的語法,而“PHP 變數函式”則成為我們繞過過濾器和規則的瑞士軍刀,
【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
PHP變數函式
PHP 支持變數函式的概念,這意味著如果變數名后面附加了圓括號,PHP 將尋找與變數求值結果同名的函式,并嘗試執行它,除其他事項外,這可用于實作回呼、函式表等,
這意味著語法如 $var(args); 和 "sting"(args; 等于 func(args); ,如果我可以通過使用變數或字串來呼叫函式,則意味著我可以使用轉義序列而不是函式名,這里有一個例子:
第三種語法是十六進制符號的轉義字符序列,PHP 將其轉換為字串“system”,然后使用引數“ls”轉換為函式系統,讓我們嘗試使用易受攻擊的腳本:
此技術不適用于所有 PHP 函式,變數函式不適用于 echo、print、unset()、isset()、empty()、include、require ,利用包裝函式將這些構造中的任何一個用作變數函式,
改進用戶輸入檢測
如果我從易受攻擊腳本的用戶輸入中排除雙引號和單引號等字符,會發生什么情況?即使不使用雙引號也可以繞過它嗎?讓我們試試:
正如您在第三行看到的,現在腳本阻止在 $_GET[code] 查詢字串引數中使用“和”,我以前的有效負載現在應該被阻止:
幸運的是,在 PHP 中,我們并不總是需要引號來表示字串,PHP 使您能夠宣告元素的型別,例如 $a = (string)foo; 在這種情況下,$a 包含字串“foo”,此外,圓括號內沒有特定型別宣告的任何內容都被視為字串:
在這種情況下,我們有兩種方法可以繞過新過濾器:第一種是使用類似 (system)(ls) 的方法;但是我們不能在代碼引數中使用“system”,所以我們可以像 (sy.(st).em)(ls); 一樣連接字串,第二種是使用 $GET 變數,如果我發送像 ?a=system&b=ls&code=$GETa 這樣的請求;結果是:$GET[a] 將替換為字串“system”,$GET[b] 將替換為字串“ls”,我將能夠繞過所有過濾器!
讓我們嘗試使用第一個有效負載 (sy.(st).em)(whoami);
和第二個有效載荷 ?
?a=system&b=cat+/etc&c=/passwd&code=$\_GET[a]($\_GET[b].$\_GET[c]);
在這種情況下,沒有用,但您甚至可以在函式名稱和引數內部插入注釋(這可能有助于繞過阻止特定 PHP 函式名稱的 WAF 規則集),以下所有語法均有效:
get_defined_functions 函式
此 PHP 函式回傳一個多維陣列,其中包含所有已定義函式的串列,包括內置(內部)函式和用戶定義函式,內部函式可以通過 $arr[“internal”] 訪問,用戶定義的函式可以使用 $arr[“user”] 訪問,例如:
這可能是另一種無需使用其名稱即可訪問系統功能的方法,如果我對“系統”進行 grep,我可以發現它的索引號并將其用作我的代碼執行的字串:
顯然,這應該對我們的 Cloudflare WAF 和腳本過濾器有效:
字符陣列
PHP 中的每個字串都可以用作字符陣列(幾乎像 Python 那樣),您可以使用語法 $string[2] 或 $string[-3] 參考單個字串字符,這可能是另一種規避阻止 PHP 函式名稱的規則的方法,例如,使用這個字串 $a=”elmsty/ “; 我可以撰寫語法系統(“ls /tmp”);
如果幸運的話,您可以在腳本檔案名中找到所需的所有字符,使用相同的技術,您可以使用類似的方法選擇所需的所有字符
OWASP CRS3
有了 OWASP CRS3,一切都變得更難了,首先,使用之前看到的技術,我只能繞過第一個偏執級別,這太神奇了!因為 Paranoia Level 1 只是我們可以在 CRS3 中找到的規則的一小部分,所以這個級別旨在防止任何誤報,對于 2 級偏執狂,由于規則 942430“受限 SQL 字符例外檢測(args):超出特殊字符數”,所有事情都變得困難,我能做的只是執行一個不帶引數的命令,如“ls”、“whoami”等,但我無法像使用 Cloudflare WAF 那樣執行類似 system(“cat /etc/passwd”) 的命令:
更多網安技能的在線實操練習,請點擊這里>>
合天智匯:合天網路靶場、網安實戰虛擬環境
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/555206.html
標籤:其他
上一篇:618大促|決議平臺、商家和消費者必須面對的三大風險
下一篇:返回列表
