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

+ Recent posts