Transferencia de un archivo entre máquinas virtuales aisladas a través de canales laterales

Alguien en Internet está equivocado

Hace no más de cinco días, aparecieron noticias sobre Habré bajo el título "Se encontró la vulnerabilidad M1RACLES en Apple M1: es posible una rápida transferencia de datos ocultos entre aplicaciones ". En una frase, la esencia se formula de la siguiente manera: en el Apple M1 encontraron un registro que cualquiera puede leer y escribir desde el modo no privilegiado. Esto significa que se puede utilizar para intercambiar datos sin pasar por los mecanismos de comunicación entre procesos proporcionados por el sistema operativo. Sin embargo, el propio autor no considera que esta característica sea una vulnerabilidad significativa, como escribe en el comentario explicativo:





Entonces, ¿cuál es el punto de este sitio web?

Burlarse de lo ridículos que se han vuelto los informes de vulnerabilidades de clickbait infosec últimamente. El hecho de que tenga un sitio web llamativo o sea noticia no significa que deba preocuparse.



Si has leído todo el camino hasta aquí, ¡enhorabuena! Eres una de las pocas personas que no solo retuitea basándose en el título de la página :-)



Pero, ¿cómo se supone que los periodistas deben saber qué errores son malos y cuáles no?

Hablar con las personas. En particular, hable con personas que no sean las personas que descubrieron el error. Este último puede o no ser honesto sobre el impacto real.



Si escuchas las palabras "canal encubierto" ... probablemente esté sobrevalorado. La mayoría de estos provienen de fábricas de papel que reciclan sin cesar el mismo concepto con un impacto de seguridad práctico aproximadamente nulo. Los títulos suelen ser clickbait y, a veces, francamente engañosos.





: - ? @SergeyMax @wataru , , , . @creker @adjachenko, , M1RACLES.





. PoC ~500 C++, . , , M1RACLES .





, .





: , , , . , MMU, , , .





M1RACLES, Apple . , . ; PoC, , , , RAM ( ), ..





, . - , ; ( ) . .





Por Ivajkin Timofej (traducido del wiki en inglés) - en.wikipedia.org, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=15444663
: Ivajkin Timofej (translated from the english wiki) - en.wikipedia.org, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=15444663

, :





void drivePHY(const bool level, const std::chrono::nanoseconds duration)
{
    static auto deadline = std::chrono::steady_clock::now();
    deadline += duration;  //        
    if (level)  //     
    {
        std::atomic<bool> finish = false;
        const auto loop = [&finish]() {
            while (!finish) { }
        };
        static const auto thread_count = std::max<unsigned>(1, std::thread::hardware_concurrency());
        std::vector<std::thread> pool;
        for (auto i = 0U; i < (thread_count - 1); i++)
        {
            pool.emplace_back(loop);
        }
        while (std::chrono::steady_clock::now() < deadline) { }
        finish = true;
        for (auto& t : pool)
        {
            t.join();
        }
    }
    else  //   --  
    {
        std::this_thread::sleep_for(deadline - std::chrono::steady_clock::now());
    }
}
      
      



, . , API CPU core affinity (macOS, , ), , . , API affinity , , :





#include <pthread.h>  // -lpthread

cpu_set_t cpuset{};
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
      
      



, :





constexpr std::chrono::nanoseconds ChipPeriod{16'000'000};  // . 1...100 
std::bitset<CDMACodeLength> CDMACode("...");                //  

void emitBit(const bool value)
{
    for (auto i = 0U; i < CDMACode.size(); i++)
    {
        const bool bit = value ^ !CDMACode[i];
        drivePHY(bit, ChipPeriod);
    }
}
      
      



( ) , , ( ):





void emitByte(const std::uint8_t data)
{
    emitBit(1);   //  
    auto i = 8U;  //    
    while (i --> 0)
    {
        emitBit((static_cast<std::uintmax_t>(data) & (1ULL << i)) != 0U);
    }
}

void emitFrameDelimiter()
{
    for (auto i = 0U; i < 20; i++)  //   9  
    {
        emitBit(0);
    }
}

      
      



