1 of 38

程式碼漏洞分析與Code Review 後感

2 of 38

關於

  • es
  • python/node
  • fullstack/infosec/devops

3 of 38

背景說明

  • 這是一個專案
  • 客戶身份保密
  • bug 很多

4 of 38

常見漏洞 (以 Web 為例)

  • OWASP Top 10 (2017)
    • Injection
    • XSS/CSRF
    • 私密資料暴露
    • XXE
    • 身份驗證缺失
    • 安全設定錯誤
    • 認證錯誤
    • 不安全的反序列化
    • 軟體本身漏洞
    • Log 做的不足��
  • shit logic
    • “後門”功能
    • race condition
    • 認證寫壞
  • 其它
    • 內鬼

5 of 38

談「應用程式安全風險」

6 of 38

安全問題分級

7 of 38

OWASP - Injection

  • 但是 injection 並不限於 SQL….
  • os.exec() / LDAP / NoSQL / Server-side Template / 其它

8 of 38

OWASP - XSS/CSRF

  • XSS
    • TodoMVC 或 任何把其它使用者輸入顯示在頁面上的站台
    • Howard 婚禮 LINE BOT
  • CSRF
    • 幫你砍 Gmail 信

9 of 38

OWASP - 身份驗證缺失

  • 「Broken Authorization」
    • 可以讓人撞庫撞到飽
    • 使用者密碼太弱
    • 密碼找回流程太弱
    • Session ID 可預測或無設定時效

10 of 38

OWASP - 私密資料暴露

  • 私密資訊在運輸和儲存過程中的安全
    • HTTPS / TLS / HSTS
    • crypt / scrypt / pbkdf2
    • 磁碟加密
  • PCI DSS
  • 露天拍賣或某些小商城
  • Equifax

11 of 38

OWASP - XXE

  • 有點古老
  • XML External Entities

12 of 38

OWASP - 認證錯誤

  • 看別人的資訊
  • 提權/假冒身份
    • 邏輯問題
    • 改密碼時送 { password: password, admin = true }
  • JWT 驗證沒做好
    • 又稱:「我拿令牌,叫你吃屎,你就吃屎」

13 of 38

OWASP - 安全設定錯誤

  • nginx/apache2 設定錯誤,可以執行任一檔或直接瀏覽目錄
  • 預設用的帳密沒改
  • 裝太多沒用到的東西
    • phpmyadmin
  • 錯誤時返回 stack trace
  • 軟體本身有洞
    • struts2, 太老的 php, 太老的 openssl

14 of 38

OWASP - 反序列化

  • python: pickle(), php: unserialize(), node 沒這東西
  • 從後端的角度來看,用序列化存東西不一定好
  • 認證錯誤 / 改變程式行為
  • RCE

15 of 38

OWASP - Log 不足

  • 2017 年列入
  • 登入、登入失敗、高風險動作

16 of 38

談 code 本身

17 of 38

背景資訊

  • 不曉得客戶是誰
  • 做白箱測試
  • 有測試機可以打
  • 有 WAF

18 of 38

插曲

要產生報告,所以要測試

被 waf 鎖 IP,WTF

19 of 38

why code review?

  • RCA (root cause analysis)
  • 程式架構分析
  • 不常見的漏洞
  • 特殊需求

20 of 38

Source / Sink

21 of 38

Source / Sink

22 of 38

開工喇

nikto2 和 nmap 先敲一敲再說

然後沒找到明顯的洞

23 of 38

順序

  • 環境分析
  • 程式架構分析
  • 程式邏輯分析

24 of 38

環境分析

  • PHP 5.6.9
    • phar 和某些 zip 相關模組有漏洞
  • nginx,版本不明
  • mysql 5.6.16-log
  • (沒有 phpmyadmin…)

25 of 38

程式架構分析

  • 這服務有串 Redis,但我們沒有 Redis 模組原碼,故不能確定有無問題
  • 聊天室使用某家網路公司的即時通訊服務,也使用了雲端儲存服務
  • 大部分的資料庫呼叫都是呼叫某一 module,該 module 再呼叫 mysql_query()
    • 所以 Stacked Query 不可用
    • 而且還有 addslashes() + htmlspecialchars() + trim()
      • db encoding = utf8mb4,如果是 gbk 就有趣了
      • 但這不是用 middleware 來搞的,百處必有一漏 :p

26 of 38

程式架構分析

  • 奇怪的函式呼叫模式
  • GET /index.php?module=a&action=a
  • 呼叫某一資料夾下任一檔案中任一 public 函式
  • combo: 有超過一個進入點可以用
  • 可以呼叫 legacy API 或任一 php 檔 :)

27 of 38

此時已知的問題

  • PHP 版本過舊
  • 潛在的 SQL Blind Injection
  • nginx 未設白名單,可取回任意檔或執行任一 php 檔
  • 可以呼叫某資料夾下任一 public function

28 of 38

程式邏輯分析

  • 客戶回報的問題:
      • 資料庫內容被修改
      • 用戶被登出/被刪除/被篡改資料
      • 強制 App 更新
  • 我們猜測的可能因素
    • SQL Injection
    • Shell / Code Exec

29 of 38

程式邏輯分析

  • 我們找到一個有趣的 API
    • system.action.php
    • 裡面有各種看起來是 “後門” 的功能
      • 刪庫
        • 刪全家
        • 刪某些庫(購買記錄等等)
      • 把使用者 ID 數字變大 (???)

30 of 38

程式邏輯分析

後來找到 legacy API 的接入點

發現沒啥用

31 of 38

程式邏輯分析

  • 發現一個全家都中的洞
  • 這東東在每個 api request 時都會執行.....

32 of 38

程式邏輯分析

  • SQL Injection WAF
    • regex
    • 白名單是個不理想的主意
    • 可以進行盲注
    • (這個 regex 也沒有擋 truncate)

33 of 38

程式邏輯分析

  • 聊天室是使用某雲端平臺的即時通訊服務
  • 其 private key 的位置是可以從源碼得知的
    • 他們用的檔名和這個平臺的教學一樣
    • 配合前面 nginx 設定問題,我們可以獲得 private key
    • 拿到 app ID 之後就可以接上 SDK,以伺服器的身份發訊息
  • 這平臺被破過很多次,所以應該有人手上有源碼
  • 踢人/開直播/關直播等等動作都是靠這即時通訊服務來做的
    • 發一個訊息,跟你說你被踢了

34 of 38

程式邏輯分析

  • API 似乎也支持用 AES 加密 response
    • 實際上沒用到這功能
  • 但有某一隻 system.action.php 下的函式,可以得知目前使用中金鑰的位置
  • 然後再透過 nginx 設定問題拿回來.....

35 of 38

程式邏輯分析

  • 假冒他人身份存取 API
    • 某 legacy API,可以帶上某 request field,改變自己的用戶 id
      • 我說我是誰你就當我是誰

36 of 38

程式邏輯分析

  • 雜項
    • 不用認證就可以對 log 寫內容
    • ???

37 of 38

結論

  • 守比攻難
    • 尤其是這客戶不改源碼,只靠 WAF
    • 攻方只要打一點就成功了
  • 開發者的素質很重要...

38 of 38

結論

  • 一開始不曉得要看什麼問題,所以不太有頭緒
  • static analysis 不一定有用