Skip to content
Somansa edited this page Nov 20, 2020 · 8 revisions

Welcome to the endpointdlp wiki!

Introduction

  • 정보유출방지 (DLP: Data Loss Prevention)와 엔드포인트 정보유출방지(Endpoint DLP)는 어떤 보안 솔루션을 뜻하는지 살펴보면 다음과 같습니다.
  1. DLP란?
  2. Endpoint DLP란?

Endpoint DLP 구현을 위한 기술

  • 엔드포인트에서 중요 정보의 유출에 사용될 수 있는 매체를 통제하기 위해서는 다음의 기술을 사용할 수 있습니다.
  1. LSM
  2. fanotify
  3. syscall table 직접 변경
  4. kprobe
  5. ftrace
  6. seccomp

Endpoint DLP 코드 샘플

  • fanotify 기반의 샘플 코드는 다음과 같습니다
  1. 초기화 하는 부분: initialize_fanotify()

    static int initialize_fanotify(int argc, const char **argv)
    {
        int i = 0;
        int fanotify_fd = 0;
        
        if ((fanotify_fd = fanotify_init (FAN_CLOEXEC| FAN_CLASS_CONTENT,
                                          O_RDONLY | O_CLOEXEC | O_LARGEFILE | O_NOATIME)) < 0)
        {
            fprintf (stderr,
                     "Couldn't setup new fanotify device: %s\n",
                     strerror (errno));
            return -1;
        }
        
        n_monitors = 1;
        monitors = (monitored_t*)malloc (n_monitors * sizeof (monitored_t));
    
        {
            monitors[i].path = strdup ( "/media/somansa/1493-193A" );
            
            if (fanotify_mark (fanotify_fd,
                               FAN_MARK_ADD | FAN_MARK_MOUNT,
                               event_mask,
                               AT_FDCWD,
                               monitors[i].path) < 0)
            {
                fprintf (stderr,
                         "Couldn't add monitor in mount '%s': '%s'\n",
                         monitors[i].path,
                         strerror (errno));
                return -1;
            }
            
            printf ("Started monitoring mount '%s'...\n",
                    monitors[i].path);
        }
        return fanotify_fd;
    }
    
    
    
    
  2. 실제 파일 이벤트 처리 함수: event_process()

    static void event_process (struct fanotify_event_metadata *event, int fanotify_fd)
    {
        char file_path[PATH_MAX] = {0};
        char program_path[PATH_MAX] = {0};
        
        if (NULL == get_file_path_from_fd (event->fd, file_path, PATH_MAX))
        {
            struct fanotify_response access = {0};
            access.fd = event->fd;
            access.response = FAN_ALLOW;
            write (fanotify_fd, &access, sizeof (access));
            return;
        }
        
        printf ("Received event in path '%s'=>[%d]", file_path, event->mask);
        printf (" pid=%d (%s): \n",
                event->pid,
                (get_program_name_from_pid (event->pid, program_path, PATH_MAX) ?
                 program_path :
                 "unknown"));
        
        //if (event->mask & FAN_OPEN_PERM)
        {
            struct fanotify_response access = {0};
            
            access.fd = event->fd;
            
            //   if (strstr (file_path, "666") != NULL)
            // {
            //   printf ("\tFAN_OPEN_PERM: denying\n");
            //   access.response = FAN_DENY;
            // }
            //   else
            {
                //printf ("\tFAN_OPEN_PERM: allowing\n");
                access.response = FAN_ALLOW;
            }
            
            write (fanotify_fd, &access, sizeof (access));
        }
        
        fflush (stdout);
        close (event->fd);
    }
    
    
    
  3. 앞의 함수들을 호출하는 main 로직 부분: main()

    int main (int argc, const char **argv)
    {
        int signal_fd = 0;
        int fanotify_fd = 0;
        struct pollfd fds[FD_POLL_MAX] = {0};
        
    .... (생략) ....
            
        if ((fanotify_fd = initialize_fanotify (argc, argv)) < 0)
        {
            fprintf (stderr, "Couldn't initialize fanotify\n");
            exit (EXIT_FAILURE);
        }
    
    .... (생략) ....
            
        /* Now loop */
        for (;;)
        {
            /* Block until there is something to be read */
            if (poll (fds, FD_POLL_MAX, -1) < 0)
            {
                fprintf (stderr,
                         "Couldn't poll(): '%s'\n",
                         strerror (errno));
                exit (EXIT_FAILURE);
            }
            
    .... (생략) ....
                
            /* fanotify event received? */
            if (fds[FD_POLL_FANOTIFY].revents & POLLIN)
            {
                char buffer[FANOTIFY_BUFFER_SIZE];
                ssize_t length;
                
                if ((length = read (fds[FD_POLL_FANOTIFY].fd,
                                    buffer,
                                    FANOTIFY_BUFFER_SIZE)) > 0)
                {
                    struct fanotify_event_metadata *metadata;
                    
                    metadata = (struct fanotify_event_metadata *)buffer;
                    while (FAN_EVENT_OK (metadata, length))
                    {
                        event_process (metadata, fanotify_fd);
                        if (metadata->fd > 0)
                            close (metadata->fd);
                        metadata = FAN_EVENT_NEXT (metadata, length);
                    }
                }
            }
        }
        
    .... (생략) ....
            
        printf ("Exiting fanotify example...\n");
        
        return EXIT_SUCCESS;
    }
    
    
  • 전체 소스는 여기를 참고해 주세요

https://github.com/somansa-oss/endpointdlp/blob/master/examples/filesystem_monitoring/fs_monitor.c

Clone this wiki locally