Путь к домашней директории для сохранения файлов (C++)
Модератор: Модераторы разделов
-
Nauro
- Сообщения: 8
- ОС: Xubuntu 8.10
Путь к домашней директории для сохранения файлов
Возникла такая вот заковыка: надо сделать сохранение конфига в файлике, чтобы при следующем запуске подцепить его. Подумал, что лучше всего сохранить куда-то типа /home/nauro/.abc/ но вот он зависит от имени юзера, т.е. на другой системе работать не будет... Можно ли путь к домашнему каталогу как-то определить?
-
CycaHuH
- Сообщения: 85
- ОС: FreeBSD; Archlinux; Calculate
Re: Путь к домашней директории для сохранения файлов
getenv("HOME");
-
kosmonaFFFt
- Сообщения: 183
- ОС: win 7, Kubuntu 10.10
Re: Путь к домашней директории для сохранения файлов
Или юзать тильду, теоретически должно работать...
Т. е. ~ = /home/username для текущего юзера.
Т. е. ~ = /home/username для текущего юзера.
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
kosmonaFFFt писал(а): ↑14.01.2009 19:59Или юзать тильду, теоретически должно работать...
Т. е. ~ = /home/username для текущего юзера.
getenv() надежней
собственно по сабжу:
Код: Выделить всё
#include<iostream>
#include <cstdio>
#include <string.h>
using namespace std;
int main(int argc ,char *argv[]){
char text[128];
FILE *name;
name = popen("whoami", "r");
fgets(text, 128, name);
pclose(name);
char home_dir[255] = {'/', 'h', 'o', 'm', 'e', '/', 0 };
strcpy(home_dir+6,text);
cout << "Home directory is: " << home_dir << endl;
return 0;
}-
Cra3y
- Сообщения: 80
- ОС: Debian
Re: Путь к домашней директории для сохранения файлов
Код: Выделить всё
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static inline char* get_home() {
return getpwuid(getuid())->pw_dir;
}
int main(int argc, char** argv) {
puts(get_home());
return 0;
}HP G62 (AMD Phenom II x3 1.8GHz 4GB DDR3 Ram) / Debian 8 amd64
-
Nauro
- Сообщения: 8
- ОС: Xubuntu 8.10
Re: Путь к домашней директории для сохранения файлов
Спасибо за помощь. Разобрался.
P.S. Тильда была первым интуитивным рывком, но, увы, неудачным.
P.S. Тильда была первым интуитивным рывком, но, увы, неудачным.
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Путь к домашней директории для сохранения файлов
Не должно. Тильда раскрывается шеллом, а не libc или ядром. getenv("HOME") -- правильный вариант, потому что общепринятый.
Мои розовые очки
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
watashiwa_daredeska писал(а): ↑16.01.2009 20:26Не должно. Тильда раскрывается шеллом, а не libc или ядром. getenv("HOME") -- правильный вариант, потому что общепринятый.
а еще кроме того, что он общепринятый - он еще и теоретически уязвимый.
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
нет времени и желания что-то расписывать. почитайте лучше книгу Джон Эриксон "Хакинг. Искусство эксплойта" там для начинающих, все очень подробно расписано (и про переполнение в куче и bss, форматные строки). читайте.
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Путь к домашней директории для сохранения файлов
Где в getenv("HOME") может произойти переполнение кучи или bss, где здесь форматные строки? Начинающим рекомендуется, в первую очередь, думать, что и каким местом куда применимо. Вот это чудовище куда страшнее getenv во всех смыслах, а этот вариант ведет себя не так, как принято в большинстве случаев, нарушая Rule of Least Surprise, хотя и имеет право на жизнь в некоторых случаях, но не для поиска конфигов.
Мои розовые очки
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
watashiwa_daredeska писал(а): ↑21.01.2009 01:42Где в getenv("HOME") может произойти переполнение кучи или bss, где здесь форматные строки? Начинающим рекомендуется, в первую очередь, думать, что и каким местом куда применимо. Вот это чудовище куда страшнее getenv во всех смыслах, а этот вариант ведет себя не так, как принято в большинстве случаев, нарушая Rule of Least Surprise, хотя и имеет право на жизнь в некоторых случаях, но не для поиска конфигов.
почему вы все так усложняете? ваш пост похож на параноидальный бред.
во-первых, я сказал теоретически уязвимый, во-вторых, я не говорил что в этом коде присутствуют такие уязвимости как переполнение, доступ к поизвольному адресу памяти, в-третьих, ваш интерес к уязвимостям вызвал с моей стороны вполне объяснимое желание помочь, а именно указать книгу, в которой вы можете почерпнуть все необходимые знания; в-четвертых, хотите уязвимость? получайте:
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
int main ()
{
char home_path[255];
strcpy(home_path, getenv("PATH"));
return 0;
}К чему все это? А к тому, что доверять внешним данным нельзя, в данном случае - необходимо проверить возвращенную функцией строку на правильность.
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Путь к домашней директории для сохранения файлов
Я как раз не боюсь getenv, ибо знаю чем он грозит, а чем нет. А вот "параноидальный бред" по поводу уязвимостей несу тут совсем не я
Хорошо: Где в getenv("HOME") может теоретически произойти переполнение кучи или bss, где здесь теоретически форматные строки?
Меня интересовали уязвимости конкретно getenv("HOME"), а не вообще. Вообще-то, я более-менее знаком с различными видами уязвимостей, как разработчик конечно, а не как эксперт по безопасности. Так что можете общаться на нормальном уровне, не подразумевая в собеседнике девятиклассника
Ну и причем тут getenv? Скажите еще, что параметры командной строки теоретически уязвимы. По той же самой причине. И строки char* вообще.
Мои розовые очки
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
по-моему, мы друг друга совсем не поняли - я не против использования getenv, а за то чтобы его использовали с умом! грош цена программе, не проверяющей входные данные. давайте проведем "мысленный" эксперимент: представим что есть некая гипотетическая программа, которая должна принять принять от пользователя некоторые данные(в нашем случае значение переменной среды окружения $HOME) и потом соответствующим образом обработать.
пусть будет сильно упрощенный код, который выполняет данные действия:
скомпилируем программу и запустим ее:
хорошо, похоже все и в правду работает... Поробуем "позапускать" ее еще:
А вот это уже интересно - контроля со стороны ОС или libc за значением $HOME нет. хорошо... идем дальше:
Как видите, код уязвим. К счастью, в моем случае (я имею в виду мой ПК) все максимум может ограничится ошибкой сегментирования, т.к. начальный адрес стека и кучи у меня выбираются случайно. В случае, отсутствия подобной рандомизации эксплуатировать уязвимость можно более эффективно - передать шелл-код, и не дай бог программа работает с правами рута.
думаю на этот раз мы разобрались и недопониманий никаких больше не будет =)
P.S. если спросите, почему я постоянно копирую в char[], то ответ предельно прост - адрес, возвращаемый функцией getenv() для каждой определенной переменной всегда одинаков, т.е. возможна модификация значения $HOME, чтобы избежать даже "случайной" модификации лучше скопировать в буффер. вот пример доказывающий это:
вывод:
P.P.S никакой паранои =)
пусть будет сильно упрощенный код, который выполняет данные действия:
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char *home_dir = getenv("HOME");
char home[255];
strcpy(home, home_dir);
printf("%s\n", home_dir);
return 0;
}
}скомпилируем программу и запустим ее:
negativ@negativ-pc
negativ@negativ-pc:~$ g++ -O2 -o prog main.cpp
negativ@negativ-pc:~$ ./prog
/home/negativ
хорошо, похоже все и в правду работает... Поробуем "позапускать" ее еще:
negativ@negativ-pc
negativ@negativ-pc:~$ HOME=/ ./prog
/
negativ@negativ-pc:~$ HOME=blah-blah ./prog
blah-blah
А вот это уже интересно - контроля со стороны ОС или libc за значением $HOME нет. хорошо... идем дальше:
negativ@negativ-pc
negativ@negativ-pc:~$ HOME=/ ./prog
negativ@negativ-pc:~$ HOME=`perl -e 'print "\x41" x 320;'` ./prog
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAA
Ошибка сегментирования
Как видите, код уязвим. К счастью, в моем случае (я имею в виду мой ПК) все максимум может ограничится ошибкой сегментирования, т.к. начальный адрес стека и кучи у меня выбираются случайно. В случае, отсутствия подобной рандомизации эксплуатировать уязвимость можно более эффективно - передать шелл-код, и не дай бог программа работает с правами рута.
думаю на этот раз мы разобрались и недопониманий никаких больше не будет =)
P.S. если спросите, почему я постоянно копирую в char[], то ответ предельно прост - адрес, возвращаемый функцией getenv() для каждой определенной переменной всегда одинаков, т.е. возможна модификация значения $HOME, чтобы избежать даже "случайной" модификации лучше скопировать в буффер. вот пример доказывающий это:
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char *home_dir = getenv("HOME");
char home[255];
strcpy(home, home_dir);
printf("%s\n", home_dir);
home_dir[0] = 'B';
home_dir = (char*)0x00;
home_dir = getenv("HOME");
strcpy(home, home_dir);
printf("%s\n", home);
return 0;
}вывод:
negativ@negativ-pc
negativ@negativ-pc:~$ !HO
HOME=`perl -e 'print "\x41" x 320;'` ./prog
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
Ошибка сегментирования
P.P.S никакой паранои =)
-
watashiwa_daredeska
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Путь к домашней директории для сохранения файлов
по-моему, мы друг друга совсем не поняли - я не против использования getenvаргументов командной строки, а за то чтобы их использовали с умом! (и далее по тексту с заменой s/getenv("HOME")/argv[1]/)
Вопросы:
- Назовите что-нибудь, что можно использовать без ума.

