네트워크를 망가뜨리지 않고 Mac에서 백신 제거하기
백신 제품은 앱 하나가 아닙니다. 앱 번들에 더해, macOS가 자기 쪽 울타리 안에 따로 보관하는 등록 정보 한 무더기가 딸려 있습니다. 시스템 확장 기능, 저장된 네트워크 필터 설정, 하나 이상의 launchd 작업, 대개 권한 있는 헬퍼, 그리고 관리 대상 Mac이라면 구성 프로필까지요. 번들을 휴지통으로 끌어다 놓으면 앞단만 사라지고 이 등록 정보는 전부 그대로 남습니다. 이 분야가 "지워지지 않는다"는 평판을 얻은 이유이자, 첫 번째로 해야 할 일이 Finder가 아니라 제조사 자체의 제거 도구인 이유입니다.
보안 제품이 앱 번들 말고 또 무엇을 설치하는가
어떤 Mac에서든 읽기 전용으로 1분이면 전체 설치 흔적을 목록으로 뽑을 수 있습니다.
systemextensionsctl list
ls -la /Library/LaunchDaemons /Library/LaunchAgents ~/Library/LaunchAgents
ls -la /Library/PrivilegedHelperTools
profiles list
pkgutil --pkgs | grep -i vendorname
시스템 확장 기능은 파일과 트래픽을 검사하는 코드를 담고 있으며, 이 소프트웨어가 예전에 함께 설치하던 커널 확장 기능을 대체합니다. 그래서 .kext를 지우라는 옛날 조언은 이제 아무것도 설명해주지 못합니다. Apple의 시스템 확장 기능 안내는 이게 어디 사는지 이렇게 말합니다. "시스템 확장 기능은 앱의 Contents/Library/SystemExtensions 폴더 안에 있습니다." 활성화하려면 여러분의 승인이 필요하니, 보안 소프트웨어를 설치할 때는 반드시 시스템 설정을 거쳐야 합니다. Apple의 배포 기술 노트는 제거할 때 중요해지는 특성을 하나 더 덧붙입니다. 이런 식으로 패키징된 provider는 "로그인한 사용자와 완전히 무관한 전역 컨텍스트에서 실행"됩니다.
네트워크 콘텐츠 필터나 투명 프록시는 별개의 객체이고, 사람들의 인터넷을 끊어버리는 바로 그 주범입니다. 이걸 켜는 설정은 앱이 아니라 시스템 쪽에 속해 있습니다. NEFilterManager는 이렇게 명확히 밝힙니다. "필터 설정은 Network Extension 프레임워크가 관리하는 Network Extension 환경설정에 저장됩니다." 그리고 변경 사항은 소유 앱이 명시적으로 저장할 때만 적용됩니다.
launchd 작업이 백그라운드 요소를 시작합니다. /Library/LaunchDaemons는 아무도 로그인하기 전에 부팅 시점에 root로 실행되고, /Library/LaunchAgents는 모든 사용자의 로그인 시점에 실행되며, ~/Library/LaunchAgents는 여러분을 위해 실행됩니다. 이 폴더 안의 plist는 평범한 설정 파일이 아니라 launchd에 대한 등록 정보입니다.
/Library/PrivilegedHelperTools 아래의 권한 있는 헬퍼는 root가 소유한 실행 파일이고, 파일이 어디로든 옮겨지기 전에 먼저 언로드해야 하는 데몬과 짝을 이룹니다. 직장이나 학교가 배포한 Mac의 구성 프로필은 확장 기능 승인과 필터 페이로드를 담고 있어서 아무에게도 묻지 않고 소프트웨어를 설치할 수 있게 해주는데, 같은 메커니즘이 그걸 다시 되돌려놓을 수도 있습니다.
휴지통으로 끌어다 놓는 게 통하지 않는 이유
Apple은 좋은 소식을 하나 문서로 남겼는데, 처음 읽을 때보다 실제로는 훨씬 좁은 범위입니다. "사용자가 해당 앱을 삭제하면 시스템이 시스템 확장 기능을 자동으로 제거합니다." 이건 번들 안에 있는 확장 기능에만 해당하고, 번들 안에 없는 나머지 등록 정보에 대해서는 아무 말도 하지 않습니다.
가장 흔한 불만 뒤에는 필터 설정이 있습니다. 이건 Network Extension 환경설정 안에서 독자적인 생명 주기를 가지며, Apple은 그 제거를 소유 앱이 명시적으로 호출해야 하는 작업으로 문서화하고 있습니다. 앱을 지운다고 그 호출이 일어나지는 않습니다. 남는 건 더 이상 존재하지 않는 provider를 가리키는 활성화된 필터이고, 이게 바로 사람들이 절반만 제거된 뒤에 보고하는 증상입니다. DNS 조회 실패, 모든 페이지에서 멈춰버리는 브라우저, Wi-Fi 아이콘은 신호 가득인데 연결이 타임아웃되는 현상. 네트워크는 멀쩡합니다. 트래픽이 응답할 수 없는 필터로 넘어가고 있는 겁니다.
launchd 작업이 두 번째 실패입니다. 실행 파일을 지운다고 그걸 시작하는 작업이 등록 해제되지는 않습니다. 오히려 멀쩡히 돌아가던 서비스를 실행할 때마다 실패하는 서비스로 바꿔놓을 뿐이고, 계속 살아 있도록 설정된 작업은 루프를 그리며 재시도되는데, "제거했는데 팬이 돌아간다"는 제보가 여기서 나옵니다. 작업이 로드된 상태에서 plist를 지우는 건 그 반대 상황입니다. launchd는 디스크에 그 실체가 없어도 다음 재부팅까지 그 작업을 계속 유지합니다. 헬퍼와 프로필이 살아남는 이유도 같습니다. 소프트웨어 페이로드를 담은 프로필은 여러분이 지운 걸 다시 설치해버립니다.
이 번거로움은 설계상의 결정입니다
어떤 프로세스든 조용히 제거할 수 있는 보안 소프트웨어라면 쓸모가 없을 겁니다. 제대로 된 악성코드라면 가장 먼저 자기를 감시하는 걸 없애려 들 테니까요. 그래서 macOS는 이 생명 주기의 양 끝을 백그라운드 프로세스가 손댈 수 없는 곳에 둡니다. 활성화하려면 사람이 직접 시스템 설정에서 허용을 클릭해야 하고(Apple의 알림 페이지는 macOS 15 이상에서는 로그인 항목 및 확장 프로그램을, 그 이전에는 개인정보 보호 및 보안을 가리킵니다), 비활성화는 그 확장 기능을 소유한 앱이 보내는 요청이어야 합니다. 이 번거로움은 설계가 제대로 작동하고 있다는 증거이고, 여러분에게 숨겨져 있는 "진짜 제거 방법"이라는 rm 명령어 시퀀스 같은 건 없습니다.
원칙: 제조사 제거 도구부터 먼저 실행하세요
언제나, 다른 무엇에도 손대기 전에 먼저요. 자기 확장 기능의 비활성화 요청을 보낼 수 있는 건 그걸 담고 있는 앱뿐입니다. 필터 설정을 Network Extension 환경설정에서 지울 수 있는 건 그걸 저장했던 앱뿐입니다. 순서를 어기고 하나를 멈추면 나머지 구성 요소 중 무엇이 그걸 재설치할지 아는 건 제조사의 도구뿐입니다. 서드파티 제거 도구는 이런 핸들에 접근할 수 없으니, Mole을 포함한 잔여물 스캐너는 제조사 도구가 실행된 뒤 남은 것을 위한 것이지, 그걸 대체하는 게 절대 아닙니다.
이미 앱을 휴지통으로 끌어다 놓았다면 파일 > 원위치로 되돌린 뒤 실행해서 자체 제거 도구를 쓰세요. 아래 섹션에서 각 제조사가 그걸 어디에 두는지 알려드립니다.
제조사별 제거 도구 위치
아래 링크는 모두 제조사 자체 지원 사이트를 가리킵니다. 최신 절차는 거기 있습니다. 지원 페이지는 종종 바뀌니, 이 요약과 실제 페이지 내용이 다르다면 이 요약이 아니라 페이지를 따르세요.
McAfee
제거 도구는 이미 Mac 안, Applications에 구매한 제품 이름을 달고 들어 있습니다. Total Protection 설치와 LiveSafe 설치는 서로 다른 제거 도구를 씁니다. McAfee의 문서는 관리자로 로그인하고, 모든 McAfee 앱을 종료한 뒤, 이동 > 응용 프로그램을 열어 해당 제거 도구를 더블클릭하라고 안내합니다. 임의로 진행하지 말고 문서를 읽어야 할 이유가 되는 단계가 두 가지 있습니다. macOS가 시스템 확장 기능에 대해 물으면 허용을 클릭하라고 하고, 마지막은 제안이 아니라 번호가 붙은 필수 단계로 재시작을 요구합니다. 죽어버린 Dock 아이콘은 제거 뒤에도 남을 수 있어서 손으로 끌어서 빼야 합니다.
Norton
이것도 Applications에 이미 별도로 들어 있는 제거 도구 앱입니다. Norton의 제거 페이지는 이동 > 응용 프로그램을 거쳐 Norton Uninstaller를 더블클릭하고, "관리자 계정 암호를 입력한 뒤 Install Helper를 클릭"하고, 다시 암호를 입력한 뒤 완료하라고 안내합니다. 이 헬퍼 단계 덕분에 제거 도구가 자체 시스템 수준 구성 요소를 해체할 권한을 얻습니다.
Avast
앱 안에 제거 도구가 있고, 안내 페이지는 뻔한 대안부터 배제하며 시작합니다. "Avast Security를 휴지통으로 옮기거나 Clean My Mac을 쓰는 것으로는 애플리케이션이 완전히 제거되지 않습니다." 문서화된 경로는 메뉴 막대의 Avast Security > Uninstall Avast Security, Continue, 그다음 Mac 시동 암호와 Install Helper입니다. 같은 제거 도구가 Applications에도 Avast Security Uninstaller로 들어 있어서, 앱이 열리지 않을 때 쓸 수 있습니다.
Bitdefender
끌어다 놓는 대신 전용 제거 도구 바이너리를 씁니다. 제거 페이지는 Bitdefender 폴더를 열고 Bitdefender Uninstaller를 더블클릭한 뒤, 제품에 체크하고 Uninstall을 클릭하고, 관리자 이름과 암호를 입력하라고 안내합니다. 같은 과정에서 Bitdefender VPN도 함께 제거할지 물어보는데, 계속 쓸 게 아니라면 받아들이는 게 좋습니다. 그 구성 요소도 자체 네트워크 확장 기능을 등록해두기 때문입니다.
Malwarebytes
앱 안 메뉴 항목으로 제거합니다. 제거 문서는 메뉴 막대의 Help > Uninstall Malwarebytes, 확인 알림, Mac 암호 순으로 안내합니다. 이 분야치고는 특이하게, 같은 페이지가 Finder를 통한 제거도 인정하는데, 이건 제조사가 자기 설치 흔적에 대해 스스로 내린 판단입니다. 예전 support.malwarebytes.com의 제거 문서는 지금 리디렉션되니 help.malwarebytes.com 페이지를 쓰세요.
Sophos
제품이 둘이고, 답도 둘입니다. 소비자용인 Sophos Home은 Spotlight에서 실행하는 별도의 Remove Sophos Home 앱을 씁니다. 페이지는 대안에 대해 단호합니다. "Sophos Home을 휴지통으로 끌어다 놓지 마세요. 그렇게 하면 프로그램이 제거되지 않습니다." 헬퍼를 설치하고, 암호를 요구하고, 재시작이 필요합니다. 같은 페이지에는 이후 Sophos 시스템 확장 기능을 제거하는 선택 섹션도 있는데, 이 절차는 systemextensionsctl uninstall을 시스템 무결성 보호를 끄고 다시 켜는 사이에 끼워 넣습니다. 경계가 어디에 있는지 가장 명확하게 보여주는 대목입니다. 제조사 자체 제거 도구조차 항상 자기 확장 기능까지 함께 가져가지는 않는다는 겁니다. 이 단계들은 제조사가 명시한 그대로 선택 사항이고, SIP는 켜둔 채로 두는 게 좋습니다.
관리형 제품인 Sophos Endpoint는 Launchpad에서 Remove Sophos Endpoint를 쓰지만, 문서에 조건이 붙어 있습니다. "탬퍼 보호가 켜져 있으면 Sophos Endpoint를 제거하기 전에 먼저 꺼야 합니다." 이건 Sophos Central 관리자나 해당 콘솔에 있는 기기별 암호가 필요하니, 회사용 Mac에서는 사용자가 직접 할 수 있는 작업이 아닙니다.
Kaspersky
앱 안의 지원 패널을 통해 제거합니다. 제거 페이지는 Help > Support, Uninstall, 다시 Uninstall, 그다음 관리자 자격 증명 순으로 안내하고, Chrome과 Firefox 확장 기능은 앱이 사라져도 남는다고 경고합니다. Kaspersky는 앱 안 경로가 실패할 때를 대비해 kavremover-mac이라는 별도 제거 도구도 공개하고 있습니다. 두 페이지 모두 2024년 날짜가 찍혀 있으니 여러분의 버전에 맞는지 확인하세요.
Mac이 관리 대상이라면, 답은 IT 팀에 있습니다
저녁 시간을 통째로 여기 쏟기 전에, 애초에 이게 여러분이 결정할 수 있는 문제인지부터 확인하세요.
profiles status -type enrollment
profiles list
첫 번째는 관리자 권한 없이도 DEP와 MDM 등록 상태를 출력하고, 두 번째는 여러분 사용자에게 설치된 구성 프로필을 나열합니다. 같은 정보가 시스템 설정 > 일반 > 기기 관리에도 나타납니다. Apple의 기기 관리 안내는 그다음에 대해 분명하게 말합니다. "일부 프로필은 Mac의 시스템 관리자만 제거할 수 있습니다. 프로필을 제거할 수 없다면 Mac이 관리 대상 컴퓨터일 수 있습니다."
관리 대상 Mac에서는 보안 소프트웨어가 그 관리 체계의 페이로드입니다. 로컬에서 제거해도 프로필이 다시 설치해버립니다. 탬퍼 보호를 로컬에서 꺼보려 해도 할 수 없습니다. 암호가 여러분에게 없는 콘솔 안에 있기 때문입니다. IT 팀에 할당을 해제해달라고 요청하세요.
제거됐는지 확인하기
바로 여기서 절반만 끝난 제거를 큰 대가 없이 잡아낼 수 있습니다. 제조사 제거 도구가 끝나고 Mac이 재시작된 뒤에 하세요. 이 확인 중 몇 가지는 부팅을 거쳐야만 진실을 말해주니까요.
1. 시스템 확장 기능.
systemextensionsctl list
아무것도 설치되지 않은 Mac이라면 출력은 0 extension(s) 한 줄뿐입니다. 그렇지 않다면 각 행이 팀 식별자, 확장 기능의 번들 식별자, 버전, 대괄호로 묶인 상태를 보여줍니다. 제거한 제조사의 식별자가 여전히 남아 있다면 비활성화가 끝나지 않은 겁니다. 이 도구는 systemextensionsctl uninstall <teamID> <bundleID>도 제공하고 몇몇 제조사는 정확히 이런 경우를 위해 이걸 문서화해두지만, 제조사 페이지가 그렇게 하라고 안내할 때만 쓰세요.
2. launchd 등록. 세 위치 모두에서 제조사의 label을 찾아본 뒤, launchd에게 실제로 뭐가 로드돼 있는지 물어보세요.
ls -la /Library/LaunchDaemons /Library/LaunchAgents ~/Library/LaunchAgents
launchctl list | grep -i vendorname
sudo launchctl list | grep -i vendorname
launchctl list 두 호출은 서로 다른 질문에 답합니다. 첫 번째는 여러분의 로그인 세션을, 두 번째는 root 데몬이 사는 시스템 도메인을 다룹니다. 로드된 작업과 매칭되지 않는 남은 plist는 오래된 잔여물이고, plist 없이 로드된 작업은 재부팅이 필요한 Mac이며, 둘 다에 있는 작업은 소프트웨어가 여전히 실행 중이라는 뜻입니다. Mole은 같은 세 위치를 하나의 목록으로 보여주는데, 다음 섹션에서 다룹니다.
3. 네트워크 필터. 등록된 콘텐츠 필터는 시스템 설정 > 네트워크에 Filters 항목으로 나타나니, 항목이 없으면 아무것도 등록돼 있지 않은 겁니다. 앱이 사라진 뒤에도 여전히 목록에 남아 있는 게 연결을 망가뜨리는 범인입니다.
4. 로그인 항목 및 확장 프로그램. 시스템 설정 > 일반 > 로그인 항목 및 확장 프로그램을 열고 로그인 목록과 그 아래 백그라운드 항목을 둘 다 읽어보세요. 제조사 구성 요소는 여기서 앱보다 오래 살아남는 경우가 흔합니다.
5. 실행 중인 프로세스. Activity Monitor에서 제조사 이름을 검색하고 보기 메뉴에서 모든 프로세스로 전환해서 root가 소유한 데몬도 포함시키세요. 재시작 후 결과가 비어 있다면 원하는 확인이 끝난 겁니다.
6. 영수증. pkgutil --pkgs | grep -i vendorname는 설치 프로그램이 뭘 썼는지 알려주는데, 활성 구성 요소가 사라진 뒤 ~/Library/Application Support 아래에서 검토할 가치가 있는 경로를 알려줍니다.
처음 세 가지 확인이 깨끗하다면 제품은 기기에서 완전히 빠진 것이고, 남은 건 동작이 아니라 그냥 디스크 공간일 뿐입니다.
여기서 Mole이 하는 일과 하지 않는 일
Mole의 Software 탭은 앱 목록과 시작 항목을 한 화면에 담고 있으니, 제품이 등록한 launch agent, launch daemon, 로그인 항목을 그걸 등록한 앱 바로 옆에서 실제 경로와 함께 볼 수 있습니다.
잔여물에 대해서는 Mole이 이름이 아니라 번들 식별자로 매칭하며, 알고 있는 시스템 수준 경로는 위에서 본 것들입니다. /Library/LaunchDaemons/<bundle-id>.plist, /Library/LaunchAgents/<bundle-id>.plist, /Library/PrivilegedHelperTools/<bundle-id>, /private/var/db/receipts 아래의 영수증. 시스템 수준의 모든 매칭은 검토 확신도로 취급되어, 즉 선택 해제 상태로 나타납니다. 미리 체크된 목록에서 빼는 게 아니라, 읽어본 뒤 각 경로를 직접 선택해서 넣는 방식입니다. 삭제는 휴지통으로 가서 실수하면 그냥 도로 꺼내면 되고, 건너뛴 것과 실패한 것도 보고되며, 모든 작업은 로컬에서만 이뤄집니다.
이 모든 것보다 중요한 건 두 가지 거부입니다. Mole은 제거 중인 앱이 소유한 확장 기능을 찾으려고 /Library/SystemExtensions를 스캔하고, 하나라도 찾으면 그 확장 기능의 이름을 밝히며 앱이 사라진 뒤에도 남을 수 있다고 알려주는 주의 사항을 띄웁니다. 비활성화는 시도하지 않습니다. 할 수가 없기 때문입니다. 그 요청은 소유 앱에서 나와야 합니다. 그리고 ESET, CrowdStrike, SentinelOne, Jamf, Palo Alto GlobalProtect, Cisco Secure Client를 포함해 잠겨 있거나 관리 대상이거나 조각조각 제거하면 위험한 제품을 만드는 제조사에 대해서는, Mole은 아예 제거를 거부하고 제조사의 공식 제거 도구를 안내합니다.
이 경계가 이 페이지의 나머지 내용을 신뢰할 수 있게 만들어주니, 에두르지 않고 그대로 밝힙니다. Mole은 악성코드 대응 도구도, 백업 도구도 아니고, 드라이버나 VPN 구성 요소, 시스템 확장 기능을 함께 설치하는 소프트웨어에는 제조사 제거 도구를 대체할 수 없습니다. 백신에 대해서는 제조사 제거 도구가 끝난 뒤부터가 Mole의 일입니다. 터미널에서는 무료 오픈소스인 Mole CLI가 mo uninstall로 같은 검토를 다루고, 파괴적인 명령어마다 --dry-run이 있어서 먼저 경로 목록을 읽을 수 있습니다.
자주 묻는 질문
백신을 지웠더니 인터넷이 안 돼요. 어떻게 해야 하나요?
거의 확실히 앱보다 오래 살아남은 네트워크 필터 설정 때문입니다. 이건 Network Extension 환경설정 안에 있고, 이 프레임워크는 번들과 무관하게 독자적으로 관리되기 때문에, 앱을 지워도 더 이상 존재하지 않는 provider를 가리키는 필터가 활성화된 채로 남습니다. 시스템 설정 > 네트워크에서 Filters 항목을 확인하고 systemextensionsctl list로 살아남은 확장 기능이 있는지 확인하세요. 해결책은 제조사 제품을 다시 설치하고 자체 제거 도구를 실행하는 겁니다. 지우려던 소프트웨어를 다시 설치한다는 게 이상하게 느껴지겠지만, 그래도 가장 빠른 길입니다.
/Library/LaunchDaemons 안의 plist를 그냥 지워도 되나요?
첫 번째로 할 일은 아니고, 마지막으로 할 일이 되는 경우도 드뭅니다. 거기 있는 plist는 launchd에 대한 등록 정보라, 작업이 로드된 상태에서 파일을 지우면 디스크에는 아무 설명도 남지 않은 채 다음 재부팅까지 작업이 계속 실행됩니다. 제조사 제거 도구가 실행되고, Mac이 재시작되고, sudo launchctl list에서 매칭되는 로드된 작업이 보이지 않는다면, 남은 plist는 활성이 아닌 잔여물입니다. 아직 설치돼 있는 소프트웨어에 속하는 plist는 절대 지우지 마세요.
제조사 제거 도구가 암호를 요구하고는 실패해요. 이제 어떻게 하나요?
세 가지를 확인하세요. Mac이 관리 대상인지, 그렇다면 탬퍼 보호나 프로필이 제거를 막고 있는 것이고 답은 IT입니다. 제품이 여전히 실행 중인지, 일부 제거 도구는 자체 데몬이 파일을 붙잡고 있는 동안에는 끝낼 수 없으니 재시작하고 다시 시도하세요. 그리고 제거 도구가 최신인지, 일부 제조사는 앱 안 경로와 별개로 독립 실행형 제거 도구를 따로 공개합니다. 셋 다 문제없다면 다음 단계는 제조사 지원팀입니다.
지워졌는지 확인하기 전에 재시작해야 하나요?
네. 확장 기능 해체와 launchd 등록 해제 둘 다 부팅을 거쳐야 완료됩니다. 그러니 제거 도구가 끝나자마자 바로 확인하면 이미 사라지기로 예정된 잔여물이 보일 수도 있고, 반대로 다시 돌아올 데몬이 안 보이게 가려질 수도 있습니다.
관련 글
- Mac에서 앱 완전히 제거하기: 일반적인 순서, 번들 식별자, 공유 컨테이너.
- Mac 앱 제거 후 남은 파일 지우기: 활성 구성 요소가 사라진 걸 확인한 뒤의 잔여물.
- Mac 정리 도구가 절대 지우면 안 되는 것: 같은 판단의 반대편.