day3. 4.5
데몬
데몬은 백그라운드 프로세스인데, 유저의 인터랙티브 세션이 필요하지 않다.
기기가 부팅될때 실행되고 필요하다면 종료할 수 있음. 주로 시스템레벨에서 동작하며 기기 작동에 필수적인 작업을 함. (네트워크서비스관리, 시스템유지보수, 바이너리코드서명 확인 등
에이전트
에이전트는 특정 앱이나 서비스를 대신해서 실행되는 백그라운드 프로세스. 사용자가 앱을 실행하거나 이벤트가 발생할때 시스템이 실행해주기도 한다. 위치정보서비스 같은 경우 백그라운드에서 위치정보가 필요한 앱들에게 전달해줌. iCloud 사진 보관함 에이전트는 백그라운드에서 사진과 비디오를 기기와 사용자의 아이클라우드 계정 간 동기화하는 역할을 한다.
아래폴더의 데몬과 에이전트는 시스템 부팅시에 로드되고 명시적으로 중단되지 않는 한 시스템 종료시까지 실행된다.
/Library/LaunchAgents, /Library/LaunchDaemons,
/System/Library/LaunchAgents, /System/Library/LaunchDaemons,
https://theapplewiki.com/wiki/Signed_System_Volume
SSV(Signed System Volume) 때문에 볼륨 자체를 변경할 수 없다. 설치할때 해시값을 파일시스템에 저장하고, 부팅될때 해시값이 다르면 복구모드로 진입된다.
공격지속성을 방지하기 위함이다. 누군가가 해킹에 성공하고 데몬이나 에이전트 폴더에 악성 프로그램을 넣는다면 지속적으로 부팅시마다 해킹이 될것임. 그래서 서명해서 변경되지 않게한다.
데몬리스트확인
ps -e | grep '[d]$'
launchctl list | grep '[d]$' | grep -v "-" # d로 끝나고 -가 포함된거(실행중이 아니라면 pid위치에 - 가 출력됨) 제외
launchctl: launchd 데몬에게 물어보는거고 데몬을 실행하거나 중지하기도하고 모든 서비스와 데몬을 알려주기도 한다.
lsof # 모든 파일핸들 출력
lsof -p <pid> # 해당 프로세스의 열린 파일핸들이 표시된다.
lsof /path/to/file # 해당 파일을 참조하는 프로세스가 표시된다.
lsof +D /path/to/directory # 디렉터리 내부 모든 파일에 해당하는 프로세스들
fsmon 파일시스템 변경사항 모니터링 (파일생성, 변경, 삭제, 메타데이터 변경)
ldid -S <바이너리> 자체서명
실행하면 kill 당함
루팅방식에 따라서 /var/jb/usr/bin 하위폴더에서만 바이너리 실행이 가능할 수 있다.
데몬 : 백그라운드 프로세스로 실행되는 프로그램 사용자 세션에서 실행되는게 아니라 주로 기기가 부팅될때 시작되며 시스템레벨 서비스로 동작한다. (네트워크 서비스 관리, 시스템유지보수, 바이너리 코드서명확인)
vs
에이전트 : 특정 앱이나 서비스를 대신해서 실행하는 백그라운드 프로세스 보통 사용자가 앱을 실행하거나 이벤트가 발생했을때 시스템에의해 실행된다. 위치정보서비스: 백그라운드에서 실행되면서 앱이나 서비스가 위치정보가 필요할때 줌 사진보관함 에이전트: 기기와 icloud 계정간 동기화
다른경로에 저장된다. /Library/LaunchAgents /Library/LaunchDaemons /System/Library/LauchAgents /System/Library/LaunchDaemons
DEAMON과 AGENT는 동작은 동일하다.
DAEMON 시스템 부팅 시 커널이 뜬 후 시스템 초기화 단계에서 launchd 가 실행된다. 이후 /System/Library/LaunchDaemons 와 /Library/LaunchDaemons/ 의 plist를 읽어서 데몬이 요청한 소켓/FD를 미리 등록한다. keepalive 옵션이 설정된 대몬을 먼저 띄우고 나머지 대몬은 서비스 요청이 왔을때 띄워서 처리하게한다. 시스템 종료 시 모든 대몬에게 SIGTERM을 보낸다.
AGENT 로그인시 유저마다 launchd가 실행되고 /System/Library/LaunchAgents, /Library/LaunchAgents, ~/Library/LaunchAgents를 읽어서 이후부터는 위와 동일함 로그아웃 시 모든 AGENT에게 SIGTERM 보냄.
launchd 로 실행시키려면 위의 폴더에서 plist를 등록해두면 된다. job의 식별자, 실행할 프로그램과 인자, 소켓FD, on-demand/keepalive … 주기나 파일변경 트리거도 가능
plist는 대몬 에이전트 모두 구조가 동일함
Label은 Job의 ID일 뿐이고, array에 전달되는게 argv로 보면된다. 예시에서는 hello 프로그램(argv[0])을 실행시키면서 world 라는 인자(argv[1])를 넘긴다.
소켓이나 이벤트는 plist에 정의해두면 launchd가 알아서 bind/listen/open 해두고 프로그램에서는 전달받은 fd 로 accept, read, write 하기만 하면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.hello</string>
<key>ProgramArguments</key>
<array>
<string>hello</string>
<string>world</string>
</array>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
자세한건 문서에 있음
SIGTERM은 시스템이 보내는 종료요청이고 agent나 daemon이 받으면 특정 작업(정리로직) 후 안전하게 종료할 수 있다.
SSV(Signed System Volume)때문에 /SYSTEM 볼륨은 에이전트와 데몬을 변경할 수 없음 이 폴더에 plist 를 추가할 수 없음 이건 지속성을 방지하기 위한 목적이다.
/System이 아닌곳에는 추가할 수 있는데 쓰기권한을 얻어야 가능하다. <실제 캡쳐한 사진>
실제로 테스트해보면 좋을듯 ~/Library/LaunchAgents 는 유저권한으로도 맘대로 쓸수있는것같은데 민감기능은 TCC 승인이필요함 <테스트해봄년 좋을듯>
공격자 입장에서는 이미 등록된 데몬이나 에이전트를 변조하거나 폴더에 맘대로 넣어둘 수 있을텐데, 실행 조건이나 지속성 여부를 참고할 수 있다.
방어자 입장에서는 각 데몬이나 에이전트가 어떤 행위를 할지 어느정도 확인이 가능함.
launchctl/lsof 은 launchd에 어떤 job들이 등록되어 있는지 확인하기 좋음. 그리고 그 job이 원하는 방향으로 동작하고 있는지 확인하기 좋다.
데몬을 확인하는 방법 launchctl 은 iOS의 마스터 데몬인 launchd와 상호작용하여 서비스들을 관리하는 명령어이다. d로 끝나는 프로세스(데몬) 을 출력하고 PID에 “-” 이 포함된건 제거해서 실행 중인 데몬만 출력하는명령 launchctl list | grep ‘[d]$’ | grep -v “-”
launchd 는 그럼 다른거ㄴ 더 안하나? 나머지는 누구지? 모든서비스? 그럼 launchd는 init같은건가?
특정 데몬의 열린 핸들을 식별하는 방법 식별하려 하는 이유: lsof -p 746
특정 프로세스에 대해 현재 열려있는 파일에 대한 정보를 표시하ㅓ기위해 사용되는 명령어이다
반대로 파일을 참조하는 모든 프로세스 확인 lsof /path/to/file lsof +D /path/to/directory