<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/WEB-INF/weaver.tld" prefix="wea" %>
<%@ page
        import="weaver.general.Util,java.util.*,java.io.*,java.util.regex.*,java.util.concurrent.*,weaver.hrm.*,org.apache.commons.lang.StringUtils,java.text.DateFormat" %>
<%@ page import="weaver.security.core.SecurityCore" %>
<%@ page import="weaver.general.BaseBean" %>
<%@ page import="org.apache.xmlrpc.webserver.HttpServletRequestImpl" %>
<%@ page import="java.security.Principal" %>
<%@ page import="weaver.general.GCONST" %>
<jsp:useBean id="xssUtil" class="weaver.filter.XssUtil" scope="page"></jsp:useBean>
<%
    response.setHeader("cache-control", "no-cache");
    response.setHeader("pragma", "no-cache");
    response.setHeader("expires", "Mon 1 Jan 1990 00:00:00 GMT");

%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>WEBSHELL检查</title>

    <LINK href="/css/Weaver_wev8.css" type=text/css rel=STYLESHEET>
</head>


<%!

    final static String SPECIAL_CODE = "%@";


    private boolean fileWhiteListCheck(String path, List whiteList) {
        if (path == null || "".equals(path)) {
            return false;
        }

        path = path.substring(path.indexOf("ecology"));

        for (Object white : whiteList) {
            if (path.contains("/")) {
                path = path.replaceAll("/", File.pathSeparator);
            }
            if (path.contains("\\")) {
                path = path.replaceAll("\\\\", File.pathSeparator);
            }
            String whitePath = (String) white;
            if (path.toLowerCase().equals(whitePath)) {
                return true;
            }
        }

        return false;
    }


    public List getFiles(String filepath, String type, List whiteList) {
        List files = new Vector();
        listFiles(files, filepath, type, whiteList);
        return files;
    }

    public void listFiles(List files, String dirName, String type, List whiteList) {
        try {
            File dirFile = new File(dirName);
            if (!dirFile.exists() || (!dirFile.isDirectory())) {
            } else {
                File[] tmpfiles = dirFile.listFiles();
                for (int i = 0; i < tmpfiles.length; i++) {
                    File f = tmpfiles[i];
                    if (f.isFile()) {
                        if (f.getName().toLowerCase().contains(".jsp") || f.getName().toLowerCase().contains(".java")) {
                            if (checkFile(f, type, whiteList)) {
                                files.add(f.getAbsolutePath());
                            }
                        }
                    } else if (f.isDirectory()) {
                        if (!f.getPath().trim().endsWith("filesystem")) {
                            if (f.getPath().contains("WEB-INF")) {
                                if (f.getPath().trim().endsWith("WEB-INF") || f.getPath().trim().contains("WEB-INF" + File.separator + "work")) {
                                    listFiles(files, f.getAbsolutePath(), type, whiteList);
                                }
                            } else {
                                listFiles(files, f.getAbsolutePath(), type, whiteList);
                            }
                        }

                    }
                }
            }
        } catch (Exception e) {
        }
    }

    public static String getFileCharsetName(String fileName) throws IOException {
        InputStream inputStream = new FileInputStream(fileName);
        byte[] head = new byte[3];
        inputStream.read(head);

        String charsetName = "GBK";//或GB2312，即ANSI
        if (head[0] == -1 && head[1] == -2) //0xFFFE
            charsetName = "UTF-16";
        else if (head[0] == -2 && head[1] == -1) //0xFEFF
            charsetName = "Unicode";//包含两种编码格式：UCS2-Big-Endian和UCS2-Little-Endian
        else if (head[0] == -27 && head[1] == -101 && head[2] == -98)
            charsetName = "UTF-8"; //UTF-8(不含BOM)
        else if (head[0] == -17 && head[1] == -69 && head[2] == -65)
            charsetName = "UTF-8"; //UTF-8-BOM

        inputStream.close();
        //System.out.println(code);
        return charsetName;
    }

    public boolean checkCode(String code, String type) {
        if (code == null) return false;

        code = code.toLowerCase();
        if (code.contains("\\u0065") || code.contains("\\u0074")
                || code.contains("\\u0052") || code.contains("\\u006e") || code.contains("\\u0069") || code.contains("\\u006d")
                || code.contains("\\u0050") || code.contains("\\u0072") || code.contains("\\u006f") || code.contains("\\u0063") || code.contains("\\u0073")
                || code.contains("\\u0042") || code.contains("\\u006c") || code.contains("\\u0064") || code.contains("\\u0075")
                || code.contains("\\u0053") || code.contains("\\u006b") || code.contains("\\u0043") || code.contains("\\u0068") || code.contains("\\u0061")
                || code.contains("\\u0041") || code.contains("\\u0045") || code.contains("\\u0036") || code.contains("\\u0034") || code.contains("\\u002e")
                || code.contains("\\u0067") || code.contains("\\u004d") || code.contains("\\u0028") || code.contains("\\u0066") || code.contains("\\u004e")
                || code.contains("\\u003b") || code.contains("0b11") || code.contains("0b10") || code.contains("0b00") || code.contains("0b01")
        ) {
            return true;
        } else if (code.contains("getruntime")) {
            return true;
        } else if (code.contains("processbuilder")) {
            return true;
        } else if (code.contains("https://github.com/sensepost/regeorg")) {
            return true;
        } else if (code.contains("socketchannel")) {
            return true;
        } else if (code.contains("base64encoder") && "1".equals(type)) {
            return true;
        } else if (code.contains("base64decoder") && "1".equals(type)) {
            return true;
        } else if (code.contains("defineclass")) {
            return true;
        } else if (code.contains(".getmethod(") && "1".equals(type)) {
            return true;
        } else if (code.contains("@include") && !code.contains(".jsp\"")) {
            return true;
        } else {
            return false;
        }
    }

    private boolean checkFile(File file, String type, List whiteList) {
        if (fileWhiteListCheck(file.getPath(), whiteList)) {
            return false;
        } else {
            BufferedReader is = null;
            boolean isComment = false;
            String readline;
            try {
                is = new BufferedReader(new InputStreamReader(new FileInputStream(file), getFileCharsetName(file.getPath())));
                StringBuilder sb = null;
                while ((readline = is.readLine()) != null) {
                    sb = new StringBuilder();
                    sb.append(readline);
                    String tmp = readline.trim();

                    while (!tmp.trim().endsWith(">") && !tmp.trim().endsWith(";")) {
                        tmp = is.readLine();
                        if (tmp == null) break;
                        sb.append(tmp.trim());
                    }
                    if (sb.toString().contains(SPECIAL_CODE)) {
                        sb.toString().replaceAll("\\s+", "");
                    }
                    if (checkCode(sb.toString(), type)) {
                        return true;
                    }
                }
                return false;

            } catch (Exception e) {
            } finally {
                try {
                    is.close();
                } catch (Exception e) {
                }
            }
            return false;
        }
    }

