Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Жёсткие требования к приложению, Реализация 
:(
    Опции темы
CPlusPlusFAN
Дата 23.8.2008, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 1.11.2005
Где: Воронеж

Репутация: нет
Всего: нет



Здравствуйте. Какое-то приложение (test.exe к примеру), запускается из моего приложения. Это test.exe находится в специально отведённой для него директории. Предполагается, что оно что-то читает из файла a.txt и записывает что-то в b.txt, находящиеся в одной директории с test.exe. Запускаемое приложение должно выполнять только эти действия. Как мне для него выполнить следующие требования:

1) читать только из a.txt
2) записывать только в b.txt (неважно, существовал ли он до этого или нет)
3) запретить создавать, менять, удалять какие-либо другие файлы, кроме 2-х вышеперечисленных
3) исключить все лишние телодвижения test.exe типа system("cd .."), system("rm *").

Подскажите, как это можно реализовать для запускаемого придожения. Можно ли это сделать средствами C++ или придётся прибегнуть к шеллу?
PM MAIL ICQ Jabber   Вверх
Sartorius
Дата 23.8.2008, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1568
Регистрация: 18.7.2006
Где: Ivory tower

Репутация: нет
Всего: 37



Придется ИМХО отслеживать события в файловой системе и если что убивать порожденный процесс
http://www-128.ibm.com/developerworks/linu.../l-inotify.html
PM MAIL ICQ   Вверх
andrew_121
Дата 23.8.2008, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



CPlusPlusFAN, Если у тебя есть сорцы этого test.exe то можешь их пригрутить к своему С++ коду. И никаких шеллов!
Странно. Рубрика про Линукс, а у тебя exe-шки smile 


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
W4FhLF
Дата 23.8.2008, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: нет
Всего: 121



Если приложение не очень большое, то лично я бы продизасмил его, нашёл все места, где происходит обращение к файлам и посмотрел бы уже на месте. Думаю, это бы заняло меньше времени и сил, нежели написание монитора(хотя насчёт линя могу ошибаться). 


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
MAKCim
Дата 23.8.2008, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



W4FhLF, 
монитор пишется легко
ptrace() + PTRACE_SYSCALL
после остановки дочернего процесса смотрим EAX
через __NR_<имя системного сервиса> проверяем значение EAX
для
Цитата(CPlusPlusFAN @  23.8.2008,  14:18 Найти цитируемый пост)
3) запретить создавать, менять, удалять какие-либо другие файлы, кроме 2-х вышеперечисленных

__NR_open, __NR_write, __NR_unlink
для
Цитата(CPlusPlusFAN @  23.8.2008,  14:18 Найти цитируемый пост)
3) исключить все лишние телодвижения test.exe типа system("cd .."), system("rm *").

__NR_clone, __NR_fork, __NR_execve


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


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
kamre
Дата 23.8.2008, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 24.3.2006

Репутация: 1
Всего: 13



Цитата

Как мне для него выполнить следующие требования:

1) читать только из a.txt
2) записывать только в b.txt (неважно, существовал ли он до этого или нет)
3) запретить создавать, менять, удалять какие-либо другие файлы, кроме 2-х вышеперечисленных
3) исключить все лишние телодвижения test.exe типа system("cd .."), system("rm *").


По описанию чем-то похоже на AppArmor:
Цитата
AppArmor profiles completely define which system resources an application can access and with which privileges it can do so. Because they are written in standard UNIX syntax with no new jargon, the profiles can be audited quickly for the security implications of a profiled application. Further, AppArmor contains built-in reporting capabilities so that system administrators can quickly view AppArmor related events, schedule reports and aggregate events from multiple systems into a common report.

PM MAIL   Вверх
CPlusPlusFAN
Дата 23.8.2008, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 1.11.2005
Где: Воронеж

Репутация: нет
Всего: нет



Цитата(Sartorius @  23.8.2008,  14:30 Найти цитируемый пост)
Придется ИМХО отслеживать события в файловой системе и если что убивать порожденный процесс
http://www-128.ibm.com/developerworks/linu.../l-inotify.html


Вряд ли такую штуку дадут на сервак поставить...


Цитата(andrew_121 @  23.8.2008,  15:18 Найти цитируемый пост)
CPlusPlusFAN, Если у тебя есть сорцы этого test.exe то можешь их пригрутить к своему С++ коду. И никаких шеллов!
Странно. Рубрика про Линукс, а у тебя exe-шки 


Сорцы есть. Но хотелось бы к ним не обращаться. Я хотел решить эту проблему исключением файлов stdlib.h и cstdlib, но их тянут за собой какие-то stl хедеры.

