Описание
Библиотека, загруженная от внешне управляемого пути, ищет библиотеки, загруженные от фиксированных или управляемых путей. Если непреднамеренные агенты могут управлять одним или несколькими местоположениями на этом фиксированном пути, Средство поиска Ошибки повышает дефект.
Риск
Если атакующий знает или управляет путем, который вы используете, чтобы загрузить библиотеку, атакующий может измениться:
Библиотека, что загрузки программы, заменяя намеченную библиотеку и команды.
Среда, в которой библиотека выполняется, давая непреднамеренные полномочия и возможности атакующему.
Фиксация
Когда возможно, используйте трудно закодированные или полностью определенные пути, чтобы загрузить библиотеки. Возможно, что трудно закодированные пути не работают над другими системами. Используйте централизованное местоположение для трудно закодированных путей, так, чтобы можно было легко изменить путь в рамках исходного кода.
Другое решение состоит в том, чтобы использовать функции, которые требуют явных путей. Например, 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;
}