iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0

資安攻防戰

資安攻防戰

因為大學專題的關係,我選擇了 PHP 作為開發語言。不過那時候環境還不成熟,PHP 從 4.x 正要升級到 5.x,沒有 Framework 可用,整個開發過程幾乎是土法煉鋼,非常辛苦。

「Ray,你的 PHP 有做資安防禦嗎?」老師在我製作專題的過程中,問了我這個問題。

老實說,那時候我完全沒想到這件事。可老師既然特別強調,顯然代表這點非常重要。於是我開始在心裡猜測:到底是哪裡需要特別注意?

就在我還在思索的瞬間,老師的下一句話,直接打斷了我的思考——

「到時候發表時,你們會先把作品交給系主任和其他老師試用,但記得不要提供後台,發表時由你們自己操作就好,這樣才能避免被其他老師亂搞。」老師叮嚀著說。

ㄟ…原來老師這樣提醒不是沒道理的。
說穿了,專題不只學生在拚,老師之間其實也在暗暗較勁,畢竟誰不想自己的學生做出最亮眼的成果?所以偶爾就會出現一些小心機、小競爭。

我心裡只能默默想:
「哇,原來專題戰場不只在學生之間,老師們背後也有小劇場啊 XD」

一路從跌跌撞撞到最後的專題發表,過程雖然辛苦,但也因為老師對細節的嚴格把關,從簡報內容到報告方式都幫我們拉了一把,結果發表會當天一切都非常順利,不只拿到系上老師們的讚賞,最後作品甚至被選為招生範例。

對我們這組來說,這完全是一場漂亮的逆轉勝。

專題發表的時候看起來風光順利,但等我後來仔細研究資安防禦,回頭檢視我們的系統時才發現 ——那根本不是作品,是一塊蜂巢,滿滿都是洞啊 XD

至於後來我們的專題系統嘛……直接被我玩到壞掉,結局比發表會還要精彩。XD

資安防禦的基本概念

那麼資安防禦到底在講什麼呢?簡單來講就是不被駭客入侵,或者是防止駭客入侵後造成的損害。

有些人可能不太懂什麼是駭客以及駭客其實有區分為三大類:

  • 白帽駭客: 這類駭客是為了保護系統而存在的,他們會找出系統的漏洞並且通知系統管理員修補漏洞,又稱道德駭客。
  • 黑帽駭客: 主要是以自己利益為優先,利用系統的漏洞來獲取非法利益。
  • 灰帽駭客: 這類駭客介於白帽與黑帽之間。

其中我們最不希望遇到的就是黑帽駭客。

早些年有一場非常知名的黑帽駭客事件 —— 「WannaCry(中文:想哭、想解密)」 那次攻擊讓許多企業與個人都蒙受巨大損失。

前面章節中我們提到過,中毒本身就是件麻煩的事,更何況有些病毒並不是單純重新安裝作業系統就能解決。因為它們可能早已潛伏在你的檔案或備份裡,所以即使重灌系統,依然會再次被感染。

這邊也簡單講一下當年的令人聞風喪膽的 WannaCry 病毒。

WannaCry 是一種利用 Microsoft Windows 系統漏洞的勒索病毒,當電腦遭到感染時,它會立即加密你的檔案,接著要求你支付比特幣才能解鎖。

它採用了 非對稱加密 的方式,這種加密的特點是使用一組金鑰:公開金鑰與私密金鑰。公開金鑰負責加密資料,而只有私密金鑰才能解密,也就是說,如果你不按照駭客的指示支付贖金,就無法拿到解密所需的私密金鑰,你的檔案也就等於被永久鎖死。

Note
如果想多了解加密的議題,可以參考我之前寫的文章:加密是什麼呢?為什麼要加密?關於加密的基本觀念

你可能會想:「那我只要定期備份就好了吧?」
沒錯,定期備份是一個手段,但問題在於 —— 如果連備份也被感染了,那麼當你還原時,病毒也會一併回來。

老實說,我早期也曾中過一次毒,當時用雲端硬碟備份檔案,但因為沒有回溯功能,連備份也被感染,幸好資料不重要,我只好直接放棄,畢竟照當時的 Bitcoin 價格來算,贖金得要好幾萬台幣。