Цитата(MAKCim @  23.8.2008,  18:20 Найти цитируемый пост)
W4FhLF, 
монитор пишется легко
ptrace() + PTRACE_SYSCALL
после остановки дочернего процесса смотрим EAX
через __NR_<имя системного сервиса> проверяем значение EAX
для

Цитата(CPlusPlusFAN @  23.8.2008,  14:18 )    
3) запретить создавать, менять, удалять какие-либо другие файлы, кроме 2-х вышеперечисленных    

__NR_open, __NR_write, __NR_unlink
для

Цитата(CPlusPlusFAN @  23.8.2008,  14:18 )    
3) исключить все лишние телодвижения test.exe типа system("cd .."), system("rm *").    

__NR_clone, __NR_fork, __NR_execve


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


MAKCim, можно пример. А то как-то не очень понятно.

ЗЫ Ребяты! Спасибо всем за отклики!

PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 23.8.2008, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(CPlusPlusFAN @  23.8.2008,  20:16 Найти цитируемый пост)
MAKCim, можно пример.

да
вот эта штука не позволит создать файл с именем MAKCim  smile 
Код

#include <asm/page.h>
#include <linux/user.h>
#include <linux/limits.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

static int monitor(pid_t pid) {
    static struct user_regs_struct regs;
    if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
        return 3;
    switch (regs.orig_ax) {
        default:
            return 0;
        case __NR_open: {
            if (!(regs.si & O_CREAT))
                return 0;
        }
        case __NR_creat: {
            char path[PATH_MAX + 1];
            char * ptr;
            unsigned long data;
            unsigned long start = regs.di, offset = start;    // get address of path name string
            for (;;) {
                unsigned long boundary;
                void * address;
                #define MASK ~(PAGE_SIZE - 1)
                if (((boundary = offset + sizeof(unsigned long)) & MASK) != (offset & MASK)) {
                    boundary -= offset;
                    boundary = sizeof(unsigned long) - boundary;
                    offset -= boundary;
                } else
                    boundary = 0;
                data = ptrace(PTRACE_PEEKDATA, pid, offset, NULL);
                if (errno)
                    return 6;
                if ((address = memchr((void*)&data + boundary, '\0', sizeof(unsigned long) - boundary)) == NULL) {
                    memcpy(&path[offset - start + boundary], (void*)&data + boundary, sizeof(unsigned long) - boundary);
                    offset += sizeof(unsigned long);
                    continue;
                }
                memcpy(&path[offset - start + boundary], (void*)&data + boundary, (size_t)(address - ((void*)&data + boundary)));
                ptr = &path[offset - start + address - ((void*)&data + boundary)];
                *ptr-- = '\0'; // null-terminated
                break;
            }
            for (; *ptr != '/' && ptr >= path; --ptr);
            ++ptr;
            if (strcmp(ptr, "MAKCim"))
                return 0;
            regs.di = 0;
            if (ptrace(PTRACE_SETREGS, pid, NULL, &regs) < 0)
                return 4;
        }
    }
    return 0;
}

int main(int argc, char * argv[], char * envp[]) {
    int status;
    int flags = 0;
    pid_t pid = fork();
    if (pid == 0) {
        if (ptrace(PTRACE_TRACEME, -1, NULL, NULL) < 0)
            _exit(errno);
        execvp(argv[1], &argv[1]);
    }
retry:
    waitpid(pid, &status, 0);
    if (WIFSTOPPED(status)) {
        if (flags)
            if (status = monitor(pid))
                return status;
        if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0)
            return 2;
        flags = 1;
    } else if (WIFEXITED(status))
        return 0;
    else if (WIFSIGNALED(status))
        return 1;
    goto retry;
}

к примеру
Код

# <эта программа> touch MAKCim



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
andrew_121
Дата 23.8.2008, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 3
Всего: 33



CPlusPlusFAN, Действительно странно. Есть сорцы твоей программы, но ты их тягать не хочешь! Но ты согласен дописывать демон-контроль?!!! Разве это проще?


Это сообщение отредактировал(а) andrew_121 - 24.8.2008, 11:11


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
CPlusPlusFAN
Дата 24.8.2008, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 1.11.2005
Где: Воронеж

Репутация: нет
Всего: нет



MAKCim, попробовал. Решил маленькую прогу для тестов накрапать. Вот она:
Код

#include <asm/page.h>    
#include <linux/user.h>    
#include <linux/limits.h>    
#include <sys/ptrace.h>    
#include <sys/syscall.h>    
#include <sys/wait.h>    
#include <fcntl.h>    
#include <unistd.h>    
#include <errno.h>    
#include <string.h>    
#include <stdio.h>

