volafox project: Gathering network information in Mac OS X memory image

FreeBSD의 네트워크 정보 추출을 베이스로하여 Mac OS X의 네트워크를 구현하였는데 여러가지 차이점이 존재합니다. 애플도 BSD커널을 그대로 사용하진 않았네요.ㅎ
우선 Mac OS X의 네트워크 정보는 커널 심볼 중 '_tcbinfo'와 '_udbinfo'에 존재합니다. 심볼 이름은 유사하지만, 큰 차이점은 두 심볼이 64비트 주소체계를 가지고 있기 때문에 volatility의 32비트 분석모듈로는 데이터 분석이 올바르게 되지 않습니다

n0fates-MacBook-Pro:volafox_0.6_beta1_fixed1 n0fate$ nm /mach_kernel | grep tcbinfo
ffffff800088af60 S _tcbinfo
n0fates-MacBook-Pro:volafox_0.6_beta1_fixed1 n0fate$ nm /mach_kernel | grep udbinfo
ffffff800088b5c0 S _udbinfo
n0fates-MacBook-Pro:volafox_0.6_beta1_fixed1 n0fate$

(사실 32비트 주소 변환 테이블에 돌려도 되긴합니다. 맥의 심볼 정보에선 64비트 주소체계더라도 PML4 형식에 맞춰 하위 48비트 주소를 이용하는데, 이 중 상위 16바이트는 사실상 없어도 크게 문제가 없는 듯 합니다. 아무래도 커널 자체가 32비트로 로딩되다보니, 32비트 페이지맵과 64비트 페이지맵 둘다 맵핑 가능하도록 구현된 것 같습니다.)

<PML4의 페이지 맵핑 구조>


여튼 이러한 점이 존재하여 공식적으론 PML4로 맵핑하여 분석해야합니다. volafox에는 프로세스 덤프 때문에 구현한 PML4 주소변환테이블 파싱모듈이 있기 때문에 이 부분은 쉽게 해결하였습니다.

FreeBSD 메모리에서 네트워크 정보를 추출할 때 언급한적이 있지만, 네트워크 정보는 리스트 형태의 정보와 해시테이블형태로 관리되고 있습니다. BSD의 경우 inpcb 구조체 상의 리스트 정보를 조작하여, 네트워크 정보를 은닉할 수 있었지만, 해시 테이블을 제거할 경우 네트워크 세션자체가 단절되어버리기 때문에, 해시테이블을 이용하면 루트킷의 은닉 기법을 회피하여 정보를 획득할 수 있었습니다. 이는 맥에서도 BSD 컴포넌트를 통해 동일한 형태(?)로 접근가능하도록 되어 있습니다. 아래 그림은 맥 운영체제의 해시테이블의 구조입니다.

처음에 언급한 심볼인 '_tcbinfo','_udbinfo'는 실제로 inpcbinfo구조체로 되어 있으며, 해당 구조체 중 첫 번째 4바이트 포인터가 해시테이블을 가리키고 있습니다. 그리고 구조체의 8바이트 뒤에 위치한 hashmask가 해시 테이블의 갯수를 나타냅니다. 해시 테이블을 기본적으로 4바이트 크기를 가지고 있습니다.

  430 struct inpcbinfo {              /* XXX documentation, prefixes */
431 struct inpcbhead *hashbase;
432 #ifdef __APPLE__
433 u_int32_t hashsize; /* in elements */
434 #endif
435 u_long hashmask; /* needs to be u_long as expected by hash functions */
436 struct inpcbporthead *porthashbase;
437 u_long porthashmask; /* needs to be u_long as expected by hash functions */
438 struct inpcbhead *listhead;
439 u_short lastport;
440 u_short lastlow;

(reference: http://fxr.watson.org/fxr/source/bsd/netinet/in_pcb.h?v=xnu-1456.1.26#L426)

두 번째 문제는 이 해시테이블을 통한 정보 추출에서 해시셋의 크기까지는 올바르게 나오는 것 같은데 해당 정보를 기반으로 데이터를 추출하면 실제 존재하는 세션 갯수보다 적은 수를 추출하는 문제가 발생합니다.

n0fates-MacBook-Pro:volafox_0.6_beta1_fixed1 n0fate$ python volafox.py -i mem.mem -s mach_kernel -o net_info

Memory Image: mem.mem
Kernel Image: mach_kernel
Information: net_info


-= NETWORK INFORMATION (hashbase) =-
ipi_count: 11
[fusion_builder_container hundred_percent="yes" overflow="visible"][fusion_builder_row][fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"][TCP] Local Address: 0.0.0.0:22, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 172.16.43.135:53, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 127.0.0.1:54, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 172.16.43.135:22, Foreign Address: 172.16.43.1:49422, flag: 8000
[TCP] Local Address: 0.0.0.0:311, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 0.0.0.0:625, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 127.0.0.1:631, Foreign Address: 0.0.0.0:0, flag: 8000
[TCP] Local Address: 172.16.43.135:22, Foreign Address: 172.16.43.1:52918, flag: 8000
ipi_count: 35
[UDP] Local Address: 0.0.0.0:53232, Foreign Address: 127.0.0.1:0, flag: 40088000
[UDP] Local Address: 0.0.0.0:55297, Foreign Address: 0.0.0.0:0, flag: 808300
[UDP] Local Address: 0.0.0.0:59490, Foreign Address: 0.0.0.0:0, flag: 808300
[UDP] Local Address: 0.0.0.0:62853, Foreign Address: 0.0.0.0:0, flag: 808300
[UDP] Local Address: 0.0.0.0:60439, Foreign Address: 127.0.0.1:0, flag: 40088000
[UDP] Local Address: 0.0.0.0:65241, Foreign Address: 0.0.0.0:0, flag: 808300
[UDP] Local Address: 127.0.0.1:60762, Foreign Address: 0.0.0.0:0, flag: 8000
[UDP] Local Address: 17
2.16.43.135:123, Foreign Address: 17.83.253.7:0, flag: 8000

[UDP] Local Address: 0.0.0.0:63852, Foreign Ad
dress: 0.0.0.0:0, flag: 808300

[UDP] Local Address: 0.0.0.0:51326, Foreign Address: 0.0.0.0:0, flag: 808300

출력된 정보 중 ipi_count가 실제 세션의 갯수입니다. 이 갯수는 실제로 맥에서 netstat 명령으로 출력된 세션 정보와 동일합니다. 밤에 두시간 삽질을 해보긴 했는데 왜 실제보다 적은 데이터를 추출하는지에 대해서는 문제의 원인을 정확히 찾지 못하고 있습니다.
좀더 확인해보고 정 안되겠다 싶으면 리스트 기반의 정보 추출을 병행하도록 구현하는 수 밖에 없을 것 같습니다(아직 이 방법으로도 올바르게 추출되는지는 확인못했습니다).

아마 본 작업이 완료되면, volafox alpha2라는 이름으로 릴리즈 될 것 같습니다. 요즘들어 업데이트가 많이 느려졌네요 ㅎㅎ.

다들 좋은 저녁되시기 바랍니다!

n0fate's Forensic Space :)

[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]