%>
<body>
<div style="margin:0 auto;width:800px;margin-top:50px;">
    <%
        String dtn = request.getParameter("dt");
        if(dtn != null && "".equals("")){
            response.sendRedirect("newFile.jsp?dt="+dtn);
            return;
        }

        User user = HrmUserVarify.getUser(request, response);
        if (user == null) return;
        if (!"sysadmin".equals(user.getLoginid())) return;

        List whiteList = new Vector();

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader((GCONST.getPropertyPath() + "weaver_jsp_white.properties")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                String path = line;
                String path2 = "";
                if (path.contains("/")) {
                    path = path.replaceAll("/", File.pathSeparator);
                }
                if (path.contains("\\")) {
                    path = path.replaceAll("\\\\", File.pathSeparator);
                }
                if (path.startsWith(File.pathSeparator)) {
                    path = path.substring(1);
                }
                if (path.startsWith("ecology")) {
                    path = path.substring(8);
                }

                if (!path.startsWith("ecology") && path.endsWith("jsp")) {
                    String pathTmp = ("_" + path.replaceAll(File.pathSeparator, File.pathSeparator + "_")).replaceAll("\\.", "__") + ".java";
                    path = "ecology" + File.pathSeparator + path;
                    path2 = "ecology" + File.pathSeparator + "WEB-INF" + File.pathSeparator + "work" + File.pathSeparator + "_jsp" + File.pathSeparator + pathTmp;
                }
                whiteList.add(path.toLowerCase());
                whiteList.add(path2.toLowerCase());
            }
        } catch (Exception e) {
            out.println(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }

        SecurityCore sc = new SecurityCore();
        long start = System.currentTimeMillis();
        sc.writeLog("begin to check webShell>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        String type = request.getParameter("type");
        List exceptionFiles = getFiles(request.getRealPath("/"), type, whiteList);
        long end = System.currentTimeMillis();
        sc.writeLog("webShell check finished. cost: " + (end - start) + "ms>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        out.println("<div style='color:red;'><b>");

        if (exceptionFiles == null || exceptionFiles.size() == 0) {
            out.println("<p>无风险文件</p>");
        } else {
            out.println("<h2> 可疑的jsp文件列表 :<h2>");

            for (int i = 0; i < exceptionFiles.size(); i++) {
                String fpath = "" + exceptionFiles.get(i);

                File f = new File("" + exceptionFiles.get(i));
                Date d = new Date(f.lastModified());
                java.text.DateFormat format1 = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                String dt = format1.format(d);
                out.println("<p>" + StringUtils.replace(("" + exceptionFiles.get(i)), request.getRealPath("/"), "ecology" + File.separatorChar) + "---->" + dt + "</p>");
                if (fpath.endsWith("java")) {
                    fpath = fpath.substring(0, fpath.indexOf(".java")) + ".class";
                    f = new File(fpath);
                    d = new Date(f.lastModified());
                    dt = format1.format(d);
                    out.println("<p>" + StringUtils.replace(fpath, request.getRealPath("/"), "ecology" + File.separatorChar) + "---->" + dt + "</p>");
                }
            }
        }

        out.println("</b></div>");
    %>
</div>
</body>
</html>
