what is seccomp & bypass

위 문제를 풀다가 실패하면서 배운점을 적는다.

Program terminated with signal SIGSYS, Bad system call. 오류가 난다.

SIGSYS 는 보기 쉽지 않은 시그널이다. 누가봐도 seccomp에서 보내는 시그널 같았다.

다음 블로그를 참고하였다.

• SECCOMP_RET_KILL : System call을 수행하지 않고 해당 process를 즉시 종료 시킨다. 해당 process의 종료 값은 SIGSYS을 갖게된다. (Not SIGKILL)

프로그램에서 사용하는 SCMP_ACT_KILL flag에서 SIGSYS 시그널을 보내 안되는 것이 확실해져간다.

따라서 내가 직접해당 함수를 지워보고 컴파일을 해보았다.

JavaScript
//banned_execve();

다음과 같이 함수를 주석처리안뒤 컴파일을 하고 내 코드를 다시 실행해보니

JavaScript
(base) ┌──(kali㉿kali)-[~/Desktop/one day 1 pwn]
└─$ python exploit.py
[+] Starting local process './shell_basic': pid 2737363
b'jBX\xfe\xc4H\x99RH\xbf/bin//shWT^I\x89\xd0I\x89\xd2\x0f\x05'
/home/kali/miniconda3/lib/python3.12/site-packages/pwnlib/tubes/tube.py:841: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  res = self.recvuntil(delim, timeout=timeout)
[*] Switching to interactive mode
 $ ls
core.1985754  core.2063618  exploit.py  shell_basic  shell_basic.c
$ id
uid=1000(kali) gid=1000(kali) groups=1000(kali),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),101(netdev),106(bluetooth),113(scanner),135(wireshark),137(kaboxer),988(docker)

정상적으로 execve가 실행되면서 shell이 따진다.

seccomp에 대해서 자세히 알아보자면

C
void banned_execve() {
  scmp_filter_ctx ctx;
  ctx = seccomp_init(SCMP_ACT_ALLOW);
  if (ctx == NULL) {
    exit(0);
  }
  seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
  seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 0);

  seccomp_load(ctx);
}

ctx = seccomp_init(SCMP_ACT_ALLOW);

에서 일단 초기화 모든 시스템콜을 허락한뒤

seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0); seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 0);

다음과 같이 execve , execveat 에 대해서 rule을 추가한다. 그런데 왜 2개를 추가할까?

seccomp는 특정 시스템 호출의 번호(syscall number, NR)를 기반으로 필터링을 하게 된다.

따라서 번호가 다르면 우회를 할수 있다는 뜻이다.

execve 는 원래부터 있었던 명령어 지만 나중에 execveat ( execve at a location , 파일 디스크립터등으로 명려어 실행이 가능함 → 확장판이라고 보면 됨 ) 가 추가되었다. 따라서 둘은 당연히 NR 이 다르고 우회가 가능하게 된다.

추가적으로 64비트는 32비트 명령어를 지원한다. 이때 64비트와 32비트의 같은 명령어도 NR이 다르다. 따라서

seccomp 우회를 할때는 at을 붙이는 at a location 명령어를 생각해야 하고 32비트 명령어도 생각해봐야 한다.

https://github.com/david942j/seccomp-tools

다음과 같이 seccomp 에 대해 알려주는 tool이 존재한다.

seccomp의 syscall 인자 제한에 대한 글