
초보자를 위한 펌웨어 해킹 접근법
이 문서는 펌웨어 리버싱과 익스플로잇에 입문한 초보자인 제 개인적인 경험을 담고 있습니다.

데모를 위해, 우리는 CVE-2023-27216을 분석하고 재현할 것입니다.
펌웨어를 익스플로잇하기 위해 다음 단계가 있습니다:
gdbserver를 정적으로 빌드합니다.일반적으로 펌웨어 바이너리 파일은 부트로더(uBoot), 커널 파일, 부트로더용 커널 헤더(uImage), 압축된 파일 시스템(일반적으로 SquashFS 형식), CRC/MD5 테이블(파일 무결성 확인용) 및 기타 여러 파일들을 포함합니다.
먼저 펌웨어를 분석할 방법을 찾고, 연구를 수행하여 몇 가지 리소스를 얻었습니다:

Extract firmware using binwalk: binwalk -Me DSL-3782_A1_EU_1.01_07282016.bin

추출된 squashfs-root 폴더와 몇 가지 이상한 파일들을 얻었습니다.

보너스: squashfs-root 폴더가 보이지 않는다면, 보이는 ".squashfs" 파일에 unsquashfs를 사용하세요. 그냥 zip 파일과 같습니다😅.
펌웨어 아키텍처와 엔디언을 확인합니다. 펌웨어에서 추출한 일부 바이너리를 확인하여 이를 확인할 수 있습니다. 아키텍처와 펌웨어 확인: file <binary>

여기서 펌웨어가 MIPS 32비트 MSB 아키텍처에서 실행된다는 것을 거의 확신할 수 있습니다. "거의"라고 한 이유는 일부 펌웨어가 Lexra와 같은 MIPS 호환 아키텍처에서 실행될 수 있기 때문입니다.
squashfs-root 폴더를 확인하고 몇 가지 흥미로운 파일을 발견했습니다:
usr/etc/init.d/rcS => 펌웨어가 부팅될 때 실행되는 스크립트입니다usr/etc/passwd => 사용자 정보가 포함된 파일입니다userfs/romfile.cfg => 자격 증명 admin:admin이 있습니다rcS 파일을 확인하고 흥미로운 코드를 발견했습니다:
echo "admin:$1$$iC.dUsGpxNNJGeOm1dFio/:0:0:root:/:/bin/sh" > /usr/etc/passwd
passwd 파일에 쓰는 데 사용됩니다Boa는 2000년대에 라우터와 같은 임베디드 장치에서 주로 사용된 고대 웹서버입니다. 그러나 boa 서버는 2005년에 이미 개발이 중단되었습니다! Boa 서버가 거의 20년 전에 죽었지만, 우리 공급업체 덕분에 오늘날까지 살아 있습니다.

에뮬레이션 프로세스에는 Ubuntu 또는 Kali와 같은 Debian 기반 OS를 권장합니다. 펌웨어 해킹에 특화된 또 다른 OS인 AttifyOS도 있습니다. 이 문서에서는 Kali Linux를 사용했습니다. 에뮬레이션 과정은 두 가지 도구로 시작합니다:

FAT를 사용하여 펌웨어를 완전히 에뮬레이트하는 방법을 살펴보겠습니다. 먼저 GitHub에서 Kali 머신으로 레포지토리를 클론합니다. 그런 다음 설정 과정을 진행합니다. fat.config 파일도 변경해야 합니다. 그렇지 않으면 작동하지 않습니다.
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
./setup.sh
vi fat.config # Modify to your sudo password.
그런 다음 펌웨어 바이너리(제조사에서 다운로드한 것)를 Kali 머신의 FAT 폴더로 복사하고 실행합니다.
./fat.py DSL-3782_A1_EU_1.01_07282016.bin
참고: FAT 설정 과정에서 오류가 발생할 수 있습니다. libmagic이 없다고 나올 수 있습니다.

간단히 다음을 실행하세요
pip unistall python-magic
pip install python-magic
이렇게 하면 문제가 해결되며, 빌드 명령을 다시 실행합니다. 이제 완벽하게 작동할 것입니다.

Enter를 눌러 실행합니다. 에뮬레이션 프로세스가 잘 작동하여 http://192.168.1.1 (Kali 머신에서)로 접속하여 작동 여부를 확인할 수 있습니다.

자격 증명이 있으면 콘솔에 로그인할 수도 있습니다. 자격 증명은 admin:admin입니다.

에뮬레이션된 펌웨어를 종료하려면 Ctrl+A X를 누르세요. 다시 실행해야 할 때는 fat.py를 다시 실행하지 마십시오. 펌웨어가 이미 이미지로 빌드되었기 때문입니다. 이미 생성된 스크립트만 실행하면 됩니다.
cd firmadyne/scratch/<Image-ID>
./run.sh

디버깅 목적으로 gdbserver를 빌드합니다. gdbserver를 빌드하는 방법은 여러 가지가 있습니다. 정적으로 빌드된 서버를 다운로드할 수도 있습니다. 정적으로 빌드된 일부 파일을 저장한 repo가 있습니다. 그러나 저는 gdbserver를 직접 빌드하는 것을 선호합니다. GitHub repo에 있는 것은 꽤 오래되어 호환성 문제가 발생할 수 있기 때문입니다.
참고를 위해 이 블로그 게시물을 참조하세요: https://sheran.sg/blog/cross-compile-gdb-for-mips/. 블로그는 2024년 7월 30일에 업로드되었으며, 이 프로젝트 직전이므로 완벽하게 작동합니다.
참고: 블로그는 MIPS x32 LSB용으로 빌드되었지만 우리는 MIPS x32 MSB가 필요합니다. mipsel-linux-gnu를 mips-linux-gnu로 변경해야 합니다.
MIPS용 툴체인을 설치해야 합니다. 다행히 Debian 패키지에 이미 있습니다.
**apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mips-linux-gnu g++-mips-linux-gnu**
MIPS용 gdbserver를 빌드하려면 빌드 및 설치해야 할 몇 가지 패키지가 있습니다. 다음은 소스를 가져온 곳입니다.
소스 다운로드
wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz
툴체인으로 라이브러리 빌드 이 라이브러리들을 빌드할 때 루트 권한이 있어야 합니다. MPFR을 빌드할 때 필요하기 때문에 먼저 GMP를 빌드해야 합니다.
tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mips-linux-gnu
make -j$((`nproc`+1))
make install
cd ..
그런 다음 MPFR을 빌드합니다:
tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=<YOUR-FOLDER>/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..
이제 마침내 gdbserver를 빌드할 수 있습니다:
tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=<YOUR-FOLDER>/gmp-6.3.0 --with-mpfr-include=<YOUR-FOLDER>/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static
빌드된 바이너리 gdbserver는 gdb-15.1/gdbserver 폴더에 있어야 합니다.
에뮬레이션된 펌웨어에는 wget, nc, curl, /dev/tcp 등이 없습니다. 파일 전송을 위해 Python HTTP 서버를 호스팅할 수 없습니다. ssh도 없습니다. 그러나 이미지를 마운트하여 에뮬레이션된 머신에 gdbserver를 넣을 수 있습니다.
sudo ./scripts/mount.sh 1gdbserver를 마운트된 폴더의 아무 곳에나 복사합니다.sudo ./scripts/umount.sh 1./run.sh를 다시 실행합니다).
