'll Hacker
[EVI$ION 프로젝트 세션] iptime 펌웨어 분석 본문
개념 설명
펌웨어? 컴퓨팅과 공학 분야에서 특정 하드웨어 장치에 포함된 소프트웨어로, 소프트웨어를 읽어 실행하거나, 수정하는 것도 가능한 영구적 소프트웨어를 뜻한다.
[펌웨어 대략적인 구조]
- boot loader : 하드웨어 부팅에 필요한 기본 요소
- kernel : 운영체제의 커널과 같은 역할을 수행하는 영역
- file system : 펌웨어의 기능이 포함되어 있는 영역
- other : 데이터 저장 공간 등 기타 영역
[펌웨어의 특징]
- 전자기기 등의 기본적인 제어와 구동을 담당한다
- 다른 소프트웨어보다 우선적으로 하드웨어의 기본적인 동작을 제어할 수 있다.
- 펌웨어가 없거나 이상이 생기면 해당 기기는 우리가 흔히 말하는 벽돌이 된다.
- 소프트웨어 기능을 펌웨어로 변경하면 속도가 증가한다
- 하드웨어의 기능을 펌웨어로 변경하면 저렴하고 편리하게 구현이 가능하다.
- EPROM에 기록되며 하드웨어보다는 교환이 쉽지만 소프트웨어에 비해 교환이 어렵다.
실습
1. 장비기능, 동작 파악
- 어떻게 동작하고 어떤 기능이 있는지, 사용법은 어떻게 되는지 파악해야한다.
2. 구성 요소 파악
- 하드웨어, 앱, 클라우드 서비스 등 물리적인 장비 외에도 어떤 서비스들이 엮여있는지 파악해야한다.
3. 취약점 진단
- 2번에서 파악한 구성요소 별로 취약점 진단을 수행한다.
- 웹 해킹, 앱 해킹 등이 포함된다.
4. 모든 분석이 끝나고 더 분석 진행할 것이 없다면 장비를 뜯어본다.
- 대신 다시 정상적인 동작을 할 것이라는 보장은 없음...ㅋㅋ
관련 명령어
binwalk [펌웨어 파일 명]
- 펌웨어 파일 시그니처 분석, default option으로 설정되어있음. 지정해주려면 -B를 써주면 된다.
- 시그니처를 분석하면 데이터와 파일 시스템의 파악이 가능하다.

| 오프셋(Decimal) | 설명 |
| 0 | uImage 헤더 (Linux 커널 이미지) |
| 64 (0x40) | LZMA 압축된 커널 이미지 |
| 51638 (0xC9B6) | Cisco IOS 마이크로코드 |
| 3473408 (0x350000) | SquashFS 파일 시스템 시작 |
1. 0x0 - uImage Header
- uImage는 U-Boot 부트로더에서 사용하는 포맷이다.
- image name : a3004nm - 해당 펌웨어는 아마도 ipTIME A3004NS-M 또는 유사한 라우터 장비용.
- copression : lzma - 압축 포맷.
.LZMA 파일이란?
LZMA(Lempel-Ziv-Markov chain Algorithm) 압축방법을 사용하여 생성된 압축 아카이브 파일이다.
이들은 주로 유닉스 운영체제에서 발견/사용되며 파일 크기를 최소화하기 위해 ZIP와 같은 다른 압축 알고리즘과 유사하다. LZMA는 레거시 파일 형식으로 .xz 형식으로 대체되거나 대체됨.
* 레거시 파일 형식? 이전에 사용되었던 파일 형식
- OS : Linux
- CPU : MIPS - 펌웨어가 MIPS 아키텍처 기반 하드웨어용임을 나타낸다.
2. 0x40 - LZMA Compressed Kernel
- Linux 커널 이미지가 LZMA 압축으로 되어있다.
- dictionary size : 약 32MB - 압축 해제 시 메모리 요구량을 암시한다.
- uncompressed size : 약 9MB (9320640 bytes)
3. 0xC9B6 - Cisco IOS Microcode?
- "Cisco IOS microcide"라는 항목을 흔치 않은데, 정확한 장비가 Cisco가 아니라면 오탐 가능성이 있다.
- binwalk는 문자열이나 시그니처 기반 분석이기 때문에 가끔 이렇게 Cisco 형식으로 잘못 표시되기도 한다.
4. 0x350000 - SquashFS Filesystem
- 압축된 루트 파일 시스템 (rootfs)
- 파일 시스템 종류 : SquashFS v4.0 (일반적인 임베디드 리눅스 펌웨어에서 많이 사용된다)
- 압축 방식 : xz (LZMA 기반의 압축 포맷)
- 크기 : 약 7.8MB (7848270 bytes)
- inode 수 : 1083 (작은 시스템으로 보임)
- 생성일자: 1970-01-01 - 이건 타임스탬프가 설정되지 않았거나, 기본값일 가능성 크다.
binwalk -e [펌웨어 파일 명]
- 펌웨어 파일을 추출하는 옵션으로 [ _펌웨어 파일 명]으로 디렉터리가 만들어진다.


extracted 파일로 이동 - cd ~.extracted