int monitor(int pid)
{    
    struct user_regs_struct regs;    
    ptrace(PTRACE_GETREGS,pid,NULL,&regs);
    return regs.eax;    
}

int main()
{
    int pid,status;
    bool stop=false;
    pid=fork();
    
    if (pid==0)
    {
        ptrace(PTRACE_TRACEME,-1,NULL,NULL);
        execl("./x",NULL,NULL);
    }
    
    while (!stop)
    {
        waitpid(pid,&status,0);
        if (WIFSTOPPED(status))
        {
            printf("STOP: %d\n",monitor(pid));
            ptrace(PTRACE_SYSCALL,pid,NULL,NULL);
        }
        else
            stop=true;
    }
    
    return 0;
}


Вот сорс проги x:
Код

#include <stdio.h>
int main()
{
    FILE *f=fopen("f.txt","w");
    fclose(f);
    return 0;
}


Оптимизация везде отключена.

Вот результаты:
Код

STOP: 0
STOP: -38
STOP: 134520832
STOP: -38
STOP: -2
STOP: -38
STOP: -1208565760
STOP: -38
STOP: -2
STOP: -38
STOP: 3
STOP: -38
STOP: 0
STOP: -38
STOP: -1208639488
STOP: -38
STOP: 0
STOP: -38
STOP: -2
STOP: -38
STOP: 3
STOP: -38
STOP: 512
STOP: -38
STOP: 0
STOP: -38
STOP: -1209634816
STOP: -38
STOP: -1208684544
STOP: -38
STOP: -1208664064
STOP: -38
STOP: 0
STOP: -38
STOP: -2
STOP: -38
STOP: 3
STOP: -38
STOP: 512
STOP: -38
STOP: 0
STOP: -38
STOP: -1209786368
STOP: -38
STOP: -1209643008
STOP: -38
STOP: 0
STOP: -38
STOP: -2
STOP: -38
STOP: 3
STOP: -38
STOP: 512
STOP: -38
STOP: 0
STOP: -38
STOP: -1209790464
STOP: -38
STOP: -1209835520
STOP: -38
STOP: -1209794560
STOP: -38
STOP: 0
STOP: -38
STOP: -2
STOP: -38
STOP: 3
STOP: -38
STOP: 512
STOP: -38
STOP: 0
STOP: -38
STOP: -1211187200
STOP: -38
STOP: -1209860096
STOP: -38
STOP: -1209847808
STOP: -38
STOP: 0
STOP: -38
STOP: -1211191296
STOP: -38
STOP: 0
STOP: -38
STOP: 0
STOP: -38
STOP: 0
STOP: -38
STOP: 0
STOP: -38
STOP: 134520832
STOP: -38
STOP: 134656000
STOP: -38
STOP: 3
STOP: -38
STOP: 0
STOP: -38


Скажу честно я ожидал встретить какой-то сигнал в начале работы программы (правда чё-то этих нулевых сигналов многовато).
Но что здесь делают сигналы с отрицательными значениями и этот непонятный 512?
Между ними несколько сигналов 3 (__NR_read). Причём здесь вообще чтение?

А где сигналы __NR_creat, __NR_open, __NR_close?

В общем ситуация требует прояснения.

Цитата(andrew_121 @  23.8.2008,  23:18 Найти цитируемый пост)
CPlusPlusFAN, Действительно странно. Есть сорцы твоей программы, но ты их тягать не хочешь! Но ты согласен дописывать демон-контроль?!!! Разве это проще?

Это запрещённый приём. Тем более у меня нет никакой гарантии, что не будет вот такой проги:
Код

char str[]="../b.txt";
int main()
{
FILE *f=fopen(str,"w");
...
return 0;
}


Или ещё хуже, юзверь напишет что-то в стиле обфускации и я буду по сорцам метаться в поисках вредоносного кода?

PM MAIL ICQ Jabber   Вверх
MAKCim
Дата 24.8.2008, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(CPlusPlusFAN @  24.8.2008,  14:41 Найти цитируемый пост)
Решил маленькую прогу для тестов накрапать

внимаательно посмотри код
у меня используется orig_ax, а не ax
у тебя же используется eax, а надо orig_eax


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
CPlusPlusFAN
Дата 25.8.2008, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 1.11.2005
Где: Воронеж

Репутация: нет
Всего: нет



MAKCim, вот моя прога:
Код

