들어가며
그동안은 WeVO 공유기에 OpenWRT 가 포팅되었음에도 Telnet 인터페이스를 사용하거나, Command injection 취약점을 사용하는 것 외에, 웹 펌웨어 인터페이스로 손쉽게 플래싱할 수 있는 방법은 없었습니다. 이는 OpenWRT 펌웨어에 대한 접근성을 크게 떨어뜨리는 주범이었습니다.
이에 이를 해결하기 위해, WeVO 공유기 제품군의 firmware update 매커니즘을 리버싱하고, 이 위에서 손쉽게 플래싱할 수 있는 펌웨어 이미지를 생성하는 mkwevofw 툴을 제작하기까지 삽질기를 적어보고자 합니다.
Firmware update 검증 루틴 리버싱
우선 firmware update 검증 루틴을 역공학해 봅시다. 해당 루틴이 들어있는 CGI 파일인 upload.cgi 를 Ghidra 를 이용해 열어봅니다.
Ghidra 에서 펌웨어 플래싱에 사용되는 바이너리인 mtd_write 를 메모리 서치해보면 다음과 같은 문자열 결과들을 얻을 수 있습니다.
이 문자열을 참조하는 mtd_write_firmware 함수를 부르는 call tree 를 뽑아보면 main() 에서 mtd_write_firmware() 를 부름을 확인할 수 있습니다.
main() 에서는 다음과 같이 check() 를 불러서 firmware 의 무결성을 검사하고 이를 mtd_write_firmware() 를 이용해서 플래싱함을 알 수 있습니다.
check() 펑션을 살펴봅니다
해당 펑션을 살펴보면, 헤더 부분과 바이너리 전체에서 헤더를 뺀 부분의 crc32 값을 계산함을 확인할 수 있습니다.
이러한, uImage 헤더에서 헤더가 지정하는 커널 바이너리 길이를 무시하고 파일 전체에 대해 checksum 을 실행하는 구조는 iptime 의 그것과 유사합니다. 이제 가설 검증을 위해 iptime 펌웨어 체킹 스크립트를 이용해 WeVO 펌웨어의 헤더 구자가 iptime 펌웨어와 구조가 맞는지 체크해 봅니다.
결과는 다음과 같이 이미 iptime fw 구조를 가지고 있는 것을 확인할 수 있습니다.
펌웨어 빌딩
이제 OpenWRT 헤더 구조를 iptime FW 에 맞게 변형해서 플래싱해보면 다음과 같이 웹 플래싱은 통과하지만, 부팅 과정에서 오류가 발생함을 확인할 수 있습니다.
이는, U-Boot 가 펌웨어 뒤 squashfs 내용까지 ramdisk 내용으로 취급해 올려버림으로서 나타나는 문제로, 이를 해결하기 위해서는 큰 꼼수를 사용해야 합니다. 바로 CRC32 콜리전을 이용하는 것이죠.
WeVO 의 펌웨어 CRC32 계산 알고리즘은 헤더 구성 요소 중에 한 가지를 계산에 넣지 않았습니다. uImage 헤더 중, uImage 데이터 길이를 검증하지 않는 것이죠. 이와 더불어 CRC32 는 콜리전을 내기 쉬운 해싱 알고리즘입니다. 단지 4바이트를 덧붙이는 것 만으로도 같은 CRC32 값을 가지는 데이터를 만들어낼 수 있으니까요.
이를 이용하면, OpenWRT 펌웨어에 단지 4바이트 데이터를 덧 붙이는 것 만으로 해당 CRC 검증을 무효화하면서, U-Boot 의 정상적인 검증 루틴 또한 통과할 수 있습니다.
이를 이용해, mkwevofw 를 작성하였고, 이를 테스트해보면 다음과 같이 플래싱도 통과하고, 부팅에도 성공하는 모습을 볼 수 있습니다.
이를 이용해, 간편하게 Web UI 를 이용해 플래싱할 수 있는 WeVO 펌웨어를 만드는 데 성공하였습니다.
이런 임베디드 관련 글을 볼 때마다 좀 헷갈리는게 있는데요,
uBoot, Ramdisk, SquashFS 라는게 Flash Rom에 어떻게 적재되어 정확히 어떤 일을 하는걸까요?
검색하면서 찾아본 바로는,
1. 일단 Flash Rom에서 가장 먼저 읽어서 실행되는 uBoot는 GRUB 같은 부트로더 역할을 하면서
2. Ramdisk (initramfs) 라는 커널 + 부팅에 필요한 일부 프로그램 등이 들어있는 파티션을 램에 올려주고,
3. 이에 따라 Kernel이 로드되어서 Boot 과정을 진행 하고,
4. SquashFS 는 읽기전용으로 리눅스의 루트처럼 시스템 전체를 가지고 있기에 이를 마운트 해서 비로소 시스템 로딩이 완료
이렇게 되는것으로 이해 하고 있는데, 이게 맞을까요?
또, 보면 가끔 OpenWRT 펌웨어가 initramfs 랑 SquashFS 로 나뉘어 있던데, 이건 무슨 차이가 있는건가요?
우선 프로세서가 부팅되면 프로세서는 Boot ROM 에 있는 코드를 실행하게 됩니다. 이 Boot ROM 코드는 시스템의 기초적 초기화를 담당하며, 이후 지정된 매체 (이 경우는 SPI EEPROM) 에서 추가적인 초기화 바이너리(sram stage) 를 로드하게 됩니다.
SPI EEPROM 에서 로드된 SRAM Stage 는 메모리 버스 트레이닝과 같은 추가적인 시스템 초기화를 진행합니다. 이러한 초기화 루틴을 거쳐 DRAM 이 준비되면 SRAM stage 는 다음 stage 를 DRAM 에 로드합니다. 이후 이 다음 스테이지가 실행되며, 해당 stage 에서의 초기화 루틴을 거친 뒤, U-Boot 부트로더를 메모리에 로드 후 부트로더가 실행되게 됩니다.
부트 로더는 부트 로더 설정을 읽어들인 뒤, 리눅스 커널과 램디스크를 메모리에 로드 후 실행하게 되고, 이후 커널은 램디스크에 있는 init 을 실행한 뒤, init script 대로 부트 시퀸스를 진행하게 됩니다.
플랫폼에 따라 단계가 더 쪼개질 수도, 덜 쪼개질 수도 있지만, 큰 틀은 해당 부트 시퀸스를 따라갈 것입니다.
OpenWRT 의 경우, initramfs 버전은, 시스템의 모든 구성 요소가 initramfs 안에 들어있는 버전이고, SquashFS 버전은, 시스템의 구성 요소가 OverlayFS 지원을 위해 SquashFS 로 쪼개져 있는 구조입니다.
보통 initramfs 버전은 ipTIME 과 같은, 이미지 체크섬 검증을 파일 전체 길이에 대해 하는 펌웨어를 가진 하드웨어에 OpenWRT 를 플래싱하기 위한 첫 번째 단계로 사용됩니다. ipTIME 과 같은 시스템의 순정 펌웨어 업그레이드 페이지에 SquashFS 이미지를 올리면 펌웨어 업그레이드 파일 포멧 오류가 뜨지만, initramfs 이미지를 올릴 경우, kernel+initrd 길이가 파일 길이와 같기 때문에 순정 펌웨어의 펌웨어 업그레이드 파일 포멧 검증을 통과하는 것을 볼 수 있습니다.
우와 알고싶은것을 알려주시는군요. 감사합니다.
WeVO 11AC NAS Router 기종인데
openwrt-w2914nsv2-wevo.bin
이게 바로 안올라가네요.
공지에 내렸다고 올리셨는데 이 기종인가 보군요.
w2914nsv2 제품 사용자입니다
주인장님 덕분에 손쉽게 정펌에서 openwrt펌으로 손쉽게 변경할 수 있었습니다.
정말 감사드립니다
기글 hd 에 올리신 a8004t 개조 글을 보고 여기까지 찾아왔습니다. 작업해주셔서 감사합니다.
openwrt 를 커스텀 빌드해서 올려보고자 공부중입니다. 검색해서 찾은 정보로 따라하기 수준이라 매우 힘드네요.
a8004t용은 스냅샷으로만 올라와 있는데, 메인빌드는 openwrt 에서 직접 진행하는것인가요?
궁금한정보는 openwrt 를 올려서 usb포트에 dac를 연결한후 mpd music server 로 구성하고자 하는 것인데,
squashfs 를 플래싱한후에 opkg 에서 alsa-utils , kmod-usb-audio , mpd 순으로 설치하고 나서 재부팅하면 제대로 진행이 안되네요.
가능하다면 openwrt build를 직접해보고 싶은데요, defconfig 를 보내주실수 있을까요? 저는 buildroot 만 사용해봐서 build 후 squashfs와 initramfs 를 각각 어디에 생성되는지도 알려주시면 너무 감사하겠습니다.
네 현재 메인라이닝 된 상태이고 OpenWRT 스냅샷 빌드 나오고 있는 상태입니다.
OpenWRT defconfig 은 빌드 메뉴에서 ramips Arch 의 ipTIME A8004T 를 선택하고 빌드하면 바로 미니멀한 환경은 만들어지게 됩니다. OpenWRT 의 패키지를 함께 빌드해 넣으시고 싶다면 https://openwrt.org/docs/guide-developer/feeds 를 참조하여, Feed 들을 설치하시면, menuconfig 에 추가한 패키지가 보이게 됩니다.
(혹시 커스텀 피드, 패키지 제작을 하고 싶으시다면 위 링크의 custom_feeds 항목을 참조하시면 됩니다)
설정이 끝난 뒤, make 를 마치게 되면, 빌드 아티펙트가 bin/targets/ramips/mt7621 폴더 안에 생기게 됩니다 (아키텍쳐 / 플랫폼 조합에 따라 다름 — ipTIME A8004T 의 SoC 는 MT7621 이며, 코어는 Ralink MIPS)
이 폴더 안에 initrd 이미지와 squashfs 이미지가 생성되게 됩니다.
빠른 답변 정말 감사드립니다.
말씀하신대로 간단히 원하는 패키지를 추가해서 빌드해봤습니다.
bin/targets/ramips/mt7621 폴더에 initrd 이미지와 squashfs 이미지도 생성되었습니다..만 (만들어 올리신 파일 사이즈와 비슷한)
제가 선택한 패키지는 들어가 있지 않네요. 예를들어 alsa-utils 패키지 같은.
제가 빌드한 squashfs 에서는 스냅샷과 다른 vermagic 때문인지 opkg 로 설치가 되질 않네요. (잘 모르고 하는말입니다)
질문은 제가 선택한 패키지를 포함한 rootfs 를 만드는 옵션이 따로 있는것인지요?
그러니까 패키지가 포함된다면 용량은 4메가를 훌쩍 넘을텐데요.
미리 감사드립니다.
시간이 많이 흘러 때늦은 것입니다.
먼저, 이렇게 깊은 지식과 경험을 보유하신 것을 보니 구세주를 만난 것처럼 기쁩니다.
컴을 수십 년 사용해왔지만 Linux는 생소하고 firmware를 넘어서는 Router OS문제는
더더욱 넘사벽입니다.
어쩌다 보유한 WeVo 11ac Router 를 OpenWRT로 바꿔볼까 하면서도
home router로서 어떤 잇점이 있을까 궁금도 하지만
이 공유기가 은근 ‘열’이 많습니다. 누구말로는 미디어텍 칩이 원래 그렇다는데…
하여간, 염치없는 부탁입니다만,
제 공유기의 Web interface에서 그대로 firmware 올릴 수 있는 *.bin을
혹시 공유해 주실 수 있는지 여쫩니다.
소개해 주신 링크를 따라가보니 w2914 NS 용(?)을 다운 받아
11ac NS 의 현재 web UI 에서는 여러 번 올려봤는데
‘맞는 버전이 아니라’는 식의 에러 메시지만 나옵니다.
저같은 초보에게는
==최고의 소망==
perillamint사부님께서 11ac NS 모델용 mkwevofw 버전 만들어 주시는 버전을,
초보가 그냥 192.168.10.1치고 firmware upgrade항목에서 한 방에 올리면 최고이지만
그것까지는 염치가 없어 용기 내기 어렵습니다.
그게 아니라면 순서라도 지적해 주시면 감사하겠습니다.
가령, 아래처럼 핵심 내용과 순서만 적어 주시면 제가 방황을 덜 할 듯 합니다.
(1) uboot-11acnasrouter.bin를 어떤 환경에서 어떤 칸에서 실행하여 올린 뒤 공유기 부팅해라
(2) 그런 다음, 어디에 들어가서 openwrt-ramips-mt7621-wevo_11acnas-squashfs-sysupgrade .bin 을 올려봐라
이런 말씀만이라도 해 주시면 감사하는 마음으로 시행착오라도 해 보겠습니다.
거듭, 이러한 전문 지식이 부럽고 감사드리오며 고마운 마음 담고 갑니다.
항상 건강하시고 행복하십시오.
[Email address redacted]
김기현
현재 가장 깔끔하게 (Exploit 사용 없이) OpenWRT 를 11AC NAS 에 올리는 방법은 다음과 같습니다 (부트로더 수정 필요 없는 상태)
오, 신속히 답 주셔서 무한 감사 드립니다.
말씀주신 대로 얼른 해 보겠습니다.
항상 건강하셔서 초보자들에게 지식 나눔 해 주시면 고맙겠습니다.
감사합니다.
곰곰히 생각해보니 어떤 것이 어느 것인지 감을 못잡겠습니다.
솔직히 11ac용 initramfs가 어느 것인지, nightly는 무언지 모릅니다.
그래서 여쫩옵는데, 현재의 web UI 펌웨어 올리는 공란에
아래의 몇 번을 올리면 되는지 지적해 주십시오.
(1) MT7621A_uboot.bin
(2) openwrt-19.07.3-ramips-mt7621-11acnas-squashfs-sysupgrade.bin
(3) openwrt-ramips-mt7621-wevo_11acnas-squashfs-sysupgrade.bin
(4) openwrt-w2914nsv2-wevo.bin
(5) uboot-11acnasrouter.bin
위 중에, initramfs버전은 없는 것인지조차 모릅니다.
이 버전을 알아야 구글링이라도 할 텐데 속만 탑니다.
죄송하면서도 도움 주셔서 무한 감사 드립니다.
https://downloads.openwrt.org/releases/18.06.4/targets/ramips/mt7621/
에서 다음 파일을 순서대로 플래싱 하십시오
11acnas-initramfs-kernel.bin
이후 OWRT 부팅 대기 후
11acnas-squashfs-sysupgrade.bin
플래싱
안녕하세요,,,
1번 과정을 제조사 펌웨어 web ui 에서 해도 무방한가요? 본문에 의하면 변환과정을 거쳐야 제조사 web ui 통해서 업데이트 가능한것 같은데요.
고맙습니다.
아, 정말이지 어떻게 감사 드려야 할 지 모르겠습니다.
지식이 짧은 사람에게 베풀어 주셔서 감사드리고
친절한 도움 말씀에 천만 번 감사 드릴 뿐입니다.
사부님의 건강과 행복을 기도합니다.
안녕하세요. W2914NS V2 (AKA hi1200ac) 펌웨어지원이 2016년 이후로 끊겨서 좌절하고 있다가 우연히 이곳까지 와서 희망을 봅니다.
최근 댓글까지 확인하였으나 혼란이 있네요. 제 환경은 제조사 정펌 상태고요.
요약하면,,,
https://downloads.openwrt.org/releases/21.02.3/targets/ramips/mt7621/ 의 최신 wevo_w2914ns-v2-initramfs-kernel.bin 파일을 받아서
제조사 정펌 web ui 펌웨어 업데이트 메뉴에서 업데이트 후 재시작하면 openwrt 로 부팅되고 openwer luci 에서 wevo_w2914ns-v2-squashfs-sysupgrade.bin 를 적용.
이게 맞나요?
아니면 주인장님이 github에 올려두신 변환된 펌웨어를 설치해하고 21.0.3 으로 업그레이드 해야하나요?
아무쪼록 조언주시면 고맙겠습니다.
일단 정식 절차는 wevo_w2914ns-v2-initramfs-kernel.bin 을 정펌 UI 업데이트 메뉴에서 플래시한 후, 새로 올라간 OpenWRT 에서 squashfs 이미지를 sysupgrade 로 올리는 것이긴 합니다. 변형 과정은 squashfs 이미지를 바로 굽기 위해 진행하는 것이지, initramfs-kernel.bin 에는 별도의 패치가 필요하지 않습니다.
제가 만들어 두었던 변형 펌웨어를 사용하셔도 되지만, 버전이 낮으니, 정식 방법으로 업데이트 하시는 것을 권장드립니다.
광속답변에 다시 감동합니다.
고맙습니다!
안녕하세요!
우연히 ddns마저 끊긴 회사의 공유기의 활용방안을 찾다가 방문하였습니다!
제 공유기가 w2914ns v2의 클론모델인 hi1200ac인데
w2914ns의 펌웨어를 올리면 이후의 openwrt를 위한 작업이 진행 가능 할 듯 한데…
혹시 도움을 주실 수 있으실까요? w2914ns의 펌웨어를 hi1200ac의 펌웨어라고 속이면 가능할 것 같은데 문외한이라 어렵네요…
안녕하세요!
ddns마저 지원이 끊긴 공유기의 활용방안을 찾아보다 들어오게 되었습니다!
제가 가진 모델이 w2914ns의 클론모델인 hi1200ac인데 초기 비밀번호까지 같은주제에 펌웨어는 구별되어있더라고요…
hw적으로 같은 모델이라 w2914ns의 펌웨어를 올리면 그 후의 openwrt까지는 이미 알려진방법으로 가능할 것 같은데…
도움을 주실 수 있으실까요?
안녕하세요, 바빠서 이제야 보네요.
hi1200ac, 이거 완전히 동일 모델입니다. w2914ns 펌웨어만 올리신다면 문제 없이 사용 가능합니다.
웹 업데이트에서 꼬리에 붙은 CRC와 더불어 uImage 이름을 체크하던걸로 기억하는데, 너무 오래 전 일이라 저도 잘은 기억이 나지 않네요.
mkwevofw 에서 uImage 이름을 바꿔준다면 아마 문제 없이 플래싱은 되겠지만, 이후 sysupgrade 시 Hi1200AC 부트로더가 uImage 이름에 까탈스럽게 반응했던지 여부는 기억이 가물하네요.
답변 감사합니다! 하지만 아쉽게도
hi1200은 비밀번호도 w2914와 같은 주제에 펌웨어는 거르네요?
가장 큰 문제가 iwevo사이트도 사라져버려서 다시 도전해보려니 펌웨어를 얻을수가 없네요 ㅋㅋㅋ
백업이 어디 있기는 할건데…
hi1200ac 부트로더 셸에 진입한 뒤 tftp도 타임아웃나고 진행을 못 하겠네요
윈도우말고도 리눅스가 설치된 pc가 있어야 크로스컴파일러를 진행할 수 있는걸까요?