2P by GN⁺ | ★ favorite | 댓글 1개
  • Samsung WB850F는 DRIMeIII SoC와 Wi-Fi를 함께 쓴 첫 모델이며, 펌웨어 ZIP에 포함된 partialImage.o.map 덕분에 메인 SoC 펌웨어 분석과 핫스팟 감지 우회가 가능해짐
  • WB850F_FW_210086.zip에는 6개 파티션을 담은 WB850-FW-SR-210086.bin과 30만 줄이 넘는 링커 덤프가 들어 있어 Main_Image가 실제 ARM 펌웨어임을 확인할 수 있었음
  • Ghidra 분석에서는 문자열 주소 차이를 이용해 Main_Image베이스 주소 0xc0004000을 찾고, .text 함수명을 변환해 심볼로 가져오는 과정이 핵심이었음
  • 핫스팟 판단 함수 DevHTTPResponseStart는 HTTP 200의 Yahoo 도메인 쿠키나 301/302/307 리다이렉트 URL 초반의 yahoo. 문자열로 AP 인증 여부를 판정함
  • Yahoo가 HTTPS로 리다이렉트되면서 yahoo. 위치가 코드의 허용 범위를 벗어났고, samsung-nx-emailservice 패치 후 WB850F의 사진 업로드가 성공함

WB850F 펌웨어 ZIP의 구조

  • Samsung WB850F는 단종된 iLauncher 애플리케이션 이후에도 Samsung이 여전히 펌웨어와 지원 파일을 공개하는 몇 안 되는 모델 중 하나임
  • WB850F_FW_210086.zip에는 다음 파일들이 들어 있음
    • GPS_FW/BASEBAND_FW_Flash.mbin
    • GPS_FW/BASEBAND_FW_Ram.mbin
    • GPS_FW/Config.BIN
    • GPS_FW/flashBurner.mbin
    • FWUP
    • partialImage.o.map
    • WB850-FW-SR-210086.bin
    • wb850f_adj.txt
  • FWUP는 펌웨어 테스트/자동화 모듈용 스크립트로 보이는 upgrade all 문자열만 포함함
  • wb850f_adj.txt는 GPS 펌웨어를 업그레이드하고 관련 파일을 삭제하는 더 복잡한 스크립트임
  • GPS 관련 스크립트와 GPS_FW 폴더는 이번 분석 대상에서 제외됨

partialImage.o.map: 링커 덤프라는 지도

  • partialImage.o.map는 30만 줄이 넘는 텍스트 파일이며, partialImage.o에 대한 링커 출력과 연결된 파일의 전체 메모리 맵을 담고 있음
  • .text 섹션에는 sysInit, archPwrDown, DevHTTPResponseStart, DevHTTPResponseData, DevHTTPResponseEnd 같은 함수명이 들어 있음
  • .data 섹션에는 sysBus, sysCpu, sysBootLine 같은 데이터 심볼이 포함됨
  • 이 파일은 펌웨어 안의 코드와 함수명을 맞추는 심볼 지도로 활용됨

WB850-FW-SR-210086.bin 헤더와 파티션 테이블

  • binwalkWB850-FW-SR-210086.bin을 보면 HTML, PNG, JPEG 헤더, VxWorks 헤더, 여러 Unix 경로가 보이지만 명확한 파티션이나 파일시스템은 드러나지 않음
  • 첫 1KB를 헥스 덤프하면 펌웨어 버전 210086 뒤에 0x00 0x06이 나오고, 이어서 FW_UP/ONBL1.bin 같은 파일명이 보임
  • 각 레코드는 60바이트 구조로 보이며, 32바이트 0 패딩 문자열, 두 개의 리틀엔디언 정수, 20바이트 0 패딩 파티션 이름으로 구성된 것으로 분석됨
  • 두 정수는 각각 길이파일 내 오프셋으로 해석됨
  • 총 6개 레코드가 있어 0x00 0x06은 펌웨어 버전 문자열의 종료 또는 패딩 바이트와 1바이트 파티션 개수로 해석됨
  • 재구성한 파티션

    • FW_UP/ONBL1.bin
      • 크기: 196바이트, 오프셋: 0x0000800, 파티션 이름: ONBL1
    • FW_UP/ONBL2.bin
      • 크기: 46KB, 오프셋: 0x00008c4, 파티션 이름: ONBL2
    • [WB850]DSC_5KEY_WB850
      • 크기: 30MB, 오프셋: 0x000bef4, 파티션 이름: Main_Image
    • RomFS/SPID.Rom
      • 크기: 48MB, 오프셋: 0x1d2b32c, 파티션 이름: Resource
    • FW_UP/WB850.HEX
      • 크기: 19KB, 오프셋: 0x4c75f2c, 파티션 이름: OIS
    • FW_UP/skin.bin
      • 크기: 36MB, 오프셋: 0x4c7acb2, 파티션 이름: SKIN
    • 파티션 추출에는 DRIMeIII 펌웨어 파티션 추출 도구를 작성해 사용함

