🤛🏽

샌드박스 무결성 검사 - fork() - 잘못알려짐

 
 

ios 디렉토리 구성

 
ios 앱 경로는 크게 두가지다.
1. 앱 샌드박스 내에 설치
기본적으로 서드파티 앱들은 신뢰할 수 없다고 가정하고 다양한 기능을 제한함. (앱스토어 앱)
 
2. 루트 파티션의 애플리케이션 폴더에 설치 ( /Applications )
기본 탑재 앱은 샌드박스 없이 루트 경로 아래인 /Applications 에 설치된다. (샌드박스의 제한을 받지 않는다.)
물론 Cydia 등에서 받은 앱들도 웬만하면 굳이 샌드박스에 설치되지 않고 /Applications에 설치한다.
 

샌드박스 무결성 검사 ( "X" - 잘못 알려진 내용 )

 
알려진 내용 : 샌드박스에선 fork()가 금지된다.
따라서 fork()가 제대로 동작한다면 샌드박스 제한을 받지 않는 상태다!
--> 샌드박스 밖에 설치됐거나, 샌드박스 자체가 무력화 된 상태 (즉, 탈옥상태)
int result = fork(); if(!result) //자식이 수행할 코드 //바로 종료 (그냥 확인용이니까) exit(0); if(result >= 0) //fork가 성공하여 result에 자식의 pid값이 담긴다면 { #if TARGET_IPHONE_SIMULATOR NSLog(@"fork executed on the simulator!); //시뮬레이터에선 탈옥이 아니더라도 fork()먹힘. return 0; #else return 1; //탈옥된 상태 #endif } return 0; //일반적인 경우
자식은 result=0이 담긴다.
부모는 자식 프로세스 생성 성공 시 result에 자식의 pid값이 담기고, 아니라면 0이 담긴다.
 
테스트했던 코드
static inline int sandbox_intergrity_compromised(void) __attribute__ ((always_inline)); int sandbox_intergrity_compromised(void) { int result = fork(); if(!result){ //자식은 바로 종료시키고 (생성되는지 확인만 하는 용도이므로) NSLog(@"hello I'm child"); exit(0); } if(result >= 0){ //fork 결과 0이 아닌 자식의 pid가 담겼다면 탈옥이다! wait(0); NSLog(@"child pid : %d", result); return 1; } NSLog(@"fork not executed"); return 0; }

하지만

테스트를 해보면 /Applications 아래에서 샌드박스 제한을 받지 않고도 fork()가 먹히지 않는다.
물론 샌드박스 내에서 실행해도 fork()가 먹히지 않는다.
 

결론

시뮬레이터로 실행했는지가 반환될 뿐 탈옥탐지에는 효과가 없다.
 

우회

알려진 대로 제대로 동작한다고 했을 때 우회 방법도 정리하자.
fork() 함수를 후킹하여 항상 -1가 반환되도록 하면 끝.
 

참고문서