#include <asm/page.h>    
#include <linux/user.h>    
#include <linux/limits.h>    
#include <sys/ptrace.h>    
#include <sys/syscall.h>    
#include <sys/wait.h>    
#include <fcntl.h>    
#include <unistd.h>    
#include <errno.h>    
#include <string.h>    
#include <stdio.h>

const int sz=sizeof(long int);

union u
{
    long int dat;
    char symb[sz];    
};

void monitor(int pid)
{    
    
    struct user_regs_struct regs;    
    ptrace(PTRACE_GETREGS,pid,NULL,&regs);
    char name[sz+1]="";
    bool stop=false;
    
    if (regs.orig_eax==SYS_open)
    {
        printf("%u:\t",regs.ecx);
        u c;
        int index=0;
        while (!stop)
        {
            c.dat=ptrace(PTRACE_PEEKDATA,pid,regs.ebx+sz*index,NULL);
            for (int i=0;i<sz&&!stop;i++)
            {
                name[i]=c.symb[i];
                stop=name[i]=='\0';
            }
            printf("%s",name);
            index++;
        }
        printf("\n");
    }    
}

int main()
{
    int pid,status;
    struct rusage us;
    bool stop=false;
    pid=fork();
    
    if (pid==0)
    {
        ptrace(PTRACE_TRACEME,-1,NULL,NULL);
        execl("./x",NULL,NULL);
    }

    while (!stop)
    {
        wait4(pid,&status,0,&us);
        if (WIFSTOPPED(status))
        {
            monitor(pid);
            ptrace(PTRACE_SYSCALL,pid,NULL,NULL);
        }
        else
            stop=true;
    }
        
    
    return 0;
}


Перехватывает все открытия файлов. Только оказалось, что в ebx смещение имени файла, а в ecx флаги.

Неужели это так сильно зависит от платформы? Т.е. на фряхе будет мусор выводиться?

Почему один и тот же сигнал выводится 2 раза?

Почему, если прога x пытается открыть несуществующий файл для чтения, то моя прога виснет, а не выходит с сигналом?

Это сообщение отредактировал(а) CPlusPlusFAN - 25.8.2008, 21:15
PM MAIL ICQ Jabber   Вверх
CPlusPlusFAN
Дата 26.8.2008, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 1.11.2005
Где: Воронеж

Репутация: нет
Всего: нет



И вот ещё 1 вопрос, пока не забыл: будет ли эта штука с чтением регистров работать, если запускать прогу на виртуальной машине?
PM MAIL ICQ Jabber   Вверх
bsa
Дата 26.8.2008, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 16
Всего: 196



Цитата(CPlusPlusFAN @ 26.8.2008,  02:00)
И вот ещё 1 вопрос, пока не забыл: будет ли эта штука с чтением регистров работать, если запускать прогу на виртуальной машине?

да
PM   Вверх
MAKCim
Дата 26.8.2008, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(CPlusPlusFAN @  25.8.2008,  18:38 Найти цитируемый пост)
Неужели это так сильно зависит от платформы? Т.е. на фряхе будет мусор выводиться?

man 2 ptrace
Цитата

The layout of the contents of memory and the USER area are quite OS- and architecture-specific.
...
This page documents the way the ptrace() call works currently in Linux.  Its behavior differs noticeably on other flavors of Unix.  In any case, use of
ptrace() is highly OS- and architecture-specific.


Цитата(CPlusPlusFAN @  25.8.2008,  18:38 Найти цитируемый пост)
Почему один и тот же сигнал выводится 2 раза?

man 2 ptrace
Цитата

PTRACE_SYSCALL, PTRACE_SINGLESTEP
              Restarts  the  stopped  child  as  for PTRACE_CONT, but arranges for the child to be stopped at the next entry to or exit from a system call, or
              after execution of a single instruction, respectively. 


Цитата(CPlusPlusFAN @  25.8.2008,  18:38 Найти цитируемый пост)
Почему, если прога x пытается открыть несуществующий файл для чтения, то моя прога виснет, а не выходит с сигналом?

если процесс трассируется, то он переходит в состояние TASK_STOPPED при получении любого сигнала кроме SIGKILL
в данном случае fclose() для f (т. к f == NULL) приводит к SIGSEGV
wait4() возвращает управление и WIFSTOPPED() выполняется, т. к SIGSEGV != SIGKILL
следующий вызов ptrace() приводит к возобновлению работы процесса
т. к до этого было сгенерировано исключение #PF (приведшее к SIGSEGV), возврат на 3-е кольцо будет осуществлен на инструкцию, выполнение которой привело к #PF и SIGSEGV
генерируется очередное #PF и SIGSEGV и т. д до бесконечности
вот программа и висит


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0763 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.