코드와 데이터 파티션 구분

  • 추출 도구는 파티션 이름을 기준으로 파일을 뽑고 .bin을 붙임
  • file 결과만으로는 Main_Image.bin이 OpenPGP Secret Key로 오인되는 등 유용성이 제한적임
  • ONBL1ONBL2Main_Image 안의 "BootLoader(ONBL1, ONBL2) Update Done" 문자열로 보아 부트로더 1단계와 2단계로 추정됨
  • Main_Image는 실제 펌웨어이며, binwalk -A가 이 파일에서 다수의 ARM 함수 프롤로그를 보고함
  • ResourceSKIN은 큰 컨테이너이며, 카메라 UI 스킨과 관련된 SoC 제조사 제공 구성일 가능성이 있음
  • OIS는 파일명과 달리 실제 HEX는 아니며, 전용 광학식 손떨림 보정 장치의 펌웨어일 수 있음
  • 분석의 중심은 Main_Image

Ghidra에서 Main_Image 매핑하기

  • ONBL1, ONBL2, Main_Image 세 파티션에는 실제 ARM 코드가 들어 있음
  • 일반적인 ARM 펌웨어는 주소 0x0000000에 리셋 벡터 테이블을 두지만, 세 바이너리 모두 시작 부분에 선형 코드가 있어 아직 알 수 없는 주소로 다시 매핑해야 함
  • 핫스팟 오인식을 분석하려면 다음 작업이 필요했음
    • Main_Image를 매핑할 올바른 메모리 주소 찾기
    • partialImage.o.map의 심볼 이름을 Ghidra에 로드하기
    • 핫스팟 로그인 판단을 잘못 트리거하는 함수 분석하기
  • Ghidra의 Defined Strings 탭에서 "yahoo"를 검색하자 DevHTTPResponseStart()의 디버그 문자열로 보이는 항목들이 나옴
    • DevHTTPResponseStart: url=%s, handle=%x, status=%d
    • DevHTTPResponseStart: This is YAHOO check !!!
    • DevHTTPResponseStart: THIS IS GOOGLE/YAHOO/SAMSUNG PAGE!!!! 111
    • 301/302/307! cannot find yahoo!
  • partialImage.o.map에서 DevHTTPResponseStart0x321a84에 있고, Ghidra도 같은 오프셋에서 함수를 찾음
  • 디버그 문자열 포인터 값과 실제 문자열 오프셋의 차이가 0xc0004000으로 맞아 Main_Image베이스 주소0xc0004000으로 결론냄
  • Ghidra에서는 사후에 베이스 주소를 바꿀 수 없어 바이너리를 프로젝트에서 제거하고 다시 가져오며 베이스 주소를 설정해야 했음

함수명 가져오기와 DevHTTPResponseStart 분석

  • Ghidra의 ImportSymbolScript.py는 텍스트 표에서 심볼을 대량으로 가져올 수 있음
  • 스크립트는 각 줄에 심볼명, 16진 주소, 함수 여부를 나타내는 f 또는 라벨 여부를 나타내는 l을 기대함
  • partialImage.o.map에서는 현재 .text 섹션의 함수만 필요했기 때문에 다음 항목들을 제외해야 했음
    • 빈 줄
    • 오브젝트 파일 오프셋
    • .text 같은 섹션 라벨
    • L$_ 접두 라벨
    • $ 접두 로컬 심볼
  • 주소에는 Ghidra 베이스 주소와 맞추기 위해 0xc0004000을 더함
  • 변환 결과는 sysInit c0004000 f, archPwrDown c0004094 f 같은 형식으로 만들어 Ghidra의 Script Manager에서 로드함
  • 함수명이 들어간 뒤에는 여러 DAT_ 필드를 포인터로 지정하고, 디버그 문자열에 맞춰 매개변수 이름을 바꾸면 DevHTTPResponseStart의 디컴파일 결과를 읽을 수 있음

핫스팟 감지 조건

  • DevHTTPResponseStart는 HTTP 응답 상태와 URL, 헤더를 보고 Wi-Fi AP가 인증되었는지 판단함
  • HTTP 200 OK 응답에서는 응답 헤더에 Yahoo 도메인 쿠키가 있어야 인증 성공으로 처리됨
    • 검사 대상은 domain=.yahoo, Domain=.yahoo, domain=kr.yahoo, Domain=kr.yahoo
    • 조건을 만족하면 p_request_ongoing을 0으로 바꾸고, 브라우저가 인증되지 않은 상태라면 safnotify_auth_ap(0)을 호출함
  • HTTP 301/302/307 리다이렉트에서는 URL 안의 yahoo. 문자열을 검사함
    • yahoo.가 없거나 url + 11보다 뒤에 있으면 Yahoo를 찾지 못한 것으로 처리함
    • 브라우저 프레임버퍼가 켜져 있지 않고 인증도 되어 있지 않으면 safnotify_auth_ap(1)을 호출함
    • yahoo.가 초반에 있으면 safnotify_auth_ap(0)으로 인증 성공 처리함
  • 음수 상태는 중단된 요청처럼 false를 반환함
  • 200도 리다이렉트도 아닌 양수 상태에서는 브라우저 프레임버퍼 상태에 따라 결과가 달라짐

