It’s me, I’m Gary.

建立安全可靠的軟體開發流程

eCloudValley: 架構師淺談 建立安全可靠的軟體開發流程 安全軟體開發生命週期(SSDLC)介紹 安全軟體開發生命週期(SSDLC)是一個將安全性考量整合到軟體開發過程中的方法,旨在從一開始就預防和減少安全漏洞。這個方法不僅能提升軟體的安全性,還能減少後期修復安全漏洞的成本。SSDLC 通常包含以下幾個主要階段:需求分析、設計、實作、測試、部署和維護。每個階段都有特定的安全實踐和工具來保障軟體的安全性。 需求分析階段 目標 確保所有安全需求都得到充分的識別和記錄。 實作方式 威脅建模(Threat Modeling) 目的:識別系統中可能存在的威脅,並確定如何應對這些威脅。 AWS 原生服務:AWS 威脅建模工具(AWS Threat Modeling)可以幫助識別和分析威脅,並提供相應的緩解措施。 安全需求規範 目的:確保安全需求被納入需求規範中,涵蓋認證、授權、數據保護等方面。 最佳實踐:參考 OWASP Application Security Verification Standard(ASVS)來確定各種安全需求。 設計階段 目標 在設計階段建構安全架構,選擇合適的安全控制措施。 實作方式 安全架構設計 目的:應用安全設計模式和最佳實踐,確保系統設計能抵禦已知威脅。 AWS 原生服務:使用 AWS Well-Architected Framework 中的安全支柱(Security Pillar)來設計安全架構。 設計審查 目的:進行安全設計審查,確保設計符合安全需求。 AWS 原生服務: AWS Well-Architected Tool 可以幫助審查設計,確保符合安全最佳實踐。 實作階段 目標 編寫安全的程式碼,並進行持續的安全檢查。 實作方式 安全程式碼編寫 目的:遵循安全編碼標準和指南,減少程式碼中的安全漏洞。 資源:參考 OWASP 安全編碼指南,確保程式碼符合安全標準。 靜態應用安全測試(SAST) 目的:使用靜態分析工具檢查程式碼中的安全漏洞。 AWS 原生服務:Amazon CodeGuru Reviewer 可以自動審查程式碼並提出改進建議。 依賴性管理 目的:確保使用安全的第三方庫和框架,避免引入已知漏洞。 AWS 原生服務:AWS CodeArtifact 可以管理和存儲軟體包,確保依賴庫的安全性。 在這個階段也建議可以導入版本控制系統 (Git), Git 使用 SHA-1 來標識每個提交、文件和目錄。這意味著任何變更皆可以被檢測到,這樣的設計確保了數據的完整性,防止了未經授權的修改,且一旦提交被創建並推送到儲存庫中,其歷史記錄是不可變的,這意味著開發者無法隱瞞或篡改他們之前的變更,這提供了一個清晰的審計軌跡,使得任何變更都可以追溯到具體的提交和責任人,若企業所架設的網站疑似遭到攻擊者上傳木馬或後門,開發者可以立即使用最乾淨的版本進行快速重新部署。 ...

2024-09-26 · Gary Tan

企業該如何評估 SOC 需要收容哪種資料

eCloudValley: 架構師淺談 企業該如何評估 SOC 需要收容哪種資料 我們可以藉由 SOC 收容各種作業系統、設備以及應用程式產出之日誌紀錄進行關聯分析,我們可以從收容的各端點日誌紀錄發現可能潛在的攻擊風險。那身為資安工程師的我們,該如何去評估決定該將哪些日誌紀錄送至 SOC 中進行儲存及分析?以一般雲端環境如 AWS 為例,我們首要先收容的日誌紀錄會是與 AWS 基礎設施相關的紀錄內容,如: VPC flow log RDS audit log/Aurora audit log AWS WAF log AWS Cloudtrail log AWS GuardDuty log Amazon CloudFront log Elastic load balancing (ALB) log 那於地端環境呢?在地端環境中我們可以收容哪些內容,來增加我們整體的資安防禦能力。 在以往我們事件調查時的經驗,常常會遇到日誌紀錄收集不完全而造成線索中斷,無法完整的還原整起攻擊事件的全貌,我們可以藉由收容以下的日誌內容以保全完整的攻擊軌跡。 Windows eventlog 開啟命令列程序稽核(Command line auditing) 可於群組原則中開啟此功能(電腦設定 > Windows 設定 > 安全性設定 > 進階稽核設定 > 詳細追蹤 > 稽核程序建立),並且開啟新的原則設定(系統管理範本 > 系統 > 稽核程序建立 > 在程序建立事件中包括命令列),開啟此功能後若有程式執行系統指令即會在 Security eventlog 中記錄一筆 4688 的紀錄。 ...

