Seccomp
리눅스 커널에서 제공하는 프로세스 샌드박싱 기법입니다.
규칙에 맞게 syscall 호출을 허용 및 차단하여 쉘 코드의 공격을 방지하는 리눅스 보안
매커니즘이라고 볼 수 있겠습니다.
Seccomp 기능은 prctl( ) 함수를 통해 사용할 수 있습니다.
prctl(PR_SET_SECCOMP, mode, &sock_fprog)
struct sock_fprog {
unsigned short len; // BPF 인스트럭션 개수
struct sock_filter *filter; BPF // BPF 인스트럭션 배열
};
struct sock_filter { /* 필터 블록 */
__u16 code; /* 실제 필터 코드 */
__u8 jt; /* 참 점프 */
__u8 jf; /* 거짓 점프 */
__u32 k; /* 범용 다용도 필드 */
};
첫 번째 인자는 seccomp의 설정
두 번째 인자는 seccomp의 mode
seccomp.h
#define SECCOMP_MODE_DISABLED 0
#define SECCOMP_MODE_STRICT 1
#define SECCOMP_MODE_FILTER 2
/*
https://code.woboq.org/linux/include/linux/seccomp.h.html
sock_fprog 구조체의 경우 seccomp mode가 FILTER이고 BPF를 사용하여 필터를 추가할 때
사용하게 됩니다.
seccomp의 모드를 먼저 살펴보겠습니다.
SECCOMP_SET_MODE_STRICT
허용되는 시스템 호출이 read, write, _exit, sigreturn 입니다. 그 외의 다른 시스템 호출은
SIGKILL 시그널을 전달하여 프로그램을 종료하게 됩니다.
SECCOMP_SET_MODE_FILTER
블랙리스트 혹은 화이트리스트 방식으로 필터를 만들어 적용합니다.
필터를 만드는 2가지의 방법은 다음과 같습니다.
라이브러리 함수를 사용하는 경우
#include<seccomp.h>
typedef void & scmp_filter_ctx;
scmp_filter_ctx seccomp_init(uint32_t def_action);
/* def_action
SCMP_ACT_KILL : 필터를 제외한 나머지는 모두 차단
SCMP_ACT_ALLOW: 필터를 제외한 나머지는 모두 허용
*/
seccomp_rule_add(scmp_filter_ctx, uniot32_t action, int syscall, ...)
/* 필터를 추가 */
seccomp_load(scmp_filter_ctx)
/* seccomp 필터를 커널에 로드. */
/*
참고 : https://manpages.debian.org/testing/libseccomp-dev/
버클리 패킷 필터(BPF)를 사용
BPF_STMT(opcode, operand)
/* operand에 해당하는 값을 opcode로 가져옴 */
BPF_JUMP(opcode, operand, true_offset, false_offset)
/* operand와 opcode를 비교 후 결과에 따라 특정 offset으로 분기 */
#define ALLOW_SYSCALL(name) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_##name, 0, 1),\
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
#define KILL_PROCESS \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
/*
참고 : https://outflux.net/teach-seccomp/step-2/seccomp-bpf.h
sock_filter 구조체에 ALLOW_SYSCALL 매크로를 사용하여 필터를 만들고 sock_fprog 구조체를 사용해
prctl( ) 함수의 3번째 인자로 전달합니다.
Bypass Seccomp
1) Seccomp를 우회할 수 있는 다른 시스템 콜을 사용합니다. 주의해야 할 점은 다른 시스템 콜에
크게 의존하지 않는 시스템 콜을 호출해야 한다는 점입니다.
2 ) FILTER Mode에서 라이브러리 함수를 사용한 경우x86-64와 x32에서 명령어의 호완을 지원하기 위해
Seccomp 사용 시 아키텍처의 구조에 따라 do_syscall_64 , do_syscall_32 호출의 분기점을 생성합니다.
x86_64 에서 필터가 적용되어 있다면 do_syscall_32 로 우회하여 시스템 콜 호출이 가능하게 됩니다.
추가로, CTF에서 SECCOMP가 적용된 바이너리를 분석할 때에 강력한 도구인 seccomp-tools 를 사용하여
바이너리 분석을 수월히 할 수 있습니다.
'System' 카테고리의 다른 글
Stack Pivot (0) | 2022.05.17 |
---|---|
DLL Load(IAT, EAT) (0) | 2022.03.27 |