본문 바로가기

ARM아키텍쳐

[ARM] iptime 펌웨어 분석

이번엔 iptime 펌웨어를 직접 다운받아 bootloader + kernel + RFS의 구조로 분해해 보겠다.

 

해당 포스팅은 다음 해커스쿨 자료를 참조하였다.

https://www.hackerschool.org/HardwareHacking/%EA%B3%B5%EC%9C%A0%EA%B8%B0%20%ED%95%B4%ED%82%B9%20-%20ARM%20exploitation.pdf

 

 

iptime의 g104 7.60 버젼의 펌웨어를 사용하였다. 

(http://iptime.com/iptime/?pageid=4&page_id=126&mod=document&keyword=7.60&uid=9564)

binwalk로 펌웨어의 구조를 살펴보면 0x10038까지는 bootloader x0010038 이후에는 gzip으로 압축된 Kernel로 이루어진 것을 알 수 있다. 또한 0xB0000부분 부터 Squashfs 파일시스템으로 구성된 것을 볼 수 있다.

-->?? 왜 Bootloader 부분은 binwalk로 뜨지 않는것일까?

 

펌웨어의 시작 부분도 확인해 볼 수 있다.

 

앞부분은 Bootloader 이므로 dd로 잘라서 확인해보자

 

$ dd if=./g104_kr_7_60.bin of=./bootloader count=65592 bs=1

 

 

xxd로 bootloader 파일을 확인해본 결과 원래 펌웨어 파일인 g104_kr_7_60.bin의 앞부분과 동일한 것을 볼 수 있다.

 

--> 해당 bootloader 파일을 IDA로 분석할 수 있다.

 

이제 Kernel을 분석해보자

 

Kernel은 앞에서 본것처럼 offset 65592 이후에 존재하는 것을 볼 수 있다.

kernel 부분 또한 dd 명령어로 분리해 보자

 

dd skip=65592 if=./g104_kr_7_60.bin of=./i.tmp.gz bs=1

 

또한 이렇게 분리한 Kernel을 확인해보면

 

당연히 gzip으로 압축된것을 확인할 수 있다.

또한 xxd i.tmp.gz | more로 i.tmp.gz 구조를 확인해보면

여기서 Kernel의 첫번째 데이터의 값인 0x1f와 두번째 데이터인 0x8b 각각 1byte 값을 가진 데이터들은 모두 gzip의 파일 포멧을 알려주는 부분이다.

 

그럼 gzip -d i.tmp.gz 명령어로 gzip을 압축 해제 해보자

 

 

압축 해제 후 xxd i.tmp | more 명령어로 i.tmp의 데이터를 확인해 본 결과  kernel이 존재하는 헤더를 확인할 수 있다.

그리고 strings로 i.tmp 파일 (Kernel  파일)을 확인해보면 misc.c에 의한 gzip 해제 코드가 있는 것을 볼 수 있다.

 

binwalk로 i.tmp를 확인하면 모두 gzip으로 압축되어 있는 것을 볼 수 있다.

 

두번째 gzip 압축 파일이 있는 initrd는 이전에 포스팅 했던 부트로더에서 initrd=/bin/sh를 입력했던 부분과 연관이 있다고 판단된다.

 

그럼 initrd 부분을 추출해보자

 

binwalk -e i.tmp

새롭게 binwalk -e로 추출하면 _i.tmp.extracted 디렉터리가 생성되는 것을 확인할 수 있다.

해당 디렉터리 안에 추출된 initrd를 file 명령어로 확인해보면

filesystem data라고 표시되는 것을 알 수 있다.

initrd를 새롭게 생성된 FILE_SYSTEM 디렉터리에 mount를 진행하면 filesystem 형식과 같은 파일들이 나오는것을 볼 수 있다.

 

그럼 처음 binary에서 확인 되었던 Squash Filesystem과 함께 총 두개의 Filesystem이 있는 것인가?

이번엔 726896  offset에 위치한 filesystem을 분리해보자

 

$ dd skip=720896 if=./g104_kr_7_60.bin of=./RFS.bin bs=1

 

다음 명령어로 filesystem 추출해보자

file 명령어로 RFS.bin의 정보를 확인할 수 있다.

이후 RFS.bin의 Squashfs을 unsqash하기 위해 fmk를 다운 받자.

 

https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/firmware-mod-kit/fmk_099.tar.gz 

링크를 클릭하여 다운을 받을 수 있다.

다음과 같이 fmk_099.tar.gz 파일이 만들어지는 것을 볼 수 있다.

 

$ apt-get install git build-essential zlib1g-dev liblzma-dev python-magic

$ tar xvfz fmk_099.tar.gz

$ cd fmk/src

$ ./configure

$ make

$ cd..

 

다음의 fmk 폴더에 RFS.bin을 복사한다.

이후 아래 명령어로 unsquashfs를 진행해준다.

 

$ ./unsquashfs_all.sh RFS.bin [B0000.squashfs]

$ mv [B0000.squashfs] squashfs-root

 

 

다음과 같이 파일시스템을 추출할 수 있다.

 

즉, 구조의 Diagram을 그려보면 다음과 같이 Bootloader가 존재하고 i.tmp.gz 안에 Kernel과 ext2 파일 시스템이 별개로 존재하는 것이다.

 

이후 파일시스템을 다시 복원해보자.

 

$ mkdir ALL_FILE_SYSTEM

$ cd ALL_FILE_SYSTEM/

$ sudo cp ../_i.tmp.extracted/FILE_SYSTEM/* . -Rfpd

$ sudo cp ../fmk/squashfs-root/* ./cramfs/ -Rfpd

 

다음 명령어로 파일시스템을 복원하면 다음과 같이 된다.

이제 qemu로 emulating을 해보자.

 

$ qemu-arm -L ../ ./busybox

$ qemu-arm -L ../ ./busybox ifconfig

 

다음과 같이 qemu 명령어로 테스트를 진행해볼 수 있다.

$ qemu-arm -L ../ ./timepro.cgi

명령어도 확인 가능하다.

그리고 이후

 

$ cd ALL_FILE_SYSTEM

$ find . | cpio -o --format=newc > ../rootfs.img

$  cd ..

$ gzip -c rootfs.img > rootfs.img.gz

$ cp [zImage 경로]

$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh console=ttyAMA0,115200" -nographic

 

qemu로 실행하면 

다음과 같이 busybox 파일시스템이 부팅되는 것을 볼 수 있다.

 

$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh console=ttyAMA0,115200" -nographic -redir tcp:8080::80

 

뒤에 -redir tcp:8080::80 옵션을 붙여줌으로써 네트워크를 활성화 할 수 있다.

 

busybox의 파일시스템에서

 

# busybox ifconfig eth0 10.0.2.15 netmask 255.255.255.0

명령어로 link up

 

이후

# busybox route add default gw 10.0.2.2

# cd /sbin

# ./httpd

로 httpd 실행

그러나 Secure Connection Failed가 뜬다.

 

하지만 처음에 qemu로 부팅시

$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/bin/sh console=ttyAMA0,115200" -nographic -redir tcp:8081::80 

 

tcp포트를 8080에서 8081로 변경한 후 진행하면

IPTIME G104 버젼이 Emulating이 되는 것을 볼 수 있다.

'ARM아키텍쳐' 카테고리의 다른 글

[ARM] Bootloader + Kernel + RFS  (0) 2023.01.24
[ARM] Bootloader + Kerenl 부팅  (0) 2023.01.24
[ARM] Kernel 설치  (0) 2023.01.24
[ARM] Boot Loader 설치  (0) 2023.01.11
[ARM] Cross-Compiler 설치  (0) 2023.01.11