exponenta event banner

Уязвимый генератор псевдослучайных чисел

Использование криптографически слабого генератора псевдослучайных чисел

Описание

Этот дефект возникает при использовании криптографически слабых подпрограмм генератора псевдослучайных чисел (PRNG).

Список криптографически слабых подпрограмм, отмеченных этим средством проверки, включает:

  • rand, random

  • drand48, lrand48, mrand48, erand48, nrand48, jrand48, и их _r эквиваленты, такие как drand48_r

  • RAND_pseudo_bytes

Риск

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

Зафиксировать

Используйте более криптографически звуковые генераторы случайных чисел, такие как CryptGenRandom (Windows), OpenSSL/RAND_bytes(Linux/UNIX).

Примеры

развернуть все

#include <stdio.h>
#include <stdlib.h>

volatile int rd = 1;
int main(int argc, char *argv[])
{   
    int j, r, nloops;
    struct random_data buf;
    int i = 0;
    
    nloops = rand();
    
    for (j = 0; j < nloops; j++) {
        if (random_r(&buf, &i))
            exit(1);
        printf("random_r: %ld\n", (long)i);
    }
    return 0;
}

В этом примере используется rand и random_r для генерации случайных чисел. Если вы используете эти функции в целях безопасности, эти PRNG могут быть источником вредоносных атак.

Коррекция - использование более сильного PRNG

Одной из возможных корректировок является замена уязвимого PRNG более сильным генератором случайных чисел.

#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>

volatile int rd = 1;
int main(int argc, char* argv[])
{   
    int j, r, nloops;
    unsigned char buf;
    unsigned int seed;
    int i = 0;
    
    if (argc != 3) 
    {
        fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    seed = atoi(argv[1]);
    nloops = atoi(argv[2]);
    
    for (j = 0; j < nloops; j++) {
        if (RAND_bytes(&buf, i) != 1)
            exit(1);
        printf("RAND_bytes: %u\n", (unsigned)buf);
    }
    return 0;
}

Информация о результатах

Группа: Безопасность
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: VULNERABLE_PRNG
Воздействие: среднее
CWE ID: 330, 338
Представлен в R2015b