리눅스 바이너리 분석 [리눅스 바이너리와 메모리 해킹 매뉴얼]
- 원서명Learning Linux Binary Analysis (ISBN 9781782167105)
- 지은이라이언 오닐(Ryan “elfmaster” O’Neill)
- 옮긴이김창엽, 강민철
- ISBN : 9788960779136
- 30,000원
- 2016년 09월 23일 펴냄 (절판)
- 페이퍼백 | 320쪽 | 188*235mm
- 시리즈 : acorn+PACKT
판매처
- 현재 이 도서는 구매할 수 없습니다.
책 소개
소스 파일은 아래 깃허브 페이지에서 내려 받으실 수 있습니다.
(https://github.com/AcornPublishing/linux-binary)
요약
이 책은 리눅스 바이너리 분석에 꼭 필요한 지식을 예제를 통해 쉽게 설명한다. 리눅스 환경에서 사용할 수 있는 기본 도구와 환경, ELF 바이너리 포맷부터 리눅스 프로세스 추적에 필요한 기술까지 리눅스 바이너리 분석을 처음 접하는 독자들이 쉽게 배울 수 있도록 구성돼 있다. 리눅스 바이너리 보호와 메모리 포렌식, 커널 해킹 기술과 같이 난이도가 높은 내용도 다루고 있어 현업에서 분석 업무를 수행하는 보안 전문가들에게도 큰 도움이 될 만한 지침서다.
이 책에서 다루는 내용
■ ELF 바이너리 포맷 원리
■ 유닉스 바이러스 감염과 분석 방법
■ 바이너리 강화와 소프트웨어 안티 변조 방법
■ 실행 파일과 프로세스 메모리 패치
■ 악성코드에서 사용하는 안티 디버깅 방법 우회
■ 실행 파일에 대한 고급 포렌식 분석
■ C 언어로 작성된 ELF 도구 개발
■ ptrace를 사용한 메모리 조작
이 책의 대상 독자
소프트웨어 엔지니어거나 리버스 엔지니어라면 리눅스 바이너리 분석을 배울 필요성을 느낄 것이다. 이 책은 보안, 포렌식, 안티바이러스 분야 등에 관한 대부분의 정보를 제공한다. 그뿐만 아니라 보안 전문가와 시스템 레벨 엔지니어에게도 도움이 된다. C 프로그래밍 언어와 리눅스 명령어에 대해 조금이라도 알고 있다면 학습을 시작하기에 충분하다.
이 책의 구성
1장, ‘리눅스 환경과 도구’에서는 리눅스 환경과 이 책에서 사용할 도구에 대해 간략히 설명한다.
2장, ‘ELF 바이너리 포맷’에서는 유닉스와 리눅스 모두에서 주로 사용되는 ELF 바이너리 포맷 컴포넌트에 대해 다룬다.
3장, ‘리눅스 프로세스 추적’에서는 ptrace 시스템 콜을 사용해 프로세스 메모리를 읽고, 코드 인젝션을 위해 메모리에 쓰는 방법을 다룬다.
4장, ‘ELF 바이러스 기술: 리눅스/유닉스 바이러스’에서는 리눅스 바이러스의 과거, 현재, 미래에 대해 다루며, 각각의 기반 기술에 대해 자세히 살펴본다.
5장, ‘리눅스 바이너리 보호’에서는 기본적인 ELF 바이너리 보호 기술을 다룬다.
6장, ‘리눅스 ELF 바이너리 포렌식’에서는 ELF 오브젝트의 어느 부분을 분석해야 바이러스, 백도어, 의심스러운 코드 인젝션을 찾을 수 있는지 알아본다.
7장, ‘프로세스 메모리 포렌식’에서는 실행 중인 프로세스에서 악성코드, 백도어, 의심스러운 코드 인젝션을 찾기 위해서는 프로세스 주소 공간을 어떻게 분석해야 하는지 배운다.
8장, ‘ECFS: 확장된 코어 파일 스냅샷 기술’에서는 심층적인 프로세스 메모리 포렌식 기술인 ECFS 오픈소스 프로젝트에 대해 다룬다.
9장, ‘리눅스 /proc/kcore 분석’에서는 /proc/kcore 분석을 통한 리눅스 커널 악성코드 진단 방법에 대해 다룬다.
목차
목차
- 1장. 리눅스 환경과 도구
- 리눅스 도구
- GDB
- GNU binutils의 Objdump
- GNU binutils의 Objcopy
- Strace
- Ltrace
- 기본 ltrace 명령어
- ftrace
- readelf
- ERESI - ELF 리버스 엔지니어링 시스템 인터페이스
- 유용한 디바이스와 파일
- /proc/<pid>/maps
- /proc/kcore
- /boot/System.map
- /proc/kallsyms
- /proc/iomem
- ECFS
- Linker와 관련된 환경 변수
- LD_PRELOAD 환경 변수
- LDSHOWAUXV 환경 변수
- 링커 스크립트
- 요약
- 리눅스 도구
- 2장. ELF 바이너리 포맷
- ELF 파일 형식
- ELF 프로그램 헤더
- PT_LOAD
- PT_DYNAMIC: 동적 세그먼트에서 사용하는 Phdr
- PT_NOTE
- PT_INTERP
- PT_PHDR
- ELF 섹션 헤더
- .text 섹션
- .rodata 섹션
- .plt 섹션
- .data 섹션
- .bss 섹션
- .got.plt 섹션
- .dynsym 섹션
- .dynstr 섹션
- .rel.* 섹션
- .hash 섹션
- .symtab 섹션
- .strtab 섹션
- .shstrtab 섹션
- .ctors와 .dtors 섹션
- ELF 심볼
- st_name
- st_value
- st_size
- st_other
- st_shndx
- st_info
- ELF 재배열
- 재배열 가능 코드 인젝션을 이용한 바이너리 패치
- ELF 동적 링킹
- 보조 벡터
- PLT와 GOT에 대한 이해
- 동적 세그먼트 다시 보기
- ELF 파서 구현
- 요약
- 3장. 리눅스 프로세스 추적
- ptrace의 중요성
- ptrace 요청
- ptrace 요청 형식
- 프로세스 레지스터 상태와 플래그
- 간단한 ptrace 기반 디버거
- Tracer 프로그램
- 프로세스 어태치 기능을 갖는 간단한 ptrace 디버거
- 고급 함수 추적 소프트웨어
- ptrace와 포렌식 분석
- 메모리에서 찾아야 할 것
- 프로세스 이미지 복원: 메모리에 있는 실행 파일로부터
- 프로세스 실행 파일 복원 도전 과제
- 실행 파일 복원의 문제점
- 섹션 헤더 테이블 추가
- 프로세스 복원 알고리즘
- 32비트 테스트 환경에서 Quenya를 이용한 프로세스 복원
- ptrace를 활용한 코드 인젝션
- 중요하게 살펴봐야 할 간단한 예제
- code_inject 도구 활용
- ptrace 안티 디버깅 기술
- 내 프로그램이 추적되고 있는가
- 요약
- 4장. ELF 바이러스 기술: 리눅스/유닉스 바이러스
- ELF 바이러스 기술
- ELF 바이러스 기술의 연구
- 감염코드는 독립적으로 존재해야 한다
- 문자열 저장 문제
- 감염코드 저장을 위한 공간 찾기
- 감염코드로 실행 흐름 변경하기
- ELF 바이러스 감염 방법
- Silvio 패딩 감염 방법
- 리버스 텍스트 세그먼트 감염
- 데이터 세그먼트 감염
- PTNOTE -> PTLOAD 변경 감염 방법
- PTNOTE -> PTLOAD 변경 감염 알고리즘
- 제어 흐름 감염시키기
- 다이렉트 PLT 감염
- 함수 트램펄린
- .ctors / .dtors 함수 포인터 오버라이팅
- GOT: global offset table 포이즈닝, PLT/GOT 리다이렉션
- 데이터 스트럭처 감염시키기
- 함수 포인터 오버라이팅
- 프로세스 메모리 바이러스와 루트킷: 리모트 코드 인젝션 기술
- 공유 라이브러리 인젝션: .so 인젝션 / ET_DYN 인젝션
- LD_PRELOAD를 이용한 .so 인젝션
- open() / mmap() 셸 코드를 이용한 .so 인젝션
- dlopen() 셸 코드를 이용한 .so 인젝션
- VDSO 조작을 이용한 .so 인젝션
- 텍스트 세그먼트 코드 인젝션
- 실행 파일 인젝션
- 재배열 코드 인젝션: ET_REL 인젝션
- 디버깅과 패킹 기술
- PTRACE_TRACEME 기술
- SIGTRAP 핸들러 기술
- /proc/self/status 기술
- 코드 난독화 기술
- 스트링 테이블 변경 기술
- ELF 바이러스 탐지과 치료
- 요약
- 5장. 리눅스 바이너리 보호
- ELF 바이너리 패커
- Stub 메커니즘과 Userland exec
- 프로텍터 예제
- 스텁에서 수행하는 다른 작업들
- 기존 ELF 바이너리 프로텍터
- DacryFile(Grugq, 2001년)
- Burneye(Scut, 2002년)
- Shiva(Neil Mehta와 Shawn Clowes, 2003년)
- Maya's Veil(Ryan O'Neill, 2014년)
- Maya가 적용된 바이너리 다운로드
- 바이너리 보호를 위한 안티 디버깅
- 에뮬레이션 방어하기
- Syscall 테스팅을 통한 에뮬레이션 탐지
- 에뮬레이터 CPU 불일치를 이용한 탐지
- 명령어 지연 체크
- 난독화 방법
- 제어 흐름 무결성 보호하기
- ptrace 기반 공격
- 취약점 기반 공격
- 추가 자료
- 요약
- 6장. 리눅스 ELF 바이너리 포렌식
- 엔트리 포인트 변조 진단
- 컨트롤 플로우 하이재킹 진단
- .ctors(.int_array) 섹션 패치
- PLT/GOT 후킹 탐지
- 함수 트램펄린 진단
- 기생 코드의 특성
- DLL 인젝션 트레이스의 동적 세그먼트 진단
- 리버스-텍스트 패딩 감염 진단
- 텍스트 세그먼트 패딩 감염 진단
- 보호된 바이너리 진단
- 보호된 바이너리 분석
- IDA Pro
- 요약
- 7장. 프로세스 메모리 포렌식
- 프로세스는 어떻게 구성돼 있는가
- 실행 가능한 메모리 매핑
- 프로그램 힙
- 공유 라이브러리 매핑
- 스택, VDSO, VSYSCALL
- 프로세스 메모리 감염
- 프로세스 감염 도구
- 프로세스 감염 기술
- ET_DYN 인젝션 진단
- Azazel 사용자 공간 루트킷 진단
- 프로세스 주소 공간 매핑 확인
- 스택에서 LD_PRELOAD 확인
- PLT/GOT 후킹 진단
- ET_DYN 인젝션 자세히 보기
- VDSO 변조
- 공유 오브젝트 로딩: 정상적인 방법과 비정상적인 방법
- .so 인젝션 진단 휴리스틱
- PLT/GOT 후킹 진단 도구
- 리눅스 ELF 코어 파일
- 코어 파일 분석: Azazel 루트킷
- 요약
- 프로세스는 어떻게 구성돼 있는가
- 8장. ECFS: 확장된 코어 파일 스냅샷 기술
- 역사
- ECFS 철학
- ECFS 소개
- ECFS를 코어 핸들러 플러그인으로 사용하기
- 프로세스를 종료하지 않고 ECFS 스냅샷 생성
- libecfs: ECFS 파일 파싱 라이브러리
- readecfs
- ECFS를 이용한 감염된 프로세스 분석
- 숙주 프로세스 감염
- ECFS 스냅샷 생성 및 분석
- readecfs를 이용한 기생 코드 추출
- Azazel 루트킷 분석
- ECFS 레퍼런스 가이드
- ECFS을 이용한 심볼 테이블 재구성
- ECFS 섹션 헤더
- ECFS 파일을 기본 코어 파일로 사용하기
- libecfs API 사용법
- ECFS를 이용한 프로세스 되살리기
- ECFS 더 살펴보기
- 요약
- 9장. 리눅스 /proc/kcore 분석
- 리눅스 커널 포렌식과 루트킷
- Stock 버전의 vmlinux는 심볼을 가지고 있지 않다
- kdress를 이용한 vmlinux 빌드
- /proc/kcore와 GDB 살펴보기
- syscalltable 위치 조회 예제
- syscalltable 직접 변조
- syscalltable 변조 진단
- 커널 함수 트램펄린 기법
- 함수 트램펄린 예제
- 함수 트램펄린 진단
- 인터럽트 핸들러 패치 진단
- Kprobe 루트킷
- Kprobe 루트킷 진단
- DRR(디버그 레지스터 루트킷)
- DRR 진단
- VFS 레이어 루트킷
- VFS 레이어 루트킷 진단
- 그 외의 커널 감염 기술
- vmlinux와 .altinstructions 패치
- .altinstructions와 .altinstr_replace
- arch/x86/include/asm/alternative.h 살펴보기
- textify를 이용한 코드 정합성 검증
- textify를 이용한 syscalltable 검증 예제
- taskverse를 이용한 프로세스 은닉 진단
- taskverse 기술
- 감염된 LKM: 커널 드라이버
- 방법 1. 심볼 하이재킹
- 방법 2. 함수 하이재킹
- 감염된 LKM 진단
- /dev/kmem과 /dev/mem에 대해
- /dev/mem
- FreeBSD의 /dev/kmem
- K-ecfs: 커널 ECFS
- kernel-ecfs 파일 살펴보기
- 커널 해킹
- 리버스 엔지니어링과 디버깅
- 고급 커널 해킹 및 디버깅 인터페이스
- 이 책에서 언급한 논문
- 요약
도서 오류 신고
정오표
정오표
[p.47]
DT_STRSZ 문자열 테이블 크기
-> 내용 중복 2행 삭제
[p.48 : PT_INTERP 아래 행]
이 섹션은
->
이 세그먼트는
[p.56 : 1행]
readelf -s
->
readelf -S
(섹션 테이블)
[p.56]
섹션 헤더가 12개 있고, 시작 오프셋은 0x124이다.
->
The following are 12 section headers, starting at offset 0 x 124:
[p.57]
섹션 헤더가 30개 있고, 시작 오프셋은 0x1140이다.
->
The following are 30 section headers, starting at offset 0 x 1140:
[p.59 : 4행, 12행]
readelf -s
->
readelf -S
(섹션 테이블)
[p.62]
foochu함수는 0x80480da
->
foochu함수는 0x80480d8
[p.67 : 아래에서 6행]
오브젝트 파일은 재배열 가능 코드이며 실행 파일 내 특정 섹션의 주소에 코드가 재배열된다는 것을 의미한다.
->
오브젝트 파일은 재배열 가능 코드이며, 실행 세그먼트 내 특정 주소 위치로 재배열된다는 것을 의미한다.
[p.67 : 아래에서 3행]
즉 명령어 또는 심볼의 패치 과정은 링커에 의해 실행 파일의 세그먼트 주소가 확정된 이후 수행돼야 한다.
->
실행 세그먼트 내 명렁어나 심볼의 위치는 링커가 확정한 후에 패치해야 한다.
[p.68. : 1행]
재배열 엔트리는 가수 값을 몇 개 요구한다.
->
어떤 재배열 엔트리는 가수값을 요구한다.
[p.68 : 9행]
rinfo는 반드시 수행돼야 하는 심볼 테이블 인덱스
->
rinfo는 재배치 되어야 하는 심볼 테이블 인덱스
[p.68 : 13행]
다음에서 설명할 오브젝트 파일은 32비트로 컴파일될 것이며, 따라서 암시적 가수를 사용한다.
->
암시적 가수를 설명하기 위해서 다음 예제에서는 오브젝트 파일 코드를 32비트로 컴파일할 것이다.
[p. 68]
암시적 가수는 재배열 레코드가 ElfNRel에 존재해지만 raddend필드가 없는 경우에 동작하게 된다.
->
암시적 가수는 재배열 레코드가 raddend 필드가 없는 ElfNRel에 존재하는 경우에 동작하게 된다.
[p.71: 3행]
0x80480e8 + ( ... )
->
0x80480e8 - ( ... )
[p.73 : 5행]
[p.76]
" ... 유사하지만 프로그램 인터프리터에 의해 직접 실행되지 않고 자동으로 로드만 되기 때문에 PTINTERP로 설정돼 있다."
->
" ... 유사하지만 일반적으로 PTINTERP 세그먼트를 가지고 있지 않는데, 이는 프로그램 인터프리터에 의해 로드되는 것이지 프로그램 인터프리터를 호출하는 것이 아니기 때문이다.
[p.93]
POKTEXT
->
POKETEXT