漏洞資料庫暴力搜集資訊

從 Client 暴力蒐集 server 端的資訊,再一點一滴拼湊出可能用到的技術(如 framework|libs|database|ui-js|ui-css) 或是 input parameters 漏洞,在累積一段時間過後再一次搭配 shell 破解。

對應方案

  1. 時常注意 CVE
  2. 時常注意 dependency check(PATCH) 最好是整合 CI
  3. 裝 WAF(Web Application Firewall) 網站應用程式防火牆

如果上述什麼都沒做的話可以仿造以下的做法,稍稍抵擋一下延遲被情蒐的機率(第一時間中斷情蒐), 然後通報資安團隊封鎖該 IP。

以 java server 為例

如果 server 端是以 java 技術撰寫,可以寫一小filter 偵測是否有異常的關鍵字存取,如果有立即通知資安系統管理者,立即封鎖該 IP。

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

public class Yes26Filter extends OncePerRequestFilter {
    
    private static final String[] words = new String[] {
            "/WEB-INF/", "../", ".php", ".yml", ".sql", ".ini", ".log", ".dll",
            "/jars/", "/actuator", "/struts2", "/javax.faces.resource", "/OA_HTML", "/resin-doc",
            "/page/exportImport", "/solr", "/jira", "/owa/auth", "/microsoft", "/.git", "/docker-",
             "/cgi-bin", ".cgi", "/oauth", "/etc/passwd"};

    private static boolean IsVulnerable(String uri) {
        for (String s : words) {
          if ( uri.contains(s) ) { return true; }
        }
        return false;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        
        filterChain.doFilter(request, response);
        
        if( response.getStatus() == HttpStatus.NOT_FOUND.value()) {
            String reqURI = request.getRequestURI();
            if( IsVulnerable(reqURI) ) {
                String remoteAddr = getRemoteIp(request);
                String message = String.format("[%s][%s][%d]", remoteAddr, reqURI, response.getStatus() ); 
                System.out.println(message);
                // log ip and notify
                // notifyCSIRT(remoteAddr, reqURI, response.getStatus());
                return;
            }
        }
    }

    public static String getRemoteIp(HttpServletRequest request) {
        String remoteAddr = request.getHeader("X-FORWARDED-FOR");  
        if ( StringUtils.hasLength(remoteAddr) ) {  
            return remoteAddr;
        }
        remoteAddr = request.getHeader("Proxy-Client-IP");  
        if ( StringUtils.hasLength(remoteAddr) ) {  
            return remoteAddr;
        }
        remoteAddr = request.getHeader("X-Real-IP");  
        if ( StringUtils.hasLength(remoteAddr) ) {  
            return remoteAddr;
        }
        remoteAddr = request.getHeader("WL-Proxy-Client-IP");  
        if ( StringUtils.hasLength(remoteAddr) ) {  
            return remoteAddr;
        }
        remoteAddr = request.getHeader("HTTP_CLIENT_IP");  
        if ( StringUtils.hasLength(remoteAddr) ) {  
            return remoteAddr;
        }
        return request.getRemoteAddr();  
    }
}