-------------------------------- Anti-Sandbox using Trigonometry --------------------------------


    This article presents an anti-sandbox technique used by the LummaC2 v4.0 malware, which employs trigonometry to detect mouse movements consistent with
    human behavior, thus avoiding execution in sandbox environments.

    The technique involves capturing the mouse position at regular intervals and calculating the angles between vectors formed by these positions. If the calculated
    angles are smaller than a predefined threshold, the movement is considered "human," and the malware continues execution. Otherwise, the malware restarts the verification.

    Initially, the malware checks if any cursor movement occurred. The malware captures the initial mouse position, and after a 300-millisecond interval, captures the 
    new position. If the new position differs from the initial one, it indicates that mouse movement occurred. If no movement is detected, the process restarts.
    
        POINT initialPos;
        GetCursorPos(&initialPos);
    
        Sleep(300);
    
        POINT newPos;
        GetCursorPos(&newPos);
    
        if (newPos.x != initialPos.x || newPos.y != initialPos.y) {
            // Movement detected
        } else {
            // No movement
        }
    
    When movement is detected, the malware captures five consecutive mouse positions with 50-millisecond intervals between each capture. These positions will be used for vector analysis.
    
        for (int i = 0; i < 5; i++) {
            GetCursorPos(&pos[i]);
            Sleep(50);
        }
    
    Before proceeding to the trigonometric calculations, the malware ensures that all captured positions differ from one another. 
    This avoids small or simulated movements (such as constant and linear movements) being considered "human."
    
        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;
        }
    
    If all positions are the same, the malware restarts the process, waiting for new movements.

    Once the difference between positions is confirmed, the malware treats each movement between two consecutive positions as a vector in Euclidean space. 
    Thus, mouse movements form four vectors: P01, P12, P23, and P34, where P01 is the vector between P0 and P1, and so on.

    The malware then calculates the magnitude of each vector, which will be used to calculate the angle between vectors. 
    For this, the malware uses the Euclidean distance between two points (P1 and P2), which is given by the formula:

    

    In the code:
    
        double euclideanDistance(POINT p1, POINT p2) {
            return std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2));
        }
    
    Now with the magnitude of the vectors, the malware calculates the dot product between two vectors A and B, which is given by the formula:

    

    It then calculates the angle θ between vectors A and B, which is given by the formula:
    
    

    In the code, this is implemented as follows:
    
        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));
    
            // Converting from radians to degrees
            return angleRad * (180.0 / M_PI);
        }
    
    This calculation is repeated for each pair of consecutive vectors: P01 -> P12, P12 -> P23, and P23 -> P34.

    Once the angles between the vectors are obtained, the malware checks if all the angles are smaller than a predefined threshold of 45 degrees.
    If they are, the movement is considered "human," and the malware continues execution. Otherwise, the malware restarts the verification.
    
        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] Human movement detected." << std::endl;
        } else {
            std::cout << "[INFO] Human movement not detected. Restarting." << std::endl;
        }
    
    Final code:
    
        #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;
        }         
        
    
    References:
        - https://www.cuemath.com/geometry/angle-between-vectors/
        - https://outpost24.com/blog/lummac2-anti-sandbox-technique-trigonometry-human-detection/