파일시스템 squashfs-root에 이동하면 리눅스 파일시스템과 같다는 것을 볼 수 있다.
내가 살펴볼 디렉터리는 다음과 같다:
1. /etc/passwd, /etc/shadow : 기본 계정/패스워드
2. /home/httpd/, /www/ : 웹 인터페이스
3. /bin, /sbin : 실행파일(BusyBox 포함 여부 확인)
4. /etc/init.d/ : 부팅 시 실행 스크립트
근데 지금 상태에서

오류메시지가 뜨게 된다. 왜냐하면 binwalk -e로 펌웨어를 추출했을 때 심볼릭 링크(symlink)가 안전하지 않다고 판단돼서 전부 /dev/null로 연결된 상태이다. binwalk는 펌웨어 내부의 심볼릭 링크가 추출 디렉터리 외부를 가리킬 경우, 보안상 위험이 있어서 자동으로 링크를 /dev/null로 바꿔버린다. 왜냐하면 사용자의 시스템 파일이나 중요힌 경로를 실수로 덮어쓰지 않게 하기 위함이다. 지금 etc는 내용이 없는 죽인 링크이다. 그래서 rm etc && mkdir etc는 없던 것을 포기하고 새로 만드는 안전한 선택이다.
binwalk -A [펌웨어 파일 명]
- 펌웨어의 아키텍처를 분석하는 명령어이다.
- ARM 또는 MIPS 등의 어셈블리 코드 시그니처를 찾아주는 기능이야. 즉, 펌웨어 안에 있는 실행코드의 함수 시작점(prologue) 등을 분석하는데 사용도니다.

1. ARM / ARMEB?
- ARM : ARM 아키텍처에서 리틀 엔디언 방식
- ARMEB : ARM 아키텍처에서 빅 엔디언 방식
즉, 해당 펌웨어는 ARM 기반 코드가 포함되어 있으며, 일부 빅 엔디언 방식으로 저장된 걸로 보인다.
2. Function Prologue란?
- 함수 프로로그는 함수 진입 시 수행되는 초기화 코드 부분
- 보통 push {fp, lr} 같은 스택 저장이나 프레임 설정 명령이 나타남.
- binwalk는 시그니처 매칭을 통해 이런 부분을 찾아서 실행가능한 바이너리 블록의 위치를 알려주는 것.
binwalk -E [펌웨어 파일명]
데이터 엔트로피를 분석하는 기능이다. 엔트로피 분석으로 기대할 수 있는 것은 저장소의 어떤 부분을 이용하고 있는지 파악이 가능하고, 암호화 유무를 확인할 수 있다.
데이터 엔트로피?
데이터가 얼마나 무작위적인지를 수치화한 것이다. 예측 불가능성이나 압축 불가능성을 의미한다.
엔트로피가 낮다 - 반복되는 패턴이 많다 - 압축이 잘 된다 - 예측이 가능하다
예: AAAAAAABBBBBBBBBCCCCCCDD → 패턴 많음 → 엔트로피 낮음
엔트로피가 높다 - 무작위처럼 보인다. - 압축이 잘 안된다 - 예측이 어렵다
예: x8@#9v!3aZ&*Q... → 랜덤한 값들 → 엔트로피 높음


X축 (Offset) : 펌웨어 파일 내 바이트 위치
Y축 (Entropy) : 0~1 사이의 무작위성 정도 (1.0 = 매우 무작위함, 0.0 = 완전 반복됨)
[주요 특징 분석]
1. 전반적으로 엔트로피가 1.0에 가까움
- 대부분의 데이터가 압축되어있거나 암호화되어있는 의미이다.
2. 중간쯤 (offset 약 0.35 * 10^7 = 약 3.5MB 근처)에 엔트로피가 0에 가까워진다.
- 여기는 반복되는 패턴이거나 널값(zero-filled), 혹은 고정된 padding 데이터일 수 있음.
- 흔히 \x00\x00\x00... 같은 값들이 영역을 채우는 용도로 쓰일 때 이런 패턴이 나타난다.
3. 마지막 근처에 조금 떨어지는 지점 존재
- offset 약 10MB 근처(1.1e7)에서 엔트로피가 살짝 떨어진다.
- 이건 squashfs 끝부분 padding일 수도 있고, 또는 정적 설정 데이터 (예: HTML, config, 스크립트) 영역일 수도 있다.
중간 지점(offset 0x350000 근처) 내용을 hexdump로 보고 싶다면 아래 명령어로 확인가능:
hexdump -C -n 256 -s 0x350000 a3004nm_ml_15_070.bin

68 73 71 73 3B 04 00 00 00 08 00 00 ...
68 73 71 73 - ASCII로 hsqs - 이건 SquashFS의 매직넘버이다.
hsqs(0x68737173) - SquashFS를 little-endian으로 저장한 값이다.
즉, 여기부터 진짜 SquashFS 파일 시스템이 시작된다는 뜻.
0x00017022 - 리틀엔디언으로 해석하면 버전, 블록 크기 등의 정보를 포함한 값들이다.
참고)
hackerschool.org