이번엔 iptime 펌웨어를 직접 다운받아 bootloader + kernel + RFS의 구조로 분해해 보겠다.
해당 포스팅은 다음 해커스쿨 자료를 참조하였다.
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를 다운 받자.
링크를 클릭하여 다운을 받을 수 있다.
다음과 같이 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 |