읽기 권한이없는 실행 파일 추적


17

strace실행 권한을 사용할 때 Ubuntu 14.04에서 놀라운 동작을 발견 했는데 읽기 권한이 없습니다. 이것이 버그인지 또는 일부 표준 이이 모호한 동작을 요구하는지 궁금합니다.

먼저 백그라운드에서 일반 실행 파일을 시작하고 첨부하면 어떻게되는지 봅시다. 예상대로 이것은 작동합니다.

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

다음으로 실행 파일을 사용하여 읽기 권한이 없습니다.

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

이 실행중인 프로세스에 첨부 할 수 없습니다 :

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

이것은 또한 내가 기대하는 것입니다. 단순히 디버거를 프로세스에 연결하고 효과적으로 실행 파일에 대한 읽기 권한을 가질 수 있다면 읽기 권한없이 실행 권한을 부여하는 것은별로 좋지 않습니다.

그러나 이미 추적 된 프로세스에서 실행 파일을 시작하면 그렇게 할 수 있습니다.

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

이것은 나에게 예기치 않은 일이다. 이것은 보안 버그입니까, 아니면 표준에 의해 규정 된 기능입니까?


3
@ StéphaneChazelas : 요점은 단순히 그것을 strace에 대한 인수로 사용하여 ptrace 할 있다는 것입니다. 근본 원인은 execve호출시 프로세스가 이미 추적 된 경우 실행 된 파일의 읽기 권한을 다시 확인하지 않는 것 같습니다 . 그의 질문은 이것이 보안 버그인지 또는 필수 기능 인지 여부 입니다 (후자는 여전히 보안 버그, 사양의 보안 버그라고 생각합니다).
celtschk

@celtschk, 죄송합니다. 질문을 너무 빨리 읽었습니다.
Stéphane Chazelas

1
from에서 호출 된 EPERMget_dumpable()(코어 덤프가 허용되는지 여부를 확인하는 데 사용되므로 "덤프 가능") __ptrace_may_access()에서 ptrace_attach()온 것 같습니다 kernel/ptrace.c.
ninjalj

프로그램이 실행 중일 때 디버거가 코드를 포함하는 실행 가능한 실행 파일을 생성하는 데 충분한 정보를 사용할 수 있습니까? 아니면 프로그램 로더가 프로그램을 실제로 작동시키는 데 필요한 재배치 수정과 같은 항목을 버립니까?
supercat

@supercat 내가 아는 한 디버거는 재배치 코드를 포함하여 실행중인 모든 사용자 모드 코드를 통해 단일 단계에 액세스 할 수 있습니다. 이러한 수준의 액세스 권한으로 작업 실행 파일을 재현하기가 너무 어렵지 않아야합니다.
kasperd

답변:


7

이것은 다른 사람이 공부하고 싶을 경우에 대한 답이 아니라 링크와 생각의 모음입니다. 이것은 매우 흥미로운 일이기 때문입니다.

유닉스 및 리눅스에 대한 관련 답변 은 읽기 전용 바이너리를 이런 식으로 덤프 할 수 있다는 것입니다 (또는 현재 바닐라 커널로 테스트 할 수 없었습니다).

Grsecurity이 해결하기 위해 노력했다 config 옵션패치 자체를 (그 이후로 변경되었을 수 있습니다 입력해도)

이 커밋 은 커널 개발자가 실제로 suid 바이너리를 덤프하는 것만 걱정하는 것처럼 보입니다.

그러나 실제로이 에서 커널은 읽을 수없는 바이너리 바이너리를 SUID 상태로 덤프하지 않기를 원한다고 생각합니다. 그리고이 은 덤프 할 수없는 바이너리는 추적 할 수 없다는 것을 나타냅니다.

첫눈에 커널에 보안 관련 버그가있는 것 같습니다. 그러나 저는 커널 개발자가 아니므로 확실하게 말할 수 없습니다. 나는 LKML을 물을 것이다.

편집 : 디버거와 관련하여 주석에서 언급 한 원래 게시물에 대한 또 다른 발견-gdb는 추적 된 바이너리를 사용합니다 /proc/<pid>/mem. 실행중인 바이너리를 읽을 수 없으면를 cat /proc/<pid>/mem반환합니다 EPERM. 바이너리가 읽을 수 있으면를 반환합니다 EIO. (몇 가지 보안 패치를 실행하는 Ubuntu 14.10에서 이것을 테스트 했으므로 바닐라 커널과 다를 수 있습니다. 다시 말하지만 바닐라 커널은 편리한 곳에서 실행되지 않습니다 :()

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.