TLS 이후 깨진 Yahoo 검사와 우회

  • 카메라가 질의하는 URL은 http://www.yahoo.co.kr/
  • 직접 요청하면 서버는 HTTP/1.1 301 Moved Permanently와 함께 Location: https://www.yahoo.com/로 리다이렉트함
  • https://www.yahoo.com/에서 yahoo. 부분 문자열은 위치 12에 있음
  • 코드는 yahoo.가 처음 11개 위치 중 하나에 있어야 한다고 요구하므로 이 검사는 HTTPS 전환 이후 깨짐
  • 핫스팟 검사를 통과하려면 DNS 레코드를 다른 서버로 향하게 하고, 그 서버가 더 Yahoo처럼 보이는 이름으로 HTTP 리다이렉트하거나 Yahoo 도메인 쿠키를 설정해야 함
  • samsung-nx-emailservice 패치 후 카메라는 실제로 연결하고 사진을 업로드함

같은 우회가 적용된 다른 카메라들

  • 이번 분석은 역공학한 함수 하나를 바탕으로 Samsung WB850F Wi-Fi 카메라의 핫스팟 감지를 이해하고 우회하는 데 성공함
  • 최종 패치는 작았지만, Samsung 엔지니어가 구현한 감지 방식 때문에 패킷 추적만으로 우회 방법을 추측하기는 어려웠음
  • 무엇을 찾아야 하는지 알게 된 뒤에는 MSN.com을 질의하는 카메라에도 같은 우회를 적용함
  • 그 결과 EX2F, ST200F, WB3xF, WB1100F가 지원 카메라 목록에 추가됨
  • Main_Image에는 7만 7천 개가 넘는 함수가 있어 디지털 카메라 동작을 더 이해하기 위한 분석 대상이 많이 남아 있음

댓글과 토론

Hacker News 의견들
  • https://op-co.de/blog/posts/samsung_nx_cryptofail/#index3h3 쪽이 더 마음에 들었음
    정말 놀라운 펌웨어 암호화 실패 사례임

  • 대단한 작업임. 리버스 엔지니어링 방법을 튜토리얼로 만들어볼 생각은 있는지 궁금함

    • 사실 이 글이 튜토리얼 역할을 할 만큼 충분한 정보를 제공하길 바랐음
      구글링하기 쉬운 부분만 생략했을 뿐임
  • 원하는 건 카메라 버튼으로 dSLR 사진을 찍으면 잠시 뒤 그 이미지가 Apple Photos에 들어가 있는 것뿐임

    • 예전에는 사진을 자동 동기화할 수 있는 Wi-Fi 내장 SD 카드가 있었지만, 그 분야의 주요 업체였던 Eye-Fi가 폐업했고 현대적인 클라우드 서비스와 동작하는 새 제품을 만든 곳은 없는 것 같음
      스마트폰이 소비자용 카메라 시장을 거의 없애버려 수요가 부족한 듯함. 프로젝트 아이디어로는 ESP32를 SD 카드 안에 밀어 넣는 방법을 찾아보는 것임
    • Wi-Fi가 있는 Canon dSLR은 FTP가 가능할 것 같음
      휴대폰, 태블릿, 웹사이트에도 연결할 수 있지만 앱이나 서비스가 필요함. 카메라에서 직접 FTP로 보내는 문서: https://gdlp01.c-wss.com/gds/5/0300024975/01/eos5d-mk4-wff-i... 113쪽. 링크는 EOS 5D Mark IV (WG) Wi-Fi (Wireless Communication) Function Instruction Manual임
    • Linux가 올라간 Samsung NX1과 NX500은 Wi-Fi 네트워크만 있으면 JPEG나 RAW를 어떤 온라인 서비스로든 올리도록 꽤 쉽게 스크립트화할 수 있음
      아쉽게도 10년 된 기종이고 중고 시장에서도 드묾
    • Snapbridge가 있는 Nikon Z 시리즈가 그쪽에서는 거의 최선임
      Wi-Fi나 Bluetooth로 페어링되고, 원하면 iPad로 카메라를 원격 제어하고 화면도 볼 수 있음
    • 이미 Google Photos용으로는 가능하니, 이것도 가능해야 함: https://www.stg-uploader.xyz/