NTOU IND
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Help
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
# Web Security [TOC] payload 可以參考這個網站 [Web CTF Cheatsheet](https://github.com/w181496/Web-CTF-Cheatsheet) ## What is a website? 一般我們看到的網頁是由 HTML、JavaScript 以及 CSS 組成的 當你到一個網站時,實際上是向一個伺服器發起 HTTP 請求,並以此獲得資源 而瀏覽器則會 render 得到的 HTML 及 CSS 並執行裡面的 JavaScript ### Frontend 在網頁開發中,我們會將使用者可以看到並且操作的部分稱為前端,這部分是由 HTML/CSS/JavaScript 組成的 透過瀏覽器的開發者工具(F12),我們可以看到原始碼 * 主控台(console),可以執行 JavaScript * 來源(source),此頁面所用到的所有 HTML、CSS、JavaScript 或是圖片等 * 網路(network),紀錄此頁面所發起的所有連線 * 應用程式(application),存放此頁面的 Cookie 以及 LocalStorage ### HTML HTML(超文本標記語言) 是用來表示網頁架構的語言,本身雖然不具有任何執行的能力,但是可以在裡面擺放 `<script>` 標籤來讓瀏覽器執行 JavaScript ~~但加上 CSS 可以達成圖靈完備~~ 同時一些如 `<img>` 或是 `<iframe>` 等標籤會讓瀏覽器向伺服器發起 HTTP 請求來取得圖片或是其他資源 瀏覽器會以 [DOM tree](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction) 的形式來對應 HTML 的元素,使得 CSS 可以透過標籤、class 或是 id 來對元素附加 style(樣式) 同時也讓 JavaScript 可以來操控 HTML 的元素 ```xml <!DOCTYPE html> <html> <head> <title>My Link</title> <link rel=stylesheet type="text/css" href="index.css"> </head> <body> <img class="bg-img" src="https://myimage.com"> <div class="content"> <div class="box"> hihi </div> </div> </body> <script> console.log(123) </script> <style> .content { width: 300px; justify-content: center; display: flex; align-items: center; } </style> </html> ``` 每一個標籤都可以含有多個屬性,而某些標籤的某些屬性可以註冊事件,使得在觸發某些事件時執行 JavaScript(按下按鈕、送出表單) ```xml <button class="btn" onclick='alert(1)'> <img id="my-img" src='https://imgur.com/123' onload='console.log(1)'> ``` ### JavaScript ![](https://hackmd.io/_uploads/HycdXGyx6.png) JavaScript 是一個~~自由的語言~~被設計用來操縱網頁的語言,可以透過瀏覽器提供的 API 來操縱網頁的 DOM 或是發起 HTTP 請求 他也是一個以 prototype (原型鍊)來實作物件導向的弱型別語言 而以 [Google v8](https://v8.dev/) 來實作的 [Node.js](https://nodejs.org/en) 也使得它可以脫離瀏覽器的環境來運作 [MDN JavaScript](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript) ```javascript // 選取一個 id 為 my-element 的元素,並將他的文字設為 hello const a = document.querySelector('#my-element') a.innerText = 'hello' ``` #### fetch https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API 最早的時候,瀏覽器要發送請求只能透過網址或是發送表單,所以每次更動頁面都必須重新載入 後來 Google 開始使用 [AJAX](https://developer.mozilla.org/zh-TW/docs/Web/Guide/AJAX),使得網頁可以透過 JavaScript 來發送請求,並以此來動態的改變網頁 fetch 為現今瀏覽器提供的 API,比起以往的 `XMLHttpRequest` 介面好用許多 ```javascript fetch('https://example.com',{ method:'POST', header:{ 'Content-Type':'application/json' }, body: JSON.stringify(myobject) }) ``` #### cookie cookie 常被用來存放一些資訊,例如 * Session * Token * 狀態 * 追蹤資訊 而前端可以使用 JavaScript 來設置 cookie,或是使用 devtool 的 application 頁面來設置 ```javascript document.cookie = "username=Asuna"; //or //Chrome api cookieStore.set('admin',true) ``` 後端要設置 cookie 則是透過 `Set-Cookie` 標頭 ``` HTTP/1.1 200 OK ... Set-Cookie: session=deadbeef; ... ``` 而瀏覽器發起請求時,便會將這些 cookie 帶入 `Cookie` 標頭裡 ``` GET / HTTP/1.1 ... Cookie: session=deadbeef; ... ``` cookie 同時也有不同的屬性,來決定瀏覽器要怎麼處理 cookie * HttpOnly 前端的 JavaScript 不能操作這個 cookie * Domain cookie 存放的網域 * Expire cookie 什麼時候過期 * Secure 此 cookie 只能在 https 下存放 [MDN Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) ### Backend 負責處理請求以及請求的資料,可以由幾乎所有程式語言來撰寫 現代常用的 HTTP Server 或是框架都有針對不同路徑執行不同函式的功能 * Nginx 現代主流的 Web Server * Apache 老牌的 Web Server * Flask Python 的後端框架 * Express Node.js 的後端框架 * PHP ~~世界上最好的語言~~ ## HTTP HTTP 請求是前後端溝通的手段 一個 HTTP 請求會分成三個部分 * request line 這會在請求的第一行,說明此請求的方法(method)、路徑(path)以及版本 * request header 請求的標頭,可包含許多訊息,包括 Cookie 或是使用者使用的客戶端 * request body 請求攜帶的資料,不一定需要 一個 HTTP 請求的範例長這樣 ``` GET / HTTP/1.1 Host: google.com User-Agent: curl/7.68.0 Accept: */* ``` request line 以及 header 的每一行會用 `\r\n` 來隔開 ### Request Line ``` GET / HTTP/1.1 ^ ^ ^ method path version ``` 一般來說請求方法只會用到 `GET` 跟 `POST` 分別代表獲取以及上傳的意思 其他還有較不常用的 `PUT`、`OPTION`、`HEAD` 等 這部分其實完全可以自定義,只要後端有對應的 route 即可 有些開發者會依照 REST 的設計方法讓每個 API 的 method 都是更為精確的 `PUT` 或是 `OPTION` 之類的 可參考 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods 請求路徑則是 URL 的一部分 但是還可以使用 `?` 來提供參數 `/foo/bar?dead=beef&id=123` 若是在請求路徑裡含有特殊字元(如 ascii 0x00~0x19 或是中文) 我們可以使用 url encoding,也就是以 hex 來表達該字元 `/%41%42%43` ### Request Header ``` Host: google.com User-Agent: curl/7.68.0 Accept: */* ``` HTTP 標頭會攜帶封包的資訊,像是我們常聽說的 Cookie 之類的 而因為 HTTP 是無狀態的 (Stateless),所以 header 所攜帶的訊息非常重要 ### HTTP Response ``` HTTP/1.1 200 OK Server: nginx/1.18.0 (Ubuntu) Date: Fri, 15 Sep 2023 02:34:04 GMT Content-Type: text/html; charset=utf-8 Content-Length: 22511 ``` response 跟 request 的格式差不多相同 不同的點在於第一行會改而顯示 HTTP 狀態碼 像是 200 就是 OK,而我們常見的 404 就是無此頁面的意思 同時 request 跟 response 所使用的 header 也不盡相同 [MDN HTTP Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) [MDN HTTP Status](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) ### Lab 使用 Curl 或是 BurpSuite 來觀察 HTTP 封包 `curl https://www.google.com -v` ## Rookie Vulnerable ### SQLI(SQL Injection) SQL 是非常常使用的資料庫語言,可說是現代資料庫的基石 他可以用來操作關聯式資料庫(RDBMS),也就是用表格型式來儲存資料的資料庫 這些表格被稱為 table 每一個欄位被稱為 column 而每一項資料被稱為 row |id|user |password| |--|------|-------| |1 |Heathcliff|047463c04d2c12909efbbc71fb170efd |2 |Kirito|8699314d319802ef792b7babac9da58a| ```sql select * from users where user = 'Kirito' and password = '8699314d319802ef792b7babac9da58a' -- ^ ^ ^ -- columns table condition ``` 在 condition 的部分我們通常會讓使用者來提供輸入 但若沒檢查用戶輸入會發生非常嚴重的後果 假如使用者在 user 欄位輸入 `Healthcliff' or '1'='1';--` 則查詢的語句就會變成 ```sql select * from users where user = 'Healthcliff' or '1'='1';--' and password = 'something' ``` #### Union base 但是上述語句只有在登入的情況才能使用 我們能否透過其他查詢語句來將整個資料庫 dump 下來? 這時候就可以用到 union 關鍵字 假如我們有下列的 table | id | book | author | rating | | --- | ----------------- |:---------------- | ------ | | 1 | Lord of the Rings | J. R. R. Tolkien | 5 | | 2 | Sword Art Online | Kawahara Reki | 3 | 而有一個 query 長這樣 ```sql select * from books where book = 'Lord of the Rings' ``` union 便可以用來查詢另一個 table,並且跟原本的結果合併 **要注意的是**透過 union 查詢的另一個 select 語句的 column 數必須與原本的一樣 若不足的可以補 null、字串或是數字 有些 DBMS 除了 column 數要相同外,還會要求資料型態相同,可以使用 null 就好 ```sql select * from books where book = 'Lord of the Rings' union select *,null from users; ``` #### Boolean base 更常的一些情況是 query 查詢的結果不會直接顯示在頁面上 但是仍然能透過其他資訊來判斷是否查詢成功,像是登入成功與否之類的 而這時我們便可以使用 SQLI 裡的 if else 並搭配二分搜來將要搜尋的東西一個字一個字的爆出來 ```sql -- i = 1 -- mid = (l+r)/2 -- 用{}包起來不是合法 sql 語句,這樣弄只是避免看起來太長 ... and if((select ascii(substring(password,{i},{i}))<={mid} from users where user='admin'),true,false);-- ``` #### Metadata table 每種 SQL 資料庫都會有專門的 table 去存放所有 table 以及 column 的名稱 若你不知道你要撈的目標表名,則需要先從這些 table 將目標表明撈出來 * sqlite_master SQLite * information_schema MySQL * pg_database pg_tables PostgreSQL #### How to prevent? 最佳解法就是使用 prepare statement 或是使用 ORM,來避免直接串接字串 自己去過濾關鍵字,可能會有漏網之魚,還不如用別人提供的 ```javascript db.get('SELECT * FROM Users WHERE username = ?', username) ``` ### XSS(Cross-Site Scripting) 前端使用 HTML、CSS 以及 JavaScript 來 render 頁面 但若直接把用戶的輸入不加以過濾便插入至頁面上,就會造成 XSS(Cross-Site Scripting) 雖然 XSS 的形式有分很多種,但最常見的成因只有兩個 * 前端的 JS 使用到 innerHTML 來植入用戶提供的內容 * 後端在 render 模板時沒有 escape 用戶提供的內容 而受到 XSS 攻擊的網站會使得攻擊者能獲得其他用戶的 Cookie,造成能獲得其他使用者的敏感資訊,或是成為管理員 而若受到 XSS 攻擊的是使用 Electron 的應用程式,則也有機會能造成 RCE 一些常見的 payload * `<img src=# onerror="alert(1)">` * `<svg/onload="alert(1)">` * `<button onclick="alert(1)">` #### CORS(Cross-Origin Resource Sharing) 瀏覽器的同源政策 (Same-Origin Policy) 會限制網頁只能去存取同個網頁的資源,除了路徑以外,協定(protocol)、網域(domain)以及埠口(port)都必須相同 而如果要去獲取別的網站的資源(api、CSS、JavaScript),瀏覽器提供一個叫做 CORS 的機制 本質上就是只要該網站的回應包含 CORS 標頭就允許存取 `Access-Control-Allow-Origin: *` [MDN CORS](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS) #### CSP #### How to prevent? 通常會將 HTML 轉譯成 [HTML Entity](https://developer.mozilla.org/en-US/docs/Glossary/Entity) 來將 HTML 轉成純字串顯示 不要隨意使用 innerHTML 若是要有多功能的文字編輯(如用戶發文可以附圖片、超連結等) 一定要使用如 [Dompurify](https://github.com/cure53/DOMPurify) 等過濾函式庫來處理用戶的輸入 若是有其他需求,如使用到 iframe 的 srcdoc 或是讓用戶可以上傳並檢視 SVG 等,也需要去使用 [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 做好防護 ### Miss Configuration #### Information Leak 有些檔案可能會帶有敏感資訊,同時網站開發者沒限制存取 * robots.txt * .git * .htaccess * .well-known * package.json ## Other Vulnerable ### Arbitrary Read/Write 有些網站可能會將使用者的輸入拼接到路徑之上,並且讀取該路徑的檔案 這時候便可以讀取諸如原始碼或是環境變數等檔案 ```py open(f'/tmp/userdir/{file}') # file = ../../etc/passwd open('/tmp/userdir/../../etc/passwd') ``` * /etc/passwd * /proc/self/cmdline * /proc/self/fd/[0-9] * /proc/self/environ * /etc/nginx/nginx.conf * /etc/apache2/httpd.conf * ... #### Local File Inclusion 在一些特殊的語言如 PHP,可以在執行時去動態 include 外部的腳本 這時若能改變所 include 的檔案,則就有辦法達成 RCE * [include](https://www.php.net/manual/en/function.include.php) * [require](https://www.php.net/manual/en/function.require.php) ### Template Injection ### SSRF ### Prototype Pollution ### Unsafe Deserialization # Docker 在打 Web 題的時候,出題者通常會提供 Dockerfile 來讓參賽者可以在自己的電腦把環境架起來 Docker 其實就是一種 KVM 的應用,可以透過設定檔來定義虛擬容器的內容 容器化的技術可以讓服務在更精簡的環境運行,同時擴展性以及開關速度都比以往的虛擬機器還要好 ![Container vs VM](https://www.docker.com/wp-content/uploads/2021/11/docker-containerized-and-vm-transparent-bg.png) Docker 的架構主要有三個 * Dockerfile 決定 Image 如何去構建 * Image 決定 Container 開啟時會長怎樣,可以直接從官方倉庫抓下來別人構建好的 * Container 運作時的實體,每個 container 都互相獨立 ## Install Docker Ubuntu 可以直接輸入 `sudo apt-get install docker` Windows 及 MacOS 則是下載 [Docker Desktop](https://www.docker.com/products/docker-desktop) MacOS 還可以使用 [OrbStack](https://orbstack.dev/) 作為替代方案 ## Dockerfile Docker 可以使用 Dockerfile 來做好一個虛擬容器的配置 包括安裝套件或是複製原始碼 同時他也是一層一層的結構,也就是說每個 Dockerfile 都會是基於另一個 Dockerfile 去做配置 ```dockerfile # 基於 node 20 alpine 的環境 FROM node:20-alpine # 將工作目錄設成容器裡的 /app WORKDIR /app # 將檔案及目錄複製過去 COPY package.json ./ COPY package-lock.json ./ COPY views ./views COPY public ./public COPY app.js ./ # 安裝套件 RUN npm install # 容器啟動時要使用的指令 CMD ["node", "app.js"] ``` 當寫好 Dockerfile 時,我們可以使用 `docker build -t .` 來將對應的 image 建構出來 而 Dockerfile 的內容則會在 build 時執行完畢 接著便能使用 `docker run` 來啟動容器 ```sh $ docker run -d --name web -p 8080:80 image # -d 背景執行 # -p port 轉發 # image 你的 image 的名稱 ``` ## Docker compose 如果每次重新啟動容器都要重打參數會很麻煩,雖然可以自行寫 shell script 來自動化 但是官方提供了 docker compose 來使用 yaml 設定檔一次管理多個容器 docker-compose.yml ```yaml # 版本 version: "3.7" services: minecraft: # 要使用的 image image: itzg/minecraft-server # 容器名稱 container_name: minecraft # 容器裡的環境變數 environment: EULA: "TRUE" TYPE: "FABRIC" ENABLE_COMMAND_BLOCK: "true" ONLINE_MODE: "false" DIFFICULTY: "hard" VERSION: "1.20" VIEW_DISTANCE: 14 TZ: "Asia/Taipei" # 使容器裡的目錄或檔案映射到 host 的目錄或是檔案,讓容器關閉後資料仍然能留存 volumes: - ./minecraft:/data # port 轉發 port: - "25565:25565" ``` 要啟動便在同一個目錄底下輸入 ```sh $ sudo docker compose up -d ``` 如果是舊版則是 ```sh $ sudo docker-compose up -d ```

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully