
루트 권한 없이 리눅스 프로세스 모니터링
pspy는 루트 권한 없이 프로세스를 염탐하기 위해 설계된 명령줄 도구입니다. 다른 사용자가 실행하는 명령, cron 작업 등을 실행되는 그대로 볼 수 있습니다. CTF에서 Linux 시스템을 열거(enumeration)하는 데 유용합니다. 또한 명령줄 인수로 비밀을 전달하는 것이 왜 나쁜 생각인지 동료에게 시연하는 데도 유용합니다.
이 도구는 procfs 스캔에서 정보를 수집합니다. 파일 시스템의 선택된 부분에 배치된 Inotify 감시자가 이러한 스캔을 트리거하여 수명이 짧은 프로세스를 포착합니다.
검사하려는 Linux 머신에 도구를 가져오세요. 먼저 바이너리를 다운로드합니다. 릴리스된 바이너리는 여기서 다운로드하세요:
pspy32 다운로드pspy64 다운로드pspy32s 다운로드pspy64s 다운로드정적으로 컴파일된 파일은 모든 Linux 시스템에서 작동하지만 크기가 상당히 큽니다(~4MB). 크기가 문제라면 libc에 의존하고 UPX로 압축된 더 작은 버전(~1MB)을 시도해보세요.
시스템에 설치된 Go를 사용하거나 릴리스를 만드는 데 사용된 Docker 기반 빌드 프로세스를 실행하세요.
후자의 경우 Docker가 설치되어 있는지 확인한 다음 make build-build-image를 실행하여 Docker 이미지를 빌드하고, 이어서 make build를 실행하여 바이너리를 빌드합니다.
pspy --help를 실행하여 플래그와 그 의미를 확인할 수 있습니다.
요약은 다음과 같습니다:
기본 설정은 대부분의 응용 프로그램에 충분합니다.
/usr 내부의 파일을 감시하는 것이 가장 중요합니다. 많은 도구가 그 안에 있는 라이브러리에 접근하기 때문입니다.
더 복잡한 예시:
# 명령과 파일 시스템 이벤트를 모두 출력하고 1000ms(=1초)마다 procfs 스캔
./pspy64 -pf -i 1000
# 두 디렉터리에 재귀적으로 감시자를 배치하고 세 번째 디렉터리에는 비재귀적으로 배치
./pspy64 -r /path/to/first/recursive/dir -r /path/to/second/recursive/dir -d /path/to/the/non-recursive/dir
# 발견된 명령 출력을 비활성화하고 파일 시스템 이벤트 활성화
./pspy64 -p=false -f
도구의 동작을 보려면 저장소를 클론하고 make example을 실행하세요 (Docker 필요).
비밀번호를 명령줄 인수로 전달하는 것이 안전하지 않다는 것은 알려져 있으며, 이 예시는 이를 보여주는 데 사용될 수 있습니다.
이 명령은 root가 1분마다 사용자 비밀번호를 변경하는 비밀 cron 작업이 실행되는 Debian 컨테이너를 시작합니다.
pspy는 사용자 myuser로 포그라운드에서 실행되며 프로세스를 스캔합니다.
다음과 유사한 출력이 표시됩니다:
~/pspy (master) $ make example
[...]
docker run -it --rm local/pspy-example:latest
[+] cron started
[+] Running as user uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),27(sudo)
[+] Starting pspy now...
Watching recursively : [/usr /tmp /etc /home /var /opt] (6)
Watching non-recursively: [] (0)
Printing: processes=true file-system events=false
2018/02/18 21:00:03 Inotify watcher limit: 524288 (/proc/sys/fs/inotify/max_user_watches)
2018/02/18 21:00:03 Inotify watchers set up: Watching 1030 directories - watching now
2018/02/18 21:00:03 CMD: UID=0 PID=9 | cron -f
2018/02/18 21:00:03 CMD: UID=0 PID=7 | sudo cron -f
2018/02/18 21:00:03 CMD: UID=1000 PID=14 | pspy
2018/02/18 21:00:03 CMD: UID=1000 PID=1 | /bin/bash /entrypoint.sh
2018/02/18 21:01:01 CMD: UID=0 PID=20 | CRON -f
2018/02/18 21:01:01 CMD: UID=0 PID=21 | CRON -f
2018/02/18 21:01:01 CMD: UID=0 PID=22 | python3 /root/scripts/password_reset.py
2018/02/18 21:01:01 CMD: UID=0 PID=25 |
2018/02/18 21:01:01 CMD: UID=??? PID=24 | ???
2018/02/18 21:01:01 CMD: UID=0 PID=23 | /bin/sh -c /bin/echo -e "KI5PZQ2ZPWQXJKEL\nKI5PZQ2ZPWQXJKEL" | passwd myuser
2018/02/18 21:01:01 CMD: UID=0 PID=26 | /usr/sbin/sendmail -i -FCronDaemon -B8BITMIME -oem root
2018/02/18 21:01:01 CMD: UID=101 PID=27 |
2018/02/18 21:01:01 CMD: UID=8 PID=28 | /usr/sbin/exim4 -Mc 1enW4z-00000Q-Mk
먼저 pspy는 현재 실행 중인 모든 프로세스를 출력하며, 각각 PID, UID 및 명령줄을 표시합니다.
pspy가 새 프로세스를 감지하면 이 로그에 줄을 추가합니다.
이 예시에서는 PID 23인 프로세스가 myuser의 비밀번호를 변경하는 것으로 보입니다.
이는 root의 개인 crontab /var/spool/cron/crontabs/root에서 사용되는 Python 스크립트의 결과로, 다음 셸 명령을 실행합니다 (crontab 및 스크립트 확인).
myuser는 crontab이나 Python 스크립트를 볼 수 없습니다.
하지만 pspy를 사용하면 명령을 볼 수 있습니다.
아래는 Hack The Box의 Shrek 머신 예시입니다. 이 CTF 과제는 폴더 내 모든 파일의 소유권을 변경하는 숨겨진 cron 작업을 악용하는 것입니다. 취약점은 chmod와 함께 와일드카드를 안전하지 않게 사용하는 것입니다 (자세한 내용). 이를 찾고 악용하려면 상당한 추측 작업이 필요합니다. 그러나 pspy를 사용하면 cron 작업을 쉽게 찾고 분석할 수 있습니다:

