정보 · 테크
왜 validator 문제는 푸는 사람에 따라 bss에 실행권한이 다를까?

대충 이 이야기의 시작은, 오래전 작년 12월로 넘어간다.. 오픈 카톡 채팅방에 정도비님이 물어보셨다.

내 컴퓨터에서는 bss 섹션에 X가 없는데, 다른 사람 라이트업을 보니 bss에 shellcode를 작성해서 exploit을 했다더라..


까먹고 있다가 갑자기 생각나서 root cause를 찾기로 마음먹었다. 사실 LINUX MAGIC !! ^__^ 으로 남기고 싶었지만 본인은 호기심이 많은 해킹 소년이기 때문에 바로 해킹의 신 luke님에게 달려가 이것저것 원인을 찾아보기 시작했다.

그 원인은 바로 linux의 backward-compability 때문이다.

	/* Do this immediately, since STACK_TOP as used in setup_arg_pages
	   may depend on the personality.  */
	SET_PERSONALITY2(*elf_ex, &arch_state);
	if (elf_read_implies_exec(*elf_ex, executable_stack))
		current->personality |= READ_IMPLIES_EXEC;

https://github.com/torvalds/linux/blob/1d1df41c5a33359a00e919d54eaebfb789711fdc/fs/binfmt_elf.c#L1005-L1009

리눅스는 personality를 통해 execution domain을 관리한다. 만약 current process의 personality에 READ_IMPLIES_EXEC가 있다면 READ로 맵핑된 페이지도 EXECUTABLE권한을 갖게 된다.

커널에서 process의 personality를 설정할 때 아래와 같은 단계를 거친다. (visualize된 decision process는 최신 커널: https://github.com/torvalds/linux/blob/a931dd33d370896a683236bba67c0d6f3d01144d/arch/x86/include/asm/elf.h#L280-L303, validator 문제가 도는 커널 + LTS 커널: https://github.com/torvalds/linux/commit/122306117afe4ba202b5e57c61dfbeffc5c41387 를 참고하면 된다.)

  1. program header에 GNU_STACK가 있나?
  2. 없다면, READ_IMPLIES_EXEC 설정
  3. 있다면? RW인지 RWX인지 확인.
  4. RW라면 -> 그대로
  5. RWX라면 READ_IMPLIES_EXEC 설정

조금 더 알기쉽게 설명하면, nx가 없던 시절, bss영역을 포함한 read 권한이 존재하는 영역에 실행 가능한 코드를 넣는 경우가 종종 있었다. 따라서 해당 바이너리들을 현재 시스템에서 실행하면 권한 문제로 크래시가 발생하니, 이를 해결하기 위해(backward-compability) 위와 같은 코드를 삽입한 것이다.

현재는 GNU_STACK이 아예 존재하지 않아야 (decision process참고), 다른 세그먼트에도 X권한이 생긴다. validator문제 처럼 .bss에 강제로 x권한을 주기 위해서는 section header flag에 executable flag를 따로 설정해주면 된다. (0x1711 offset 3 -> 7)

  [24] .bss              NOBITS           000000000060104b  0000104b
       0000000000000005  0000000000000000 WAX       0     0     1

참고:

작성자 정보
Karatus
워게임: 50
2년 전
오호 이것 참 흥미로운 이슈네요
avatar
Sechack
CTF First Place
2년 전
헉 궁금했던건데 감사합니다.