소개
리눅스 및 유닉스 기반 시스템에서 파일 권한은 보안의 핵심 요소입니다. 특별한 권한 유형 중 하나로 SUID(Set Owner User ID) 비트가 있습니다. 바이너리 파일에 SUID 비트가 설정되어 있으면, 해당 파일을 실행한 사용자의 권한이 아닌 파일 소유자의 권한으로 실행됩니다.
이는 특정 시스템 기능 (예: 비밀번호를 업데이트하기 위해 루트 접근 권한이 필요한 passwd 명령어) 에는 필수적이지만, 잘못 구성될 경우 심각한 보안 위험이 됩니다. 시스템 관리자가 실수로 find, vim, bash와 같은 표준 유틸리티에 SUID 비트를 설정하면, 공격자는 이러한 도구를 활용하여 root 사용자로 명령을 실행할 수 있으며, 이는 '권한 상승 (Privilege Escalation)'이라고 불리는 완전한 시스템 장악으로 이어집니다.
SUID 가 위험한 이유는 프로그램 실행 자체의 권한 컨텍스트를 변경하기 때문입니다. 만약 해당 프로그램이 다른 명령어나 셸을 실행할 수 있다면, 그 권한이 외부로 유출될 수 있습니다.
이 실습에서는 보안 연구원의 입장이 되어 리눅스 파일 시스템을 스캔하고, SUID 비트가 설정된 바이너리를 찾아 취약한 구성을 식별한 뒤, 유명한 GTFOBins 프로젝트의 기술을 사용하여 루트 권한으로 상승시키는 과정을 수행합니다.
SUID 바이너리 검색 (find)
이 단계에서는 리눅스 파일 시스템에서 SUID 권한 비트가 설정된 바이너리를 검색하는 방법을 배웁니다.
이러한 파일을 찾기 위해 내장된 find 명령어를 사용합니다. find 명령어는 매우 강력하며 특정 권한을 기반으로 파일을 검색할 수 있게 해줍니다. 루트 디렉토리 /부터 시작하여 SUID 비트 (8 진수 값 4000으로 표시됨) 가 활성화된 파일을 찾아보겠습니다.
SUID 파일 열거는 일반 사용자가 높은 권한으로 실행하는 프로그램을 빠르게 찾아낼 수 있기 때문에 권한 상승을 위한 표준적인 습관입니다.
터미널에서 다음 명령어를 실행하여 SUID 바이너리를 검색하고, 그 결과를 프로젝트 디렉토리의 suid_results.txt라는 텍스트 파일에 저장하세요:
find / -perm -4000 -type f 2> /dev/null > ~/project/suid_results.txt
이 명령어가 정확히 무엇을 하는지 살펴보겠습니다. /는 파일 시스템의 최상위부터 검색을 시작하라는 의미입니다. -perm -4000 플래그는 SUID 비트가 설정된 파일을 구체적으로 찾습니다. -type f 플래그는 디렉토리가 아닌 일반 파일만 검색하도록 합니다. 마지막으로 2>/dev/null은 "Permission denied(권한 거부)" 오류 메시지를 블랙홀 (/dev/null) 로 보내 출력 결과를 깔끔하게 유지하는 유용한 기법입니다. > 기호는 깔끔한 출력 결과를 텍스트 파일로 리다이렉션합니다.
이제 방금 생성한 파일의 내용을 확인하여 어떤 바이너리에 SUID 비트가 설정되어 있는지 살펴보겠습니다:
cat ~/project/suid_results.txt
다음과 유사한 출력이 나타날 것입니다:
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/bin/chfn
/usr/bin/find
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/su
/usr/bin/mount
/usr/bin/umount
목록을 자세히 살펴보세요. passwd나 su와 같은 많은 파일은 SUID 비트가 설정되어 있는 것이 정상입니다. 하지만 이 중 하나는 매우 이례적이며 잠재적으로 위험해 보입니다.
악용 가능한 바이너리 식별 (GTFOBins)
이 단계에서는 검색 결과를 분석하고 어떤 바이너리를 악용할 수 있는지 식별합니다.
이전 단계의 출력 결과를 보면 목록에 /usr/bin/find가 있는 것을 확인할 수 있습니다. find 명령어는 파일을 검색하는 데 사용되는 표준 유틸리티이며, 정상적으로 작동하기 위해 루트 권한이 전혀 필요하지 않습니다. 이 파일에 SUID 비트가 설정되어 있다는 것은 심각한 보안 설정 오류입니다.
이러한 판단은 중요합니다. 모든 SUID 바이너리가 악용 가능한 것은 아니지만, 이례적인 바이너리는 설계자가 의도하지 않은 높은 권한을 노출할 수 있으므로 특별한 주의가 필요합니다.
이를 어떻게 악용할 수 있는지 이해하기 위해 보안 전문가들은 GTFOBins라는 리소스를 사용합니다. GTFOBins 는 잘못 구성된 시스템에서 로컬 보안 제한을 우회하는 데 사용할 수 있는 유닉스 바이너리 목록입니다. GTFOBins 웹사이트를 방문하여 "find"를 검색하면 find에는 다른 명령어를 실행할 수 있는 기능이 있다는 것을 알게 될 것입니다.
우리의 find 바이너리에 SUID 비트가 설정되어 있으므로, 이 명령어가 실행하는 모든 명령어는 바이너리 소유자 (즉, root) 의 권한으로 실행됩니다.
발견한 내용을 확인하기 위해 vulnerable_binary.txt라는 파일을 만들고 악용 가능한 바이너리의 이름을 기록하세요. 다음 명령어를 실행합니다:
echo "find" > ~/project/vulnerable_binary.txt
터미널에 출력하여 파일 내용을 확인할 수 있습니다:
cat ~/project/vulnerable_binary.txt
출력 결과는 다음과 같아야 합니다:
find
이 잘못된 구성을 식별함으로써 권한 상승 공격을 위한 진입점을 찾았습니다.
익스플로잇 명령어 작성
이 단계에서는 find 바이너리의 SUID 설정을 악용하는 데 필요한 구체적인 명령어 페이로드를 준비합니다.
GTFOBins 에 따르면 find 명령어에는 -exec 매개변수가 있습니다. 이 매개변수는 일반적으로 find가 찾는 모든 파일에 대해 특정 작업을 수행하는 데 사용됩니다. 그러나 공격자는 이 매개변수를 악용하여 시스템 셸 (/bin/sh) 을 실행할 수 있습니다.
표준 익스플로잇 페이로드는 다음과 같습니다: find . -exec /bin/sh -p \; -quit.
이 페이로드가 작동하는 이유를 살펴보겠습니다. .은 find에게 현재 디렉토리부터 검색을 시작하라고 지시합니다. -exec 플래그는 뒤따르는 명령어를 실행하라는 의미입니다. 셸을 실행하기 위해 /bin/sh를 제공합니다. -p 플래그는 매우 중요한데, 셸이 실행될 때의 권한 (이 경우 SUID 비트로 부여된 루트 권한) 을 유지하도록 지시합니다. \;는 실행하려는 명령어의 끝을 나타냅니다. 마지막으로 -quit는 명령어를 한 번 실행한 후 디렉토리 내의 모든 파일에 대해 반복하지 말고 즉시 검색을 중단하라고 find에 지시합니다.
최종 실행을 준비하기 위해 이 익스플로잇 페이로드를 exploit.sh라는 셸 스크립트 파일에 저장하겠습니다. 다음 명령어를 실행하세요:
echo 'find . -exec /bin/sh -p \; -quit' > ~/project/exploit.sh
방금 만든 스크립트를 확인하여 페이로드가 올바른지 확인하세요:
cat ~/project/exploit.sh
출력 결과에 작성한 페이로드가 표시됩니다:
find . -exec /bin/sh -p \; -quit
이제 find 바이너리를 속여 루트 셸을 얻는 데 필요한 정확한 명령어를 확보했습니다.
권한 상승 실행
마지막 단계에서는 익스플로잇을 실행하고 성공적으로 root 사용자로 권한을 상승시켰음을 증명합니다.
대화형 셸로 직접 진입하는 대신 (자동화된 실습 환경에서는 확인이 어려울 수 있음), 페이로드를 약간 수정하여 루트 권한으로 단일 명령어를 실행하고 그 결과를 저장하겠습니다. 현재 유효한 사용자의 이름을 출력하는 whoami 명령어를 사용합니다.
다음 명령어를 실행하여 취약한 find 바이너리를 통해 whoami를 실행하고 그 결과를 root_proof.txt라는 파일로 리다이렉션하세요:
/usr/bin/find . -exec whoami \; -quit > ~/project/root_proof.txt
앞서 식별한 특정 바이너리를 실행하기 위해 절대 경로 /usr/bin/find를 사용했음에 주목하세요. find 명령어가 실행되고, -exec 플래그가 트리거되며, SUID 비트 덕분에 루트 권한으로 whoami가 실행되어 결과가 저장됩니다.
이제 증명 파일의 내용을 확인하여 익스플로잇이 성공했는지 살펴보겠습니다:
cat ~/project/root_proof.txt
익스플로잇이 올바르게 작동했다면 출력 결과는 다음과 같습니다:
root
축하합니다! 잘못 구성된 SUID 바이너리를 성공적으로 악용하여 루트 사용자로 명령어를 실행했습니다.
실제로 대화형 루트 셸을 경험하고 싶다면, 이전 단계에서 작성한 페이로드를 터미널에서 직접 실행할 수 있습니다:
/usr/bin/find . -exec /bin/sh -p \; -quit
명령 프롬프트가 # 기호로 변경되어 현재 루트 사용자로 작업 중임을 나타냅니다. exit를 입력하면 루트 셸을 종료하고 일반 사용자 프롬프트로 돌아갈 수 있습니다.
요약
이 실습에서 여러분은 리눅스 시스템에서 SUID 설정 오류를 식별하고 악용하는 방법을 성공적으로 배웠습니다. find 명령어를 사용하여 SUID 권한 비트가 설정된 바이너리를 찾는 것부터 시작했습니다. /usr/bin/find가 비정상적임을 확인한 후, GTFOBins 와 같은 리소스를 사용하여 익스플로잇 페이로드를 찾는 방법을 익혔습니다. 마지막으로 find 바이너리의 -exec 매개변수를 악용하여 루트 권한으로 명령어를 실행하는 명령어를 작성하고 실행했습니다.
이 연습은 리눅스에서 적절한 권한 관리의 중요성을 강조합니다. 시스템 관리자는 표준 유틸리티가 의도치 않게 권한 상승의 경로를 제공하지 않도록 정기적으로 SUID 바이너리를 감사해야 합니다.