Linux 시스템에서 실행된 모든 프로세스(종료된 프로세스 포함)를 나열하는 도구가 존재합니다. 예를 들어 forkstat가 있습니다. 이는 포크(fork) 및 exec와 같은 프로세스 관련 이벤트에 대한 커널 알림을 수신합니다.
이러한 도구는 루트 권한이 필요하지만, 이것이 잘못된 안전감을 주어서는 안 됩니다.
Linux 시스템에서 실행 중인 프로세스를 염탐하는 것을 막을 수 있는 것은 없습니다.
프로세스가 실행 중인 동안 procfs에서 많은 정보를 볼 수 있습니다.
유일한 문제는 수명이 짧은 프로세스를 그들이 살아있는 아주 짧은 시간 동안 포착해야 한다는 것입니다.
/proc 디렉터리를 무한 루프에서 새 PID를 스캔하면 효과적이지만 CPU를 많이 소모합니다.
더 은밀한 방법은 다음 트릭을 사용하는 것입니다.
프로세스는 /usr의 라이브러리, /tmp의 임시 파일, /var의 로그 파일 등과 같은 파일에 접근하는 경향이 있습니다.
inotify API를 사용하면 이러한 파일이 생성, 수정, 삭제, 접근될 때 알림을 받을 수 있습니다.
Linux는 이 API에 대해 권한 있는 사용자를 요구하지 않습니다. 많은 무해한 응용 프로그램(예: 최신 파일 탐색기를 보여주는 텍스트 편집기)에 필요하기 때문입니다.
따라서 루트가 아닌 사용자는 프로세스를 직접 모니터링할 수 없지만 파일 시스템에 대한 프로세스의 영향을 모니터링할 수 있습니다.
파일 시스템 이벤트를 트리거로 사용하여 /proc을 스캔하면 프로세스를 포착할 만큼 빠르게 수행할 수 있기를 바랍니다.
이것이 pspy가 하는 일입니다.
하나도 놓치지 않을 것이라는 보장은 없지만, 제 실험에서는 가능성이 높아 보입니다.
일반적으로 프로세스가 오래 실행될수록 포착할 가능성이 커집니다.
Logo: "By Creative Tail [CC BY 4.0 (http://creativecommons.org/licenses/by/4.0)], via Wikimedia Commons" (link)