- Кто научил вас матерному слову strcpy?
- Почему наличие матерного strcpy в программе влияет на уязвимость getenv?
- Почему наличие матерного strcpy в программе не влияет на уязвимость прочих char*?
- При чем тут вообще getenv?
Мои розовые очки
-
RasenHerz
- Сообщения: 1341
- ОС: Arch Linux amd64
Re: Путь к домашней директории для сохранения файлов
Ответы:
- Много чего, но пользы от этого...
- Для меня это довольно удобная вещь когда мне надо к в одну строку добавить другую:
использовать здесь, к примеру, тот же memcpy(ну или strnсpy) я считаю не удобным. Есть варианты удобнее?
- Влияет так же как фаза луны влияет на то, соберется ли моя программа =)
- Влияет! Если при работе с памятью не знать границ, в прямом смысле этого слова, будет очень худо.
- Я сделал замечание, что getenv() без должного внимания может послужить дырой в безопасности программы. К самой реализации функции претензий у меня нет, а вот к ее неаккуратному использованию - определенно есть. Уж извините, но на мой взгляд, самой большой опасностью для безопасности программы являются пользовательские данные. И как заметил один мой знакомый, программа требующая интерактивности уязвима всегда =)
- Много чего, но пользы от этого...
- Для меня это довольно удобная вещь когда мне надо к в одну строку добавить другую:
Код: Выделить всё
char usr_str[RESP_MLEN] = {'U', 'S', 'E', 'R', ' ', 0};
/* ......................................... */
strcpy(usr_str+5, usr); // usr - проверенная строкаиспользовать здесь, к примеру, тот же memcpy(ну или strnсpy) я считаю не удобным. Есть варианты удобнее?
- Влияет так же как фаза луны влияет на то, соберется ли моя программа =)
- Влияет! Если при работе с памятью не знать границ, в прямом смысле этого слова, будет очень худо.
- Я сделал замечание, что getenv() без должного внимания может послужить дырой в безопасности программы. К самой реализации функции претензий у меня нет, а вот к ее неаккуратному использованию - определенно есть. Уж извините, но на мой взгляд, самой большой опасностью для безопасности программы являются пользовательские данные. И как заметил один мой знакомый, программа требующая интерактивности уязвима всегда =)