2024-05-23 · Gary Tan

HITCON 2021 DEVCORE Wargame Writeup

Flag 1 在首頁可以看到一張圖片,URL長成這樣。 http://web.ctf.devcore.tw/image.php?id=aHBfbTI4M2Zkdy5qcGc= 其中 aHBfbTI4M2Zkdy5qcGc= 拿去 base64 deocde 會變成 hp_m283fdw.jpg ,發現是一個檔名, 這裡可以嘗試 path traversal。 嘗試讀取 ../../../../etc/passwd 成功,繼續嘗試讀取 source code。 先讀取 mount device ../../../../proc/mounts,嘗試找出 web root。 /dev/sda /usr/share/nginx/frontend ext4 ro,relatime,errors=remount-ro,data=ordered 0 0 /dev/sda /usr/share/nginx/images ext4 rw,relatime,errors=remount-ro,data=ordered 0 0 /dev/sda /usr/share/nginx/b8ck3nd ext4 ro,relatime,errors=remount-ro,data=ordered 0 0 接著讀取 /usr/share/nginx/frontend/index.php 可以發現首頁的 source code。 裡面有引入 include.php,讀取 include.php 後可以在裡面發現第一個 flag。 Flag 2 在 order.php 中,可以看到 sig 沒有做型別的驗證,可以利用 PHP 的弱型別繞過程式中的 sig 驗證。 # order.php require_once('include.php'); $id = get_get_param('id', ''); $sig = get_get_param('sig', ''); if (empty($id) || empty($sig)) { header('Location: /'); exit(); } $id = intval($id); $pdo = get_pdo(); $res = $pdo->query('SELECT * FROM orders WHERE id = '.$id, PDO::FETCH_ASSOC); $order = $res->fetch(); if (!$order) { $_SESSION['error_msg'] = '找不到此訂單'; require_once('error.php'); } $sig_hash = get_sig_hash($sig); if ($sig_hash && $sig_hash != $order['sig_hash']) { $_SESSION['error_msg'] = '訂單網址參數錯誤'; require_once('error.php'); } switch ($order['status']) { case ORDER_STATUS_PICKING: $step = 1; break; case ORDER_STATUS_PACKING: $step = 2; break; case ORDER_STATUS_SENDING: $step = 3; break; case ORDER_STATUS_DELIVERING: $step = 4; break; case ORDER_STATUS_ARRIVED: $step = 5; break; case ORDER_STATUS_FINISH: $step = 6; break; } # include.php function get_sig_hash($data) { $pdo = get_pdo(); $res = $pdo->query("SELECT `value` FROM options WHERE `key` = 'sig_secret' LIMIT 1", PDO::FETCH_ASSOC); $row = $res->fetch(); if (!$row) { $secret = random_str(64); $pdo->exec("INSERT INTO options VALUES ('sig_secret', '".$secret."'), ('sig_algorithm', 'sha256')"); } else { $secret = $row['value']; } $res = $pdo->query("SELECT `value` FROM options WHERE `key` = 'sig_algorithm' LIMIT 1", PDO::FETCH_ASSOC); $algo = $res->fetch()['value']; return hash_hmac($algo, $data, $secret); } 如果將 sig 以陣列的方式傳入 if ($sig_hash && $sig_hash != $order['sig_hash']) 結果會變成 if (NULL && NULL != "abc") 恆為 False。 ...

2021-11-30 · Gary Tan