-------------------------------- Anti-Sandbox utilizando Trigonometria --------------------------------


    Este artigo apresenta uma técnica de anti-sandbox utilizada pelo malware LummaC2 v4.0, que utiliza trigonometria para detectar movimentos de mouse consistentes com 
    comportamento humano, evitando assim a execução em ambientes de sandbox.


    A técnica consiste em capturar a posição do mouse em intervalos regulares e calcular os ângulos entre vetores formados por essas posições. Se os ângulos calculados 
    forem menores que um limite pré-definido, o movimento é considerado como "humano", e o malware continua a execução. Caso contrário, o malware reinicia a verificação.

    Inicialmente, o malware verifica se houve algum movimento do cursor. O malware captura a posição inicial do mouse e, após um intervalo de 300 milissegundos, captura a 
    nova posição. Se a nova posição for diferente da inicial, isso indica que houve um movimento do mouse. Caso não haja movimento, o processo é reiniciado.
    
        POINT initialPos;
        GetCursorPos(&initialPos);
    
        Sleep(300);
    
        POINT newPos;
        GetCursorPos(&newPos);
    
        if (newPos.x != initialPos.x || newPos.y != initialPos.y) {
            // Movimento detectado
        } else {
            // Sem movimento
        }
    
    Quando o movimento é detectado, o malware captura cinco posições consecutivas do cursor com intervalos de 50 milissegundos entre cada captura. Essas posições serão utilizadas para análise vetorial.
    
        for (int i = 0; i < 5; i++) {
            GetCursorPos(&pos[i]);
            Sleep(50);
        }
    
    Antes de prosseguir para os calculos trigonometricos, o malware garante que todas as posicoes capturadas sejam diferentes umas das outras. Isso evita que pequenos
    movimentos ou movimentações simuladas (como movimentos constantes e lineares) sejam considerados como "humanos".
    
        bool different = false;
        for (int i = 1; i < 5; i++) {
            if (pos[i].x != pos[i - 1].x || pos[i].y != pos[i - 1].y) {
                different = true;
                break;
            }
        }
    
        if (!different) {
            continue;
        }
    
    Caso todas as posicoes sejam iguais, o malware reinicia o processo, aguardando novos movimentos.

    Uma vez confirmada a diferença entre as posicoes, o malware trata cada movimento entre duas posições consecutivas como um vetor no espaço euclidiano. 
    Assim, os movimentos do mouse formam quatro vetores: P01, P12, P23 e P34, onde P01 é o vetor entre P0 e P1 e assim por diante.

    Em seguida, o malware calcula a magnitude de cada vetor, que será utilizada para calcular o ângulo entre os vetores. 
    Para isso, o malware utiliza a distancia euclidiana entre dois pontos (P1 e P2), que é dada pela formula:

    

    No código:
    
        double euclideanDistance(POINT p1, POINT p2) {
            return std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
        }
    
    Agora com a magnitude dos vetores, o malware calcula o produto escalar entre dois vetores A e B, que é dado pela formula:

    

    E em seguida, calcula o ângulo θ entre os vetores A e B, que é dado pela formula:
    
    

    No código, isso é implementado da seguinte forma:
    
        double angleBetweenVectors(POINT p1, POINT p2, POINT p3) {
            double mag1 = euclideanDistance(p1, p2);
            double mag2 = euclideanDistance(p2, p3);
    
            double dotProduct = (p2.x - p1.x) * (p3.x - p2.x) + (p2.y - p1.y) * (p3.y - p2.y);
            double angleRad = std::acos(dotProduct / (mag1 * mag2));
    
            // Convertendo de radianos para graus
            return angleRad * (180.0 / M_PI);
        }
    
    Este cálculo é repetido para cada par de vetores consecutivos: P01 -> P12, P12 -> P23 e P23 -> P34.

    Assim que é obtido os ângulos entre os vetores, o malware verifica se todos os ângulos são menores que um limite pre-definido de 45 graus.
    Se forem, o movimento é considerado como "humano" e o malware continua a execução. Caso contrário, o malware reinicia a verificação.
    
        double angle1 = angleBetweenVectors(pos[0], pos[1], pos[2]);
        double angle2 = angleBetweenVectors(pos[1], pos[2], pos[3]);
        double angle3 = angleBetweenVectors(pos[2], pos[3], pos[4]);
    
        if (angle1 < 45.0 && angle2 < 45.0 && angle3 < 45.0) {
            std::cout << "[SUCCESS] Movimento humano detectado." << std::endl;
        } else {
            std::cout << "[INFO] Movimento humano não detectado. Reiniciando." << std::endl;
        }
    
    Codigo final:
    
        #include <iostream>
        #include <windows.h>
        #include <cmath>
        
        #define SLEEP_INTERVAL 50
        #define MOUSE_MOVE_CHECK 300
        #define ANGLE_THRESHOLD 45.0
        
        double euclideanDistance(POINT p1, POINT p2) {
            return std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
        }
        
        double angleBetweenVectors(POINT p1, POINT p2, POINT p3) {
            double mag1 = euclideanDistance(p1, p2);
            double mag2 = euclideanDistance(p2, p3);
        
            if (mag1 == 0 || mag2 == 0) {
                return NAN;
            }
        
            double dotProduct = (p2.x - p1.x) * (p3.x - p2.x) + (p2.y - p1.y) * (p3.y - p2.y);
            
            double angleRad = std::acos(dotProduct / (mag1 * mag2));
            return angleRad * (180.0 / M_PI);
        }
        
        int main() {
            POINT pos[5];
        
            while (true) {
                POINT initialPos;
                GetCursorPos(&initialPos);
        
                Sleep(MOUSE_MOVE_CHECK);
                POINT newPos;
                GetCursorPos(&newPos);
        
                if (newPos.x != initialPos.x || newPos.y != initialPos.y) {
                    std::cout << "[INFO] Mouse moved. Capturing positions." << std::endl;
                    
                    for (int i = 0; i < 5; i++) {
                        GetCursorPos(&pos[i]);
                        Sleep(SLEEP_INTERVAL);
                        std::cout << "\t\\_ Position " << i << ": (" << pos[i].x << ", " << pos[i].y << ")" << std::endl;
                    }
        
                    bool different = false;
                    for (int i = 1; i < 5; i++) {
                        if (pos[i].x != pos[i - 1].x || pos[i].y != pos[i - 1].y) {
                            different = true;
                            break;
                        }
                    }
        
                    if (!different) {
                        std::cout << "[INFO] All positions are the same. Restarting verification." << std::endl;
                        std::cout << std::endl;
                        continue;
                    }
        
                    double angle1 = angleBetweenVectors(pos[0], pos[1], pos[2]);
                    double angle2 = angleBetweenVectors(pos[1], pos[2], pos[3]);
                    double angle3 = angleBetweenVectors(pos[2], pos[3], pos[4]);
        
                    std::cout << std::endl;
        
                    std::cout << "[INFO] Angles calculated between consecutive vectors:" << std::endl;
                    std::cout << "\t\\_ Angle 1 (P0->P1->P2): " << angle1 << " degrees" << std::endl;
                    std::cout << "\t\\_ Angle 2 (P1->P2->P3): " << angle2 << " degrees" << std::endl;
                    std::cout << "\t\\_ Angle 3 (P2->P3->P4): " << angle3 << " degrees" << std::endl;
        
                    std::cout << std::endl;
        
                    if (angle1 < ANGLE_THRESHOLD && angle2 < ANGLE_THRESHOLD && angle3 < ANGLE_THRESHOLD) {
                        std::cout << "[SUCCESS] Human movement detected (all angles < " << ANGLE_THRESHOLD << " degrees)." << std::endl;
                        break;
                    } else {
                        std::cout << "[INFO] Human movement not detected. Restarting verification" << std::endl;
                        std::cout << std::endl;
                    }
                }
            }
        
            return 0;
        }         
        
    
    Referencias:
        - https://www.cuemath.com/geometry/angle-between-vectors/
        - https://outpost24.com/blog/lummac2-anti-sandbox-technique-trigonometry-human-detection/