728x90
반응형
원리
요약하자면 system call filtering 이다. syscall NR을 기준으로 실행여부를 판단한다.
구조
사용은 아래와 같이 한다.
int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
Mode
아래와 같이 2가지 모드가 있다.
- strict mode : read, write, sigreturn, exit만 허용함. 이외의 system call은 SIGKILL과 함께 즉시 종료.
- filter mode : 아래와 같은 추가 모드가 있다.
- SECCOMP_RET_KILL : System call을 수행하지 않고 해당 process를 즉시 종료 시킨다. 해당 process의 종료 값은 SIGSYS을 갖게된다. (Not SIGKILL)
- SECCOMP_RET_TRAP : System call을 수행하지 않고 해당 process에게 SIGSYS signal을 전송한다. SIGSYS singal을 받은 pocess는 system call을 emulation 할 수 있다.
- SECCOMP_RET_ERRNO : System call을 수행하지 않고 해당 thread의 errno 값을 설정한다.
- SECCOMP_RET_TRACE : Tracer에게 system call 이벤트를 전달한다. 만약 tracer가 존재하지 않으면 ENOSYS를 return하고 system call을 수행하지 않는다.
- SECCOMP_RET_ALLOW : System call을 수행한다.
복잡하지만, 결국 문제에서는 대부분 filter mode 일거다. (그래야 우회해서 다른 함수를 실행할 수 있으니까.)
우회 방법
syscall NR로 filtering 하는 것이기 때문에 이를 우회할 방법을 생각해야한다.
우선은 같은 역할을 수행하는 다른 syscall NR를 찾는 것이 주요사항이다.
예를 들면 open 함수는 openat과 같은 함수로 대체될 수 있다.
이를 선정하였다면 32 bit system NR로 함수를 실행하는 것을 목표로 하면 된다.
라고 길게 썼는데, seccomp-tools라는 꿀 프로그램이 있다.
https://github.com/david942j/seccomp-tools
예를 들면 이런식으로 사용하고, 필터링되는 syscall NR (K 값)을 찾아준다.
$ seccomp-tools dump spec/binary/twctf-2016-diary
# line CODE JT JF K
# =================================
# 0000: 0x20 0x00 0x00 0x00000000 A = sys_number
# 0001: 0x15 0x00 0x01 0x00000002 if (A != open) goto 0003
# 0002: 0x06 0x00 0x00 0x00000000 return KILL
# 0003: 0x15 0x00 0x01 0x00000101 if (A != openat) goto 0005
# 0004: 0x06 0x00 0x00 0x00000000 return KILL
# 0005: 0x15 0x00 0x01 0x0000003b if (A != execve) goto 0007
# 0006: 0x06 0x00 0x00 0x00000000 return KILL
# 0007: 0x15 0x00 0x01 0x00000038 if (A != clone) goto 0009
# 0008: 0x06 0x00 0x00 0x00000000 return KILL
# 0009: 0x15 0x00 0x01 0x00000039 if (A != fork) goto 0011
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
# 0011: 0x15 0x00 0x01 0x0000003a if (A != vfork) goto 0013
# 0012: 0x06 0x00 0x00 0x00000000 return KILL
# 0013: 0x15 0x00 0x01 0x00000055 if (A != creat) goto 0015
# 0014: 0x06 0x00 0x00 0x00000000 return KILL
# 0015: 0x15 0x00 0x01 0x00000142 if (A != execveat) goto 0017
# 0016: 0x06 0x00 0x00 0x00000000 return KILL
# 0017: 0x06 0x00 0x00 0x7fff0000 return ALLOW
728x90
반응형
'Tips & theory' 카테고리의 다른 글
SROP (0) | 2022.08.15 |
---|---|
rtld_global (0) | 2022.08.15 |
system call table & calling conventions (0) | 2022.08.05 |
bss 영역 찾기 (0) | 2022.08.05 |
유용한 사이트 (0) | 2022.08.03 |