1496 lines
68 KiB
Plaintext
1496 lines
68 KiB
Plaintext
<%--
|
||
Created by IntelliJ IDEA.
|
||
User: zhangfeng
|
||
Date: 2019/5/31
|
||
Time: 13:57
|
||
To change this template use File | Settings | File Templates.
|
||
--%>
|
||
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
|
||
<%@ page
|
||
import="weaver.filter.SecurityCheckList,weaver.general.Util,weaver.hrm.User,weaver.hrm.settings.ChgPasswdReminder,weaver.hrm.settings.RemindSettings,java.io.*,java.lang.reflect.InvocationTargetException" %>
|
||
<%@ page import="java.lang.reflect.Method" %>
|
||
<%@ page import="java.security.MessageDigest" %>
|
||
<%@ page import="java.util.*" %>
|
||
<%@ page import="java.util.jar.JarEntry" %>
|
||
<%@ page import="java.util.jar.JarFile" %>
|
||
<%@ page import="weaver.security.classLoader.ReflectMethodCall" %>
|
||
<jsp:useBean id="rs" class="weaver.conn.RecordSet" scope="page"/>
|
||
<jsp:useBean id="xssutil" class="weaver.filter.XssUtil"></jsp:useBean>
|
||
<jsp:useBean id="csui" class="weaver.filter.msg.CheckSecurityUpdateInfo"></jsp:useBean>
|
||
|
||
<%
|
||
User user = (User) session.getAttribute("weaver_user@bean");
|
||
int UID = xssutil.getIntValue(""+xssutil.getRule().get("userID"),1);
|
||
if (user == null || user.getUID()!=UID) {
|
||
out.println("请使用管理员权限查看");
|
||
return;
|
||
}
|
||
%>
|
||
|
||
<html>
|
||
<title>一键巡检</title>
|
||
<body>
|
||
<table width="100%" border="1" cellpadding="0" cellspacing="0">
|
||
<thead>
|
||
<th width="20%" style="text-align:center;">检查项</th>
|
||
<th width="20%" style="text-align:center;">检查结果</th>
|
||
<th width="60%" style="text-align:center;">详情及处置意见</th>
|
||
</thead>
|
||
<tbody>
|
||
<%
|
||
|
||
int type = Util.getIntValue(request.getParameter("type"), -1);
|
||
int code = Util.getIntValue(request.getParameter("code"), -1);
|
||
String nextLine = "<br/>";
|
||
String pass = "<span style=\"color:green;text-align:center;\">检查通过</span>";
|
||
String refuse = "<span style=\"color:red;text-align:center;\">检查不通过</span>";
|
||
String check = "<span style=\"color:yellow;text-align:center;\">需要人工检查</span>";
|
||
|
||
String checkStatusMsg = "";
|
||
String checkMessage = "";
|
||
boolean isRaspPass = false;
|
||
Integer checkJarStatus = 0;
|
||
long jarVersion = 0L;
|
||
String classPath = "com.baidu.openrasp.Agent";
|
||
String jarPath = null;
|
||
%>
|
||
<tr>
|
||
|
||
<td style="text-align:center;">安全包版本检测</td>
|
||
<%
|
||
String ecversion = "";
|
||
String cversion = "";
|
||
String cversionTmp = "";
|
||
rs.execute("select companyname,cversion from license");
|
||
if (rs.next()) {
|
||
cversion = rs.getString("cversion");
|
||
cversionTmp = cversion;
|
||
ecversion = "E" + cversion.substring(0, 1);
|
||
}
|
||
csui.getRemoteServerVersion();
|
||
String newOANowVersion = csui.getNewversion();
|
||
String currentVersion = csui.getVersion();
|
||
|
||
String newRuleVersion = csui.getRuleNewVersion();
|
||
String currentRuleVersion = csui.getRuleVersion();
|
||
|
||
if (newOANowVersion != null && !"".equals(newOANowVersion.trim())) {
|
||
if (csui.getNewversion().compareTo(csui.getVersion()) > 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage += "当前OA版本为: " + ecversion + "</br> 当前补丁包版本: " + currentVersion + " 最新官网补丁包版本: " + newOANowVersion
|
||
+ "</br>当前安全补丁版本过低请及时升级到最新版本";
|
||
if (csui.getRuleNewVersion().compareTo(csui.getRuleVersion()) > 0) {
|
||
checkMessage += "</br>当前规则库版本: " + currentRuleVersion + " 最新官网规则库版本: " + newRuleVersion + "</br>当前安全库版本过低请及时升级到最新版本";
|
||
} else {
|
||
checkMessage += "</br>当前规则库版本: " + currentRuleVersion + " 最新官网规则库版本: " + newRuleVersion + "</br>当前安全库版本已是最新版本";
|
||
}
|
||
} else {
|
||
checkStatusMsg = pass;
|
||
checkMessage += "当前OA版本为: " + ecversion + "</br> 当前补丁包版本: " + currentVersion + " 最新官网补丁包版本: " + newOANowVersion
|
||
+ "</br>当前安全补丁版本已是最新";
|
||
if (csui.getRuleNewVersion().compareTo(csui.getRuleVersion()) > 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage += "</br>当前规则库版本: " + currentRuleVersion + " 最新官网规则库版本: " + newRuleVersion + "</br>当前安全库版本过低请及时升级到最新版本";
|
||
} else {
|
||
checkMessage += "</br>当前规则库版本: " + currentRuleVersion + " 最新官网规则库版本: " + newRuleVersion + "</br>当前安全库版本已是最新版本";
|
||
}
|
||
}
|
||
} else {
|
||
checkStatusMsg = check;
|
||
checkMessage += "当前OA版本为: " + ecversion + "</br> 当前补丁包版本: " + currentVersion + " 最新官网补丁包版本: " + newOANowVersion
|
||
+ "</br>无法检测到官网补丁包版本,请人工确认." + "</br>当前规则库版本: "
|
||
+ currentRuleVersion + " 最新官网规则库版本: " + newRuleVersion + "</br>无法检测到官网规则库版本,请人工确认";
|
||
}
|
||
|
||
checkMessage += "</br> 官网安全补丁包地址: https://www.weaver.com.cn/cs/securityDownload.html" +
|
||
"</br> 若存在当前安全补丁包已是最新安全补丁包且仍存在相关扫描不通过的情况,请重新手动更新官网的安全补丁包";
|
||
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">安全包生效性检测</td>
|
||
<%
|
||
if (xssutil.enableFirewall()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已开启安全包防护";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未开启安全包防护.请检查: " + nextLine +
|
||
"step1 " + nextLine +
|
||
"检查WEB-INF/web.xml文件,是否存在添加如下代码且未被 <!-- 注释\n" + nextLine +
|
||
"<filter>\n" + nextLine +
|
||
"<filter-name>SecurityFilter</filter-name>\n" + nextLine +
|
||
"<filter-class>weaver.filter.SecurityFilter</filter-class>\n" + nextLine +
|
||
"</filter>\n" + nextLine +
|
||
"<filter-mapping>\n" + nextLine +
|
||
"<filter-name>SecurityFilter</filter-name>\n" + nextLine +
|
||
"<url-pattern>/*</url-pattern>\n" + nextLine +
|
||
"</filter-mapping>" + nextLine +
|
||
"如不存在请添加 完成之后重启" + nextLine +
|
||
">>>>>>>>>>>>>>>若step1 未能解决你的问题>>>>>>>>>>>>>>>>>>>" + nextLine +
|
||
"step2 备份并删除 /ecology/WEB-INF/weaver_security_config.xml" + nextLine +
|
||
"之后重启(需要先更新最新安全包)" + nextLine +
|
||
">>>>>>>>>>>>>>>若 step 1 与 step 2 都不能解决你的问题>>>>>>>>>>>>>>>>>>>>>>>>>>" + nextLine +
|
||
"请提交流程到泛微总部系统安全组";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">
|
||
JDK版本检测
|
||
</td>
|
||
|
||
<%
|
||
Properties props = System.getProperties();
|
||
String jdkVersion = props.getProperty("java.version");
|
||
String[] strarr = jdkVersion.split("[\\_\\.]");
|
||
if (strarr[0] != null && Integer.parseInt(strarr[0].toString()) > 1) {
|
||
checkStatusMsg = check;
|
||
checkMessage = "无法确认的JDK版本,请人工校验";
|
||
} else if (strarr[1] != null && Integer.parseInt(strarr[1].toString()) == 8) {
|
||
if (Integer.parseInt(strarr[strarr.length - 1].toString()) >= 121) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本为可靠版本";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本过低,推荐使用JDK8 121版本之后的版本";
|
||
}
|
||
} else if (strarr[1] != null && Integer.parseInt(strarr[1].toString()) == 7) {
|
||
if (Integer.parseInt(strarr[strarr.length - 1].toString()) >= 131) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本为可靠版本";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本过低,推荐使用JDK7 131版本之后的版本";
|
||
}
|
||
} else if (strarr[1] != null && Integer.parseInt(strarr[1].toString()) == 6) {
|
||
if (Integer.parseInt(strarr[strarr.length - 1].toString()) >= 141) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本为可靠版本";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 当前JDK版本过低,推荐使用JDK6 141版本之后的版本";
|
||
}
|
||
} else {
|
||
checkStatusMsg = check;
|
||
checkMessage = "当前JDK版本为: " + jdkVersion + "</br> 过高或过低的JDK版本,需要进行进一步确认";
|
||
}
|
||
%>
|
||
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<%
|
||
if (type != 1) {
|
||
%>
|
||
<tr>
|
||
<td style="text-align:center;">检查是否包含webshell后门文件</td>
|
||
|
||
<%
|
||
List<String> exceptionFiles = getFiles(xssutil.getRootPath());
|
||
if (exceptionFiles.isEmpty()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "未发现可疑项";
|
||
} else {
|
||
checkMessage = "疑似webshell的脚本文件如下:</br>";
|
||
checkStatusMsg = refuse;
|
||
for (String fileName : exceptionFiles) {
|
||
checkMessage += fileName + "</br>";
|
||
}
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<%}%>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">sysadmin账号IP白名单限制检测(强烈推荐启用)</td>
|
||
<%
|
||
List allowIps = (List)new weaver.filter.XssUtil().getRule().get("sysadmin-allow-login-ips");
|
||
if(allowIps == null || allowIps.isEmpty()){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "强烈建议按照以下方案启用IP白名单策略(<font color='red'>保障高权限账号泄露带来的安全隐患,配置后,只有白名单中的IP或者IP段能够正常使用sysadmin账号,其他IP使用会被拒绝</font>):<br/>"
|
||
+"修改/ecology/WEB-INF/securityXML/weaver_security_custom_rules_1.xml,在下方添加如下代码(如果要放行某个网段,则填写IP的前半段即可,如192.168.7. ,则代表192.168.7.*都可以访问):<br/>"+
|
||
"<sysadmin-allow-login-ips><br/>"+
|
||
"<ip>ip1</ip><br/>"+
|
||
"<ip>ip2</ip><br/>"+
|
||
"</sysadmin-allow-login-ips>";
|
||
}else{
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已启用.可通过访问/security/getCache.jsp?key=sysadmin-allow-login-ips查看已配置的IP白名单。";
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
|
||
</td>
|
||
</tr>
|
||
<%
|
||
String clientIp = request.getRemoteAddr();
|
||
ReflectMethodCall rmc = new ReflectMethodCall();
|
||
Boolean isInternalIp = (Boolean)rmc.call("weaver.security.webcontainer.IpUtils", null, "internalIp", new Class[]{String.class}, clientIp);
|
||
%>
|
||
<tr>
|
||
<td style="text-align:center;">外网网络策略检测(<font color="red">如果EC无互联网访问,可以忽略此项检测</font>)</td>
|
||
<%
|
||
checkStatusMsg = "当前OA系统获取到的客户端IP地址为:<font color='red'>"+clientIp+"</font>,是一个 <font color='red'>"+(isInternalIp? "内网" : "互联网IP")+" </font>,请确认该IP是否为您当前的实际客户端IP(如果此处获取到的IP和步骤查看到的IP一致,那么表示没问题)。";
|
||
checkMessage = "查看自己当前IP地址的方法:<br/>1、内网IP查看,可以打开命令提示符窗口,windows环境执行ipconfig命令,可以看到自己的机器IP。可能会有多个IP,比如wifi和有线连接2个IP等。<br/>" +
|
||
"2、如果想查看自己电脑当前的互联网出口IP,可以<a href='https://ip.900cha.com/' target='_blank'>点击查看本机互联网IP地址</a>.<br/></br/>如果检测不通过,请按以下步骤检查:<br/>" +
|
||
"用外网地址登录,访问<a href='/wui/getremoteaddr.jsp' target='_blank'>此处</a>,看下拿到的IP地址是什么。需要联系网络管理员把客户真实IP地址放到X-Forwarded-For头部传给OA应用,确保oa应用能够拿到真实IP地址。就是上面的页面必须获取到真实客户端IP地址";
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
<img src="../security/images/network.png" width="600"/>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">检测弱密码</td>
|
||
<%
|
||
List<Map<String, String>> weakResources = new ArrayList<Map<String, String>>();
|
||
List<Map<String, String>> weakResourcesManager = new ArrayList<Map<String, String>>();
|
||
weaver.filter.XssUtil xssUtil = new weaver.filter.XssUtil();
|
||
String pathname = xssUtil.getRootPath() + "WEB-INF/securityRule/weak_stand.txt"; // 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径
|
||
File filename = new File(pathname); // 要读取以上路径的input.txt文件
|
||
BufferedReader br = null;
|
||
InputStreamReader reader2 = null;
|
||
Set<String> weakPsd = new HashSet<String>();
|
||
Set<String> weakSet = new HashSet<String>();
|
||
try {
|
||
reader2 = new InputStreamReader(
|
||
new FileInputStream(filename)); // 建立一个输入流对象reader
|
||
br = new BufferedReader(reader2); // 建立一个对象,它把文件内容转成计算机能读懂的语言
|
||
|
||
String line = br.readLine();
|
||
weakPsd.add(Util.getEncrypt(""));
|
||
weakSet.add("");
|
||
|
||
while (line != null) {
|
||
weakSet.add(line);
|
||
line = Util.getEncrypt("".equals(line.trim()) ? "1" : line); // 一次读入一行数据
|
||
weakPsd.add(line);
|
||
line = br.readLine();
|
||
}
|
||
}catch (Exception e){
|
||
|
||
}finally {
|
||
if(br!=null){
|
||
try {
|
||
br.close();
|
||
}catch (Exception e){}
|
||
}
|
||
if(reader2!=null){
|
||
try {
|
||
reader2.close();
|
||
}catch (Exception e){}
|
||
}
|
||
}
|
||
|
||
pathname = xssUtil.getRootPath() + "WEB-INF/securityRule/weak.txt"; // 绝对路径或相对路径都可以,这里是绝对路径,写入文件时演示相对路径
|
||
filename = new File(pathname); // 要读取以上路径的input.txt文件
|
||
try {
|
||
reader2 = new InputStreamReader(
|
||
new FileInputStream(filename)); // 建立一个输入流对象reader
|
||
br = new BufferedReader(reader2); // 建立一个对象,它把文件内容转成计算机能读懂的语言
|
||
|
||
String line = br.readLine();
|
||
weakPsd.add(Util.getEncrypt(""));
|
||
weakSet.add("");
|
||
|
||
while (line != null) {
|
||
if(!weakSet.contains(line)) {
|
||
weakSet.add(line);
|
||
line = Util.getEncrypt("".equals(line.trim()) ? "1" : line); // 一次读入一行数据
|
||
weakPsd.add(line);
|
||
}
|
||
line = br.readLine();
|
||
}
|
||
}catch (Exception e){
|
||
|
||
}finally {
|
||
if(br!=null){
|
||
try {
|
||
br.close();
|
||
}catch (Exception e){}
|
||
}
|
||
if(reader2!=null){
|
||
try {
|
||
reader2.close();
|
||
}catch (Exception e){}
|
||
}
|
||
}
|
||
|
||
//manager账户数量不会太多
|
||
|
||
/**
|
||
* MD5加密账户弱密码校验策略
|
||
*/
|
||
String sql_manager = "select id,password,loginid from hrmresourcemanager";
|
||
rs.execute(sql_manager);
|
||
|
||
while (rs.next()) {
|
||
String password = rs.getString("password");
|
||
if (!weakPsd.contains(password)) {
|
||
continue;
|
||
}
|
||
|
||
Map<String, String> data = new HashMap<String, String>();
|
||
int id = rs.getInt("id");
|
||
data.put("loginid", rs.getString("loginid"));
|
||
weakResourcesManager.add(data);
|
||
}
|
||
|
||
String sql = "select id,password,loginid,lastname,lastlogindate,passwordlock,passwdchgdate from hrmresource where loginid is not null and status in (0,1,2,3)";
|
||
rs.execute(sql);
|
||
while (rs.next()) {
|
||
|
||
String password = rs.getString("password");
|
||
if (!weakPsd.contains(password)) {
|
||
continue;
|
||
}
|
||
|
||
Map<String, String> data = new HashMap<String, String>();
|
||
data.put("loginid", rs.getString("loginid"));
|
||
weakResources.add(data);
|
||
|
||
}
|
||
/**
|
||
* SM3 加密 弱密码用户列表
|
||
*/
|
||
|
||
Class<?> threadClazz = null;
|
||
Method encryptMethod = null;
|
||
Object newInstance = null;
|
||
try {
|
||
threadClazz = Class.forName("weaver.sm.SM3Utils");
|
||
newInstance = threadClazz.newInstance();
|
||
encryptMethod = threadClazz.getMethod("getEncrypt", String.class, String.class);
|
||
} catch (Exception e) {
|
||
}
|
||
if (threadClazz != null && newInstance != null && encryptMethod != null) {
|
||
String sql_manager_sm3 = "select id,password,loginid,salt from hrmresourcemanager where salt is not null and length(salt) > 1";
|
||
rs.execute(sql_manager_sm3);
|
||
|
||
while (rs.next()) {
|
||
|
||
int id = rs.getInt("id");
|
||
String password = rs.getString("password");
|
||
String salt = rs.getString("salt");
|
||
if (salt.contains("sm3_new#")) {
|
||
salt = salt.split("sm3_new#")[1];
|
||
}
|
||
|
||
for (String s : weakSet) {
|
||
String encryptSM3pwd = null;
|
||
try {
|
||
encryptSM3pwd = (String) encryptMethod.invoke(newInstance, s, salt);
|
||
} catch (IllegalAccessException e) {
|
||
e.printStackTrace();
|
||
} catch (InvocationTargetException e) {
|
||
e.printStackTrace();
|
||
}
|
||
if (encryptSM3pwd != null && encryptSM3pwd.equals(password)) {
|
||
Map<String, String> data = new HashMap<String, String>();
|
||
data.put("loginid", rs.getString("loginid"));
|
||
weakResourcesManager.add(data);
|
||
}
|
||
}
|
||
}
|
||
String sql_sm3 = "select id,password,loginid,lastname,lastlogindate,passwordlock,passwdchgdate,salt from hrmresource where loginid is not null and salt is not null and length(salt) > 1 and status in (0,1,2,3)";
|
||
rs.execute(sql_sm3);
|
||
while (rs.next()) {
|
||
|
||
int id = rs.getInt("id");
|
||
String password = rs.getString("password");
|
||
String salt = rs.getString("salt");
|
||
if (salt.contains("sm3_new#")) {
|
||
salt = salt.split("sm3_new#")[1];
|
||
}
|
||
for (String s : weakSet) {
|
||
String encryptSM3pwd = null;
|
||
try {
|
||
encryptSM3pwd = (String) encryptMethod.invoke(newInstance, s, salt);
|
||
} catch (IllegalAccessException e) {
|
||
e.printStackTrace();
|
||
} catch (InvocationTargetException e) {
|
||
e.printStackTrace();
|
||
}
|
||
if (encryptSM3pwd != null && encryptSM3pwd.equals(password)) {
|
||
Map<String, String> data = new HashMap<String, String>();
|
||
data.put("loginid", rs.getString("loginid"));
|
||
weakResources.add(data);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (weakResources.size() > 0 || weakResourcesManager.size() > 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "系统中存在" + (weakResources.size() + weakResourcesManager.size()) + "个弱密码用户,请及时处理. 访问/wui/weak.jsp 获取明细信息";
|
||
} else {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "无弱密码信息";
|
||
}
|
||
try {
|
||
reader2.close();
|
||
br.close();
|
||
} catch (Exception e) {
|
||
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">synccache.jsp 是否是安全版本</td>
|
||
<%
|
||
File file = new File(xssutil.getRootPath() + "synccache.jsp");
|
||
System.out.println(xssutil.getRootPath());
|
||
BufferedReader reader1 = null;
|
||
|
||
try {
|
||
if (file.exists()) {
|
||
reader1 = new BufferedReader(new FileReader(file));
|
||
String tempString = null;
|
||
// 一次读入一行,直到读入null为文件结束
|
||
while ((tempString = reader1.readLine()) != null) {
|
||
// 显示行号
|
||
if (tempString.toLowerCase().contains("SerialKiller".toLowerCase())) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "为安全的synccache.jsp版本";
|
||
break;
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "为不安全的synccache.jsp版本,请更新最新官网安全补丁包";
|
||
}
|
||
}
|
||
} else {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "非集群环境无该风险";
|
||
}
|
||
|
||
|
||
} catch (IOException e) {
|
||
checkStatusMsg = check;
|
||
checkMessage = "打开文件异常请人工检测";
|
||
} finally {
|
||
try {
|
||
reader1.close();
|
||
} catch (Exception e) {
|
||
|
||
}
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测bsh补丁是否已经升级</td>
|
||
<%
|
||
file = new File(xssutil.getRootPath() + "/security/checkbsh.jsp");
|
||
if (file.exists()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "bsh补丁已经升级";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "请及时去泛微安全官网升级你的bsh补丁";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测sql注入补丁是否已经升级</td>
|
||
<%
|
||
file = new File(xssutil.getRootPath() + "/security/checksql20191010.jsp");
|
||
if (file.exists()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "sql注入已经升级";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "请及时去泛微安全官网升级你的sql注入补丁";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测反序列化补丁是否已经升级</td>
|
||
<%
|
||
file = new File(xssutil.getRootPath() + "checkSuc.jsp");
|
||
if (file.exists()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "反序列化补丁已经升级";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "请及时去泛微安全官网升级你的反序列化补丁";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">验证码策略检测</td>
|
||
<%
|
||
ChgPasswdReminder reminder = new ChgPasswdReminder();
|
||
RemindSettings settings = reminder.getRemindSettings();
|
||
int needvalidate = settings.getNeedvalidate();
|
||
String getopenpasswordlock = settings.getOpenPasswordLock();
|
||
int checkValidate = 0;
|
||
int checkPwdLock = 0;
|
||
|
||
if (needvalidate == 1) {
|
||
checkValidate = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "验证码已开启";
|
||
}
|
||
if (checkValidate == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "验证码未开启,请开启验证码校验功能";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">密码锁定策略检测</td>
|
||
<%
|
||
if ("1".equals(getopenpasswordlock)) {
|
||
|
||
checkPwdLock = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "密码锁定策略已开启";
|
||
}
|
||
if (checkPwdLock == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "密码锁定策略未开启";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
|
||
|
||
<tr>
|
||
<td style="text-align:center;">是否开启accesslog</td>
|
||
<%
|
||
if (cversion.equals("E9")) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已开启accesslog";
|
||
} else {
|
||
SecurityCheckList scl = new SecurityCheckList();
|
||
if (scl.isEnableAccessLog() || ecversion.toLowerCase().equals("e9")) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已开启accesslog";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未开启accesslog" + nextLine +
|
||
"resin2:\n" + nextLine +
|
||
"搜索ecology关键字,在<app-dir>下面添加访问日志,如下:\n" + nextLine +
|
||
"<app-dir>F:\\workspace\\ecology7\\</app-dir>\n" + nextLine +
|
||
"<access-log id='log/access.log'>\n" + nextLine +
|
||
"<rollover-period>1D</rollover-period>\n" + nextLine +
|
||
"</access-log>\n" + nextLine +
|
||
"resin3:\n" + nextLine +
|
||
"搜索<host-default>关键字,在该节点下添加访问日志,如下:\n" + nextLine +
|
||
"<host-default>\n" + nextLine +
|
||
"<access-log path=\"logs/access.log\" archive-format=\"access-%Y%m%d.log.gz\" format='%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"' rollover-period=\"1D\">\n" + nextLine +
|
||
"<exclude>\\.gif$</exclude>\n" + nextLine +
|
||
"<exclude>\\.jpg$</exclude>\n" + nextLine +
|
||
"<exclude>\\.png$</exclude>\n" + nextLine +
|
||
"<exclude>\\.js$</exclude>\n" + nextLine +
|
||
"<exclude>\\.css$</exclude>\n" + nextLine +
|
||
"<exclude>\\.html$</exclude>\n" + nextLine +
|
||
"<exclude>\\.htm$</exclude>\n" + nextLine +
|
||
"<exclude>\\.swf$</exclude>\n" + nextLine +
|
||
"<exclude>\\.cur$</exclude>\n" + nextLine +
|
||
"</access-log>\n" + nextLine +
|
||
"修改完成后请重启OA服务";
|
||
}
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测是否已开启Host防护</td>
|
||
<%
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未开启 HSOT 防护,请及时开启" + nextLine +
|
||
"添加或者修改ecology/WEB-INF/weaver_security_config.xml" + nextLine +
|
||
"中的<skip-host>为false" + nextLine +
|
||
"<skip-host>false</skip-host> " + nextLine +
|
||
"开启了该项功能后,需要配置服务器允许的所有访问方式,包括服务器内网地址、外网地址、域名、代理服务器地址到配置文件中,具体方法如下: " + nextLine +
|
||
"添加IP到指定列表的方式如下,修改ecology/WEB-INF/securityXML/weaver_security_custom_rules_1.xml文件,添加方式如下" + nextLine +
|
||
"例: " + nextLine +
|
||
"<host-list> " + nextLine +
|
||
"<host>test.genomics.cn</host> " + nextLine +
|
||
"<host>test.genomics.cn:80</host> " + nextLine +
|
||
"</host-list> " + nextLine +
|
||
"其中 " + nextLine +
|
||
"<host>就是服务器允许的访问方式,包括内网地址、外网地址、域名、代理服务器地址,可以配置多个host节点; " + nextLine +
|
||
"若存在HOST 伪造的情况发生或无法确定自己当前环境的HOST信息\n" + nextLine +
|
||
"则在拦截发生后通过/WEB-INF/securitylog/systemSecurity+日期.log 检索 Host suspected forgery 关键字\n" + nextLine +
|
||
"将对应日志的host 字段值加入白名单 \n" + nextLine +
|
||
"重启OA验证" + nextLine +
|
||
">>>>>>>>>>>>>>>>特别声明>>>>>>>>>>>>>>>>" + nextLine +
|
||
"开启host防护却未配置正确HOST白名单将会导致系统无法访问,请特别注意! " + nextLine +
|
||
"如出现异常及时联系总部解决";
|
||
|
||
Object hostStatus = xssUtil.getRule().get("isSkipHost");
|
||
if (!(Boolean) hostStatus) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已开启host防护";
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测是否已开启登陆加密</td>
|
||
<%
|
||
Integer vtmp = Integer.parseInt(cversionTmp.substring(0, 1));
|
||
|
||
if (vtmp < 8 || (vtmp == 8 && Integer.parseInt(cversion.substring(cversion.length() - 6)) < 171100)) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前系统不支持登陆加密功能请升级OA,或联系我们人力资源模块进行二次开发";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未开启登陆信息加密传输" + nextLine +
|
||
"RSA加密方案:" + nextLine +
|
||
"1).确认 ecology/WEB-INF/lib中存在 RSA-0.0.1-SNAPSHOT.jar ,存在则忽略" + nextLine +
|
||
"2).需在ecology/WEB-INF/web.xml中增加如下配置(检查是否存在,存在则忽略):" + nextLine +
|
||
"<servlet>" + nextLine +
|
||
"<servlet-name>RsaInfo</servlet-name>" + nextLine +
|
||
"<servlet-class>weaver.rsa.GetRsaInfo</servlet-class>" + nextLine +
|
||
"</servlet>" + nextLine +
|
||
"<servlet-mapping>" + nextLine +
|
||
"<servlet-name>RsaInfo</servlet-name>" + nextLine +
|
||
"<url-pattern>/rsa/weaver.rsa.GetRsaInfo</url-pattern>" + nextLine +
|
||
"</servlet-mapping>" + nextLine +
|
||
"3)配置开启 在ecology\\WEB-INF\\prop\\openRSA.properties 配置" + nextLine +
|
||
"isrsaopen=1" + nextLine +
|
||
"4) 重启OA";
|
||
file = new File(xssutil.getRootPath() + "/WEB-INF/prop/openRSA.properties");
|
||
if (file.exists()) {
|
||
|
||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||
String line1;
|
||
|
||
while ((line1 = bufferedReader.readLine()) != null) {
|
||
if (line1.contains("isrsaopen") && line1.contains("=") && line1.contains("1")) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已开启登陆加密";
|
||
break;
|
||
}
|
||
}
|
||
try {
|
||
bufferedReader.close();
|
||
} catch (Exception e) {
|
||
|
||
}
|
||
}
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测是否已开404错误页面</td>
|
||
<%
|
||
SecurityCheckList scl = new SecurityCheckList();
|
||
if (scl.is404PageConfig()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已配置404错误页面";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未配置404错误页面" + nextLine +
|
||
"在web.xml的的末尾</web-app>上方添加如下代码即可\n" + nextLine +
|
||
"<error-page>\n" + nextLine +
|
||
"<error-code>404</error-code>\n" + nextLine +
|
||
"<location>/security/error404.jsp</location>\n" + nextLine +
|
||
"</error-page>\n" + nextLine +
|
||
"修改完成后请重启OA服务";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">检测是否已开500错误页面</td>
|
||
<%
|
||
if (scl.is500PageConfig()) {
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已配置500错误页面";
|
||
} else {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "未配置500错误页面" + nextLine +
|
||
"在web.xml的的末尾</web-app>上方添加如下代码即可\n" + nextLine +
|
||
"<error-page>\n" + nextLine +
|
||
"<error-code>500</error-code>\n" + nextLine +
|
||
"<location>/security/error500.jsp</location>\n" + nextLine +
|
||
"</error-page>\n" + nextLine +
|
||
"修改完成后请重启OA服务";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">H2驱动包检测(<font color='red'>*必须处理*</font>)</td>
|
||
<%
|
||
|
||
checkJarStatus = 0;
|
||
jarVersion = 0l;
|
||
classPath = "/org/h2/jdbc/JdbcStatement.class";
|
||
|
||
try{
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
if (!"".equals(jarPath)) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>请删除此文件。 ";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = pass;
|
||
checkMessage = "已修复";
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">CommonCollection包版本检测</td>
|
||
<%
|
||
|
||
checkJarStatus = 0;
|
||
jarVersion = 0l;
|
||
classPath = "/org/apache/commons/collections/CollectionUtils.class";
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
|
||
try{
|
||
jarVersion = getVersion(classPath);
|
||
|
||
if (jarVersion >= 3002002000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的CommonCollection包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">FreeMarker包版本检测</td>
|
||
<%
|
||
|
||
checkJarStatus = 0;
|
||
jarVersion = 0l;
|
||
classPath = "/freemarker/template/TemplateDateModel.class";
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
|
||
try{
|
||
jarVersion = getVersion(classPath);
|
||
|
||
if (jarVersion >= 2003019000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的FreeMarker包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">CommonFileUpload包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
jarVersion = 0l;
|
||
classPath = "/org/apache/commons/fileupload/DiskFileUpload.class";
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
|
||
try{
|
||
jarVersion = getVersion(classPath);
|
||
|
||
if (jarVersion >= 1005000000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的CommonFileUpload包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">XStream包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
classPath = "/com/thoughtworks/xstream/XStream.class";
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
jarVersion = 0l;
|
||
try{
|
||
jarVersion = getVersion(classPath);
|
||
|
||
if (jarVersion >= 1004020000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的xstream包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">FastJson包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
jarVersion = 0l;
|
||
classPath = "/com/alibaba/fastjson/JSONObject.class";
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
String vPath = "META-INF/maven/com.alibaba/fastjson/pom.properties";
|
||
String preStr = "version";
|
||
String mark = "=";
|
||
|
||
try{
|
||
jarVersion = getSpecialJarVersion(classPath,vPath,preStr,mark);
|
||
|
||
if (jarVersion >= 1002083000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的fastjson包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 ";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">Jackson包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
classPath = "/com/fasterxml/jackson/databind/util/BeanUtil.class";
|
||
|
||
jarVersion = 0l;
|
||
try{
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
jarVersion = getVersion(classPath);
|
||
if (jarVersion >= 2014001000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的Jackson包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align:center;">postgresql包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
classPath = "/org/postgresql/core/Encoding.class";
|
||
jarVersion = 0l;
|
||
try{
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
jarVersion = getVersion(classPath);
|
||
if (jarVersion >= 42005005000L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的postgresql包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">dubbo包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
classPath = "/org/apache/dubbo/rpc/RpcContext.class";
|
||
jarVersion = 0l;
|
||
try{
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
jarVersion = getVersion(classPath);
|
||
if (jarVersion >= 2007002200L) {
|
||
checkJarStatus = 1;
|
||
checkStatusMsg = pass;
|
||
checkMessage = "可靠的dubbo包版本!版本:"+jarVersion;
|
||
}
|
||
|
||
if (checkJarStatus == 0) {
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
} catch (Exception e){
|
||
checkStatusMsg = refuse;
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion + "</br> 请清理之后再手动更新官网最新安全补丁包 </br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
|
||
<tr>
|
||
<td style="text-align:center;">log4j包版本检测</td>
|
||
<%
|
||
checkJarStatus = 0;
|
||
classPath = "/org/apache/logging/log4j/core/lookup/JndiLookup.class";
|
||
//classPath = "/org/apache/log4j/ConsoleAppender.class";
|
||
jarVersion = 0l;
|
||
try{
|
||
jarPath = this.getClass().getResource(classPath).getPath();
|
||
checkStatusMsg = "未判断 ";
|
||
try{
|
||
jarVersion = getVersion(classPath);
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion+"</br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
} catch (Exception e){
|
||
checkMessage = "当前的依赖路径为:"+jarPath.split("!")[0] + "<br/>版本:"+jarVersion+"</br> ps:此处如果依赖路径中包含%[数字+字母]之类的乱码的情况证明该依赖中包含中文路径</br> 包含中文路径的依赖请直接删除";
|
||
}
|
||
}catch(Exception e){
|
||
checkStatusMsg = pass;
|
||
checkMessage = "未找到相关依赖!"+classPath;
|
||
}
|
||
|
||
|
||
%>
|
||
<td style="text-align:center;"><%=checkStatusMsg%>
|
||
</td>
|
||
<td><%=checkMessage%>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
</body>
|
||
</html>
|
||
|
||
<%!
|
||
private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||
|
||
public char[] encodeHex(byte[] data, char... toDigits) {
|
||
int l = data.length;
|
||
char[] out = new char[l << 1];
|
||
int i = 0;
|
||
|
||
for (int var5 = 0; i < l; ++i) {
|
||
out[var5++] = toDigits[(240 & data[i]) >>> 4];
|
||
out[var5++] = toDigits[15 & data[i]];
|
||
}
|
||
|
||
return out;
|
||
}
|
||
|
||
public String md5Hex(String input) {
|
||
try {
|
||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||
digest.update(input.getBytes());
|
||
byte[] md5bytes = digest.digest();
|
||
return new String(encodeHex(md5bytes, DIGITS_LOWER));
|
||
} catch (Throwable var4) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
private static List whiteList = new Vector();
|
||
final static String SPECIAL_CODE = "%@";
|
||
|
||
static {
|
||
//基础白名单
|
||
whiteList.add("debug.jsp");
|
||
whiteList.add("debugm.jsp");
|
||
whiteList.add("SecurityInspectionCheck.jsp");
|
||
whiteList.add("monitorXOperation.jsp");
|
||
whiteList.add("checkdone.jsp");
|
||
whiteList.add("secCheck.jsp");
|
||
whiteList.add("checkFile.jsp");
|
||
//getRuntime白名单
|
||
whiteList.add("checkredis.jsp");
|
||
whiteList.add("MyJsp.jsp");
|
||
//getRuntime白名单
|
||
whiteList.add("checkredis.jsp");
|
||
whiteList.add("getredis.jsp");
|
||
whiteList.add("redis\\ecologyClusterConfigCheck.jsp");
|
||
whiteList.add("redis/ecologyClusterConfigCheck.jsp");
|
||
//base64白名单
|
||
whiteList.add("datacenter\\maintenance\\inputreport\\InputReportEdit.jsp");
|
||
whiteList.add("datacenter/maintenance/inputreport/InputReportEdit.jsp");
|
||
whiteList.add("debug\\upload.jsp");
|
||
whiteList.add("debug/upload.jsp");
|
||
whiteList.add("debug\\uploadm.jsp");
|
||
whiteList.add("debug/uploadm.jsp");
|
||
whiteList.add("synccache.jsp");
|
||
//@include白名单
|
||
whiteList.add("cloudstore\\resource\\pc\\com\\icon-coms\\index.jsp");
|
||
whiteList.add("cloudstore/resource/pc/com/icon-coms/index.jsp");
|
||
whiteList.add("workrelate\\goal\\data\\TreeShowNew.jsp");
|
||
whiteList.add("workrelate/goal/data/TreeShowNew.jsp");
|
||
//常用白名单
|
||
whiteList.add("ecologyClusterConfigCheck.jsp");
|
||
whiteList.add("\\join\\SecurityInspectionCheck.jsp");
|
||
whiteList.add("/join/SecurityInspectionCheck.jsp");
|
||
whiteList.add("\\wui\\secCheck.jsp");
|
||
whiteList.add("/wui/secCheck.jsp");
|
||
whiteList.add("getredis.jsp");
|
||
whiteList.add("checkreds.jsp");
|
||
whiteList.add("ecology\\formmode\\zh_remindtest.jsp");
|
||
whiteList.add("ecology/formmode/zh_remindtest.jsp");
|
||
whiteList.add("ecology/login/LoginSSOAD.jsp");
|
||
whiteList.add("ecology\\login\\LoginSSOAD.jsp");
|
||
whiteList.add("ecology/wui/newFile.jsp");
|
||
whiteList.add("ecology\\wui\\newFile.jsp");
|
||
}
|
||
|
||
private boolean fileWhiteListCheck(String path) {
|
||
|
||
if (path == null || "".equals(path)) {
|
||
return false;
|
||
}
|
||
|
||
for (Object white : whiteList) {
|
||
if (path.contains((String) white)) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
public List getFiles(String filepath) {
|
||
List files = new Vector();
|
||
listFiles(files, filepath);
|
||
return files;
|
||
}
|
||
|
||
public void listFiles(List files, String dirName) {
|
||
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")) {
|
||
if (checkFile(f)) {
|
||
files.add(f.getAbsolutePath());
|
||
}
|
||
}
|
||
} else if (f.isDirectory()) {
|
||
if (!f.getPath().trim().endsWith("WEB-INF") && !f.getPath().trim().endsWith("filesystem"))
|
||
listFiles(files, f.getAbsolutePath());
|
||
}
|
||
}
|
||
}
|
||
} catch (Exception e) {
|
||
}
|
||
}
|
||
|
||
public boolean checkCode(String code) {
|
||
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")) {
|
||
return true;
|
||
} else if (code.contains(".getMethod(")) {
|
||
return true;
|
||
} else if (code.contains("@include") && !code.contains(".jsp\"")) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
private boolean checkFile(File file) {
|
||
if (fileWhiteListCheck(file.getPath())) {
|
||
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())) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
|
||
} catch (Exception e) {
|
||
} finally {
|
||
try {
|
||
is.close();
|
||
} catch (Exception e) {
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
private long getVersion(String fileuploadPath) throws IOException {
|
||
String path = this.getClass().getResource(fileuploadPath).getPath();
|
||
if (path == null) {
|
||
return -1;
|
||
}
|
||
|
||
Properties props = System.getProperties();
|
||
String Osname = props.getProperty("os.name");
|
||
weaver.filter.XssUtil util = new weaver.filter.XssUtil();
|
||
File weblogicFile = new File(util.getRootPath() + "WEB-INF/weblogic.xml");
|
||
if (!weblogicFile.exists()) {
|
||
if (Osname.contains("Windows")) {
|
||
path = path.substring("file:/".length(), path.indexOf("jar") + "jar".length());
|
||
} else {
|
||
path = path.substring("file:".length(), path.indexOf("jar") + "jar".length());
|
||
}
|
||
} else {
|
||
path = path.substring(0,path.indexOf("jar") + "jar".length());
|
||
}
|
||
JarFile jarFileFileupload = new JarFile(path);
|
||
long version = 0;
|
||
Enumeration<JarEntry> enume = jarFileFileupload.entries();
|
||
|
||
while (enume.hasMoreElements()) {
|
||
JarEntry entry = enume.nextElement();
|
||
if ("META-INF/MANIFEST.MF".equals(entry.getName())) {
|
||
InputStream input = jarFileFileupload.getInputStream(entry);
|
||
BufferedReader readerMF = new BufferedReader(new InputStreamReader(input));
|
||
String line = readerMF.readLine();
|
||
while (null != line) {
|
||
if (line.contains("Implementation-Version:")) {
|
||
String versionNow = line.substring(line.lastIndexOf("Implementation-Version:") + "Implementation-Version:".length());
|
||
long versionNowInt = 0;
|
||
String[] tmps = versionNow.trim().split("\\.");
|
||
if (1 == tmps.length) {
|
||
|
||
versionNowInt = Long.parseLong(tmps[0] + "000000000");
|
||
} else if (2 == tmps.length) {
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + "000000");
|
||
} else if (3 == tmps.length) {
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
|
||
int c = 3 - tmps[2].length();
|
||
while (0 < c) {
|
||
tmps[2] = "0" + tmps[2];
|
||
c--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + tmps[2] + "000");
|
||
} else if (4 == tmps.length) {
|
||
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
|
||
int c = 3 - tmps[2].length();
|
||
while (0 < c) {
|
||
tmps[2] = "0" + tmps[2];
|
||
c--;
|
||
}
|
||
|
||
int d = 3 - tmps[3].length();
|
||
while (0 < d) {
|
||
tmps[3] = "0" + tmps[3];
|
||
d--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + tmps[2] + tmps[3]);
|
||
}
|
||
return versionNowInt;
|
||
}
|
||
line = readerMF.readLine();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
private long getSpecialJarVersion(String fileuploadPath, String vPath, String preStr, String mark) throws IOException {
|
||
String path = this.getClass().getResource(fileuploadPath).getPath();
|
||
if (path == null) {
|
||
return -1;
|
||
}
|
||
|
||
Properties props = System.getProperties();
|
||
String Osname = props.getProperty("os.name");
|
||
weaver.filter.XssUtil util = new weaver.filter.XssUtil();
|
||
File weblogicFile = new File(util.getRootPath() + "WEB-INF/weblogic.xml");
|
||
if (!weblogicFile.exists()) {
|
||
if (Osname.contains("Windows")) {
|
||
path = path.substring("file:/".length(), path.indexOf("jar") + "jar".length());
|
||
} else {
|
||
path = path.substring("file:".length(), path.indexOf("jar") + "jar".length());
|
||
}
|
||
} else {
|
||
path = path.substring(0,path.indexOf("jar") + "jar".length());
|
||
}
|
||
JarFile jarFileFileupload = new JarFile(path);
|
||
long version = 0;
|
||
Enumeration<JarEntry> enume = jarFileFileupload.entries();
|
||
|
||
while (enume.hasMoreElements()) {
|
||
JarEntry entry = enume.nextElement();
|
||
if (vPath.equals(entry.getName())) {
|
||
InputStream input = jarFileFileupload.getInputStream(entry);
|
||
BufferedReader readerMF = new BufferedReader(new InputStreamReader(input));
|
||
String line = readerMF.readLine();
|
||
while (null != line) {
|
||
if (line.contains(preStr)) {
|
||
String versionNow = line.split(mark)[1].trim();
|
||
long versionNowInt = 0;
|
||
String[] tmps = versionNow.trim().split("\\.");
|
||
if (1 == tmps.length) {
|
||
|
||
versionNowInt = Long.parseLong(tmps[0] + "000000000");
|
||
} else if (2 == tmps.length) {
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + "000000");
|
||
} else if (3 == tmps.length) {
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
|
||
int c = 3 - tmps[2].length();
|
||
while (0 < c) {
|
||
tmps[2] = "0" + tmps[2];
|
||
c--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + tmps[2] + "000");
|
||
} else if (4 == tmps.length) {
|
||
|
||
int a = 3 - tmps[1].length();
|
||
while (0 < a) {
|
||
tmps[1] = "0" + tmps[1];
|
||
a--;
|
||
}
|
||
|
||
int c = 3 - tmps[2].length();
|
||
while (0 < c) {
|
||
tmps[2] = "0" + tmps[2];
|
||
c--;
|
||
}
|
||
|
||
int d = 3 - tmps[3].length();
|
||
while (0 < d) {
|
||
tmps[3] = "0" + tmps[3];
|
||
d--;
|
||
}
|
||
versionNowInt = Long.parseLong(tmps[0] + tmps[1] + tmps[2] + tmps[3]);
|
||
}
|
||
return versionNowInt;
|
||
}
|
||
line = readerMF.readLine();
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
%> |