這也是為什麼大家都強調:只要出現重大資安漏洞,就一定要立刻更新系統。因為如果不更新,就等於把大門敞開,讓駭客隨時能進來。

通常來講備份方式會有兩種:

  • 本地備份:簡單來講就是將自己電腦的重要資料拷貝一份到其他儲存裝置上,例如:外接硬碟、USB 隨身碟等。
  • 異地備份:將資料備份到其他地方,例如:雲端儲存服務、遠端伺服器等。

這兩種備份方式各有優缺點,本地備份的優點是速度快、成本低,但是如果你的電腦被入侵了,那麼本地備份也會被感染;異地備份的優點是可以避免本地備份被感染,但是速度較慢、成本較高。

上面我們所講的比較偏向個人電腦的資安防禦,但如果今天我們是寫程式呢?那麼要考慮的方向就不同了。

這邊要來提一個很常見的攻擊手法,也就是 SQL Injection(SQL 注入攻擊),這種攻擊是利用程式在處理 SQL 語句時,沒有對使用者輸入進行適當過濾或轉義,讓攻擊者有機會注入惡意的 SQL 指令,進而操控資料庫。

在當時 ORM(俗稱:物件關聯對映)還不流行,大家幾乎都是直接用 SQL 語句操作資料庫,所以 SQL 注入攻擊 變得特別常見。

這邊舉例一下前一篇章節所介紹的 PHP 程式碼:

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>第一個 PHP 程式</title>
</head>
<body>
  <?php
      $username = "admin";
      $password = "password123";

      $connection = mysqli_connect("localhost", $username, $password);
      if ($connection) {
          echo "<div>成功連接到 MySQL 資料庫!</div>";
      } else {
          echo "<div>無法連接到 MySQL 資料庫!</div>";
      }

      mysqli_close($connection);
  ?>
</body>
</html>

一般情況下,使用者會在畫面上輸入帳號和密碼,程式再把這些資料傳送到資料庫做驗證,這時候就會用到 SQL 語句來進行資料庫操作,例如:

$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

這段程式碼的意思是:從 users 資料表中,找出使用者名稱等於 $username 、密碼等於 $password 的資料,如果找到符合條件的紀錄,就代表使用者輸入的帳號與密碼正確。

但如果今天使用者輸入的是 $username = "admin' OR '1'='1" 呢?那就會變成以下的 SQL 語句:

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '$password'

這句 SQL 意思是「選取使用者名稱為 'admin' 或者 '1' 等於 '1' 的使用者資料」,由於 '1' 等於 '1' 永遠成立,所以這個 SQL 語句會返回所有使用者的資料,這樣就可以繞過驗證,直接登入系統。

你可能會疑惑一件事情:

「後面不是有 AND password = '$password' 嗎?那麼這樣不就還是會被驗證嗎?」

其實這個問題很好,因為在 SQL 語句中,OR 的優先級是高於 AND 的,所以這個 SQL 語句會先執行 OR 的部分,然後再執行 AND 的部分,所以最後的結果就是會返回所有使用者的資料。

最後再提一個常見的攻擊手法,在建立資料庫時,我們通常會對欄位設定型別限制,例如使用者名稱只能存放字串,密碼欄位也只能存放字串。

但如果沒有對欄位設定長度限制,攻擊者就可能利用這個漏洞發動攻擊。

那這種攻擊手法是什麼呢?其實它屬於 DoS(Denial of Service,阻斷服務攻擊) 的一種,做法就是在欄位裡存入一筆超長的字串,導致資料庫在處理時因為字串過長而消耗大量系統資源,最終把系統拖到當機。

結語

WannaCry 爆發的時候,我身邊的朋友都陸續中毒,就連我也沒能倖免,幸好當時資料不重要,所以我也就直接放棄。

不知道有沒有人中過 WannaCry 的經驗呢?

同步更新

本文將同步更新至以下網站:


上一篇
【Day 23】PHP?蛤?一隻大象?
系列文
Code Review 我的青春:從『嗶』聲開啟我的軟體工程師之路24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言