SECCOMP 우회를 위한 시스템 콜

dandb3·2023년 5월 23일
0

이것저것 TMI

목록 보기
12/17

open 시스템 콜이 SECCOMP에 의해 막혀있다면 openat 시스템 콜을 고려해 볼 수 있다.

  • openat 시스템 콜

    #include <fcntl.h>
    
    int openat(int dirfd, const char *pathname, int flags);
    int openat(int dirfd, const char *pathname, int flags, mode_t mode);
    • open 시스템 콜과 완전히 같게 동작하는데, 다음 부분이 다르다 :
      • dirfd 인자는 directory의 fd값으로, pathname이 상대경로라면 상대경로의 기준 위치를 dirfd로 잡는다.
      • 만약 pathname이 절대경로라면 dirfd값은 무시된다.
      • dirfd값이 AT_FDCWD(-100)이라면 current directory로 설정된다.
  • sendfile 시스템 콜

    #include <sys/sendfile.h>
    
    ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
    • in_fd에서 데이터를 읽어와 out_fd에 쓴다.
    • 커널 내부에서 모두 이루어지기 때문에 read & write 과정보다 더 효율적이다.
    • offset == NULL
      • in_fd는 file offset부터 읽기 시작함.
      • file offset은 자동으로 업데이트 된다.
    • offset != NULL
      • file offset값을 가지고 있는 변수를 가리킨다.
      • 읽는 시작 위치는 file offset부터 시작되며, sendfile()이 종료되면 offset이 가리키는 변수는 마지막으로 읽은 file의 위치로 설정된다.
    • 주의해야 할 점
      • sendfile 시스템 콜은 파일 간의 읽고 쓰기를 위한 것이므로, 인자로 들어오는 fd 값들은 모두 파일에 해당하는 것들이어야 한다.
      • 만약 파일의 데이터를 stdout에 쓰고 싶다고 해서 sendfile(1, in_fd, NULL, 10); 이런 식으로 쓴다면, 1은 stdout의 fd값이지 파일의 fd값으로 인식하지 않기 때문에 에러가 발생함.
      • 그래서 미리 int out_fd = openat(0, "/dev/stdout", O_WRONLY);를 해 준 후에 이 out_fd를 사용하게 되면 파일로 인식하기 때문에 잘 동작하게 된다.

    x주의x

    • 파일에 해당하지 않으면 동작하지 않는다는 것은 라이브러리 함수 상에서 그렇다는 것이고, 시스템 콜에서는 그 검증을 하지 않으므로 잘 동작한다.
    • 시스템 콜 상에서의 인자의 순서는 함수 호출규약과 다르게, rdi, rsi, rdx, r10, r8, r9 순서이다. 얘 땜에 한참 헤맸네..
profile
공부 내용 저장소

0개의 댓글