CERT C: Rec. WIN00-C

Будьте конкретны при динамичной загрузке библиотек

Описание

Управляйте определением

Будьте конкретны при динамичной загрузке библиотек. [1]

Примеры

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

Описание

Загрузкой библиотеки от относительного пути может управлять внешний агент, обнаруживает библиотеку, загружающую стандартные программы, которые загружают внешнюю библиотеку. Если вы загружаете библиотеку с помощью относительного пути или никакого пути, Средство поиска Ошибки отмечает стандартную программу загрузки как дефект.

Риск

При помощи относительного пути или никакого пути, чтобы загрузить внешнюю библиотеку, ваша программа использует небезопасный поисковый процесс, чтобы найти библиотеку. Атакующий может управлять поисковым процессом и заменить намеченную библиотеку на собственную библиотеку.

Фиксация

Когда вы загружаете внешнюю библиотеку, задаете полный путь.

Пример - открытая библиотека с именем библиотеки

#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

void relative_path()
{
    dlopen("liberty.dll",RTLD_LAZY);
}

В этом примере, dlopen открывает liberty библиотека путем вызова только имени библиотеки. Однако этот вызов библиотеки использует относительный путь, чтобы найти библиотеку, которая небезопасна.

Коррекция — использует полный путь для библиотеки

Одна возможная коррекция должна использовать полный путь для библиотеки, когда вы загружаете его в свою программу.

#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>

void relative_path()
{
    dlopen("/home/my_libs/library/liberty.dll",RTLD_LAZY);
}

Описание

Библиотека, загруженная от внешне управляемого пути, ищет библиотеки, загруженные от фиксированных или управляемых путей. Если непреднамеренные агенты могут управлять одним или несколькими местоположениями на этом фиксированном пути, Средство поиска Ошибки повышает дефект.

Риск

Если атакующий знает или управляет путем, который вы используете, чтобы загрузить библиотеку, атакующий может измениться:

  • Библиотека, что загрузки программы, заменяя намеченную библиотеку и команды.

  • Среда, в которой библиотека выполняется, давая непреднамеренные полномочия и возможности атакующему.

Фиксация

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

Другое решение состоит в том, чтобы использовать функции, которые требуют явных путей. Например, system() не требует полного пути, потому что он может использовать PATH переменная окружения. Однако execl() и execv() действительно потребуйте полного пути.

Пример - вызывает пользовательскую библиотеку

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <limits.h>

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

void* taintedpathlib() {
    void* libhandle = NULL;
    char lib[SIZE128] = "";
    char* userpath = getenv("LD_LIBRARY_PATH");
    strncpy(lib, userpath, SIZE128);
    strcat(lib, "/libX.so");
    libhandle = dlopen(lib, 0x00001);
    return libhandle;
}

Этот пример загружает библиотеку libX.so от переменной окружения LD_LIBRARY_PATH. Атакующий может изменить путь к библиотеке в этой переменной окружения. Фактическая библиотека, которую вы загружаете, могла быть различной библиотекой от той, которую вы предназначаете.

Коррекция — изменение и путь к проверке

Одна возможная коррекция должна измениться, как вы получаете путь к библиотеке и проверяете путь библиотеки прежде, чем открыть библиотеку. Этот пример получает путь как входной параметр. Затем путь проверяется, чтобы убедиться, что библиотека не находится под /usr/.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
#include <limits.h>

enum {
    SIZE10  =  10,
    SIZE100 = 100,
    SIZE128 = 128
};

/* Function to sanitize a string */
int sanitize_str(char* s, size_t n) {
    /* strlen is used here as a kind of firewall for tainted string errors */
    int res = (strlen(s) > 0 && strlen(s) < n);
    return res;
}
void* taintedpathlib(char* userpath) {
    void* libhandle = NULL;
    if (sanitize_str(userpath, SIZE128)) {
        char lib[SIZE128] = "";

        if (strncmp(userpath, "/usr", 4)!=0) {
            strncpy(lib, userpath, SIZE128);
            strcat(lib, "/libX.so");
            libhandle = dlopen(lib, RTLD_LAZY);    
        }
    }
    return libhandle;
}

Проверяйте информацию

Группа: Rec. 51. Microsoft Windows (WIN)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ-МЕЛЛОН И/ИЛИ ЕГО ИНСТИТУТА ПРОГРАММНОЙ ИНЖЕНЕРИИ СОДЕРЖАЛ, ЗДЕСЬ ПРЕДОСТАВЛЯЕТСЯ НА ОСНОВЕ "ASIS". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.