CRC-16-CCITT:





void emitPacket(const std::vector<std::uint8_t>& data)
{
    emitFrameDelimiter();
    std::uint16_t crc = CRCInitial;
    for (auto v : data)
    {
        emitByte(v);
        crc = crcAdd(crc, v);
    }
    emitByte(static_cast<std::uint8_t>(crc >> 8U));
    emitByte(static_cast<std::uint8_t>(crc >> 0U));
    emitFrameDelimiter();
}
      
      



- , — .





, - . , . , ( ) :





bool readPHY()
{
    static auto deadline = std::chrono::steady_clock::now();  // .    
    deadline += SampleDuration;
    const auto started_at = std::chrono::steady_clock::now();

    std::vector<std::int64_t> counters;
    const auto loop = [&counters](std::uint32_t index) {
        auto& cnt = counters.at(index);
        while (std::chrono::steady_clock::now() < deadline)
        {
            cnt++;
        }
    };
    static const auto thread_count = std::max<unsigned>(1, std::thread::hardware_concurrency());
    if (thread_count > 1)
    {
        counters.resize(thread_count, 0);
        std::vector<std::thread> pool;
        for (auto i = 0U; i < thread_count; i++)
        {
            pool.emplace_back(loop, i);
        }
        for (auto& t : pool)
        {
            t.join();
        }
    }
    else
    {
        counters.push_back(0);
        loop(0);
    }

    const double elapsed_ns =
        std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - started_at).count();
    const double rate = double(std::accumulate(std::begin(counters), std::end(counters), 0)) / elapsed_ns;

    static double rate_average = rate;
    rate_average += (rate - rate_average) / PHYAveragingFactor;

    return rate < rate_average;  //      
}
      
      



, , , , . (.., ) , .





, . , . () , .





CDMA , :





Diagrama esquemático de la ruta de recepción.

. , . ; , , . , .





: , . , .





. . , ; , , .





, , GPS . , GPS ( Qx , ):





Diagrama de los principios de los sistemas de navegación integrados GNSS, inercial y multisensor, PD Groves, 2ª ed.
"Principles of GNSS, inertial, and multisensor integrated navigation systems", P. D. Groves, 2- .

. , , , .





, , , , , . - LDPC , .





, , . , :





https://github.com/pavel-kirienko/cpu-load-side-channel





:





, ffmpeg ( 4K ), ~30 , . () , .





: , 16 , 1023 , .., 16 , 0.06 . CRC . - ?





M1RACLES ( 8 Mb/s), . - ( 0 b/s), .





, . , . , , ChipPeriod



CDMACodeLength



PoC ( Manjaro 5.4 Intel Core i7 990X @ 4 GHz).





( ) -, . , , , ; , . .





(airgapped networks), Mordechai Guri . , , , , , .





/r/netsec , Hector Martin, M1RACLES. : ; M1RACLES , , . , -, ; , "" .





, , . Hector Martin , , , . , , , M1RACLES , - . :





We already know all systems are vulnerable to certain side-channel attacks. In particular, all systems with shared resources have side channels. Those side channels are easy to turn into covert channels, as you did. The bandwidth, and the severity, is proportional to how closely coupled the security domains are (as you found out, where the VM boundary reduces your performance). As the severity gets higher, you go from 1 bit per second covert channels, to megabytes per second covert channels, to actually being able to steal data from noncooperative entities (actual dangerous side channels) under increasingly less demanding circumstances.





[...]





So M1RACLES is interesting because it is not a side channel - so it poses no danger of leaking data from unwitting processes - but it is a highly efficient covert channel, which does matter under a very small but not nonexistent set of attack scenarios. Does it add covert channel capability where none existed prior? No. But that doesn't mean it's not a vulnerability; as I said, we don't qualify systems on some kind of absolute "vulnerable/not vulnerable" scale. We look at individual issues and then figure out how they affect the overall security of the system under certain attack scenarios.





Mordechai Guri, . , , . , .





:





  • .





  • , .





  • M1RACLES , .








All Articles