출시된지 꽤 되었고 쓰다가 바꿀 계획이었고, 애플의 사악한 가격을 구경하고 자가교체를 하게 되었다.
자가교체시 노혼 배터리가 가장 유명하지만, 다음의 사이트에서 https://gigglehd.com/gg/mobile/7112312 아이폰 배터리관련 글을 보게되었다. 간략하게 요약하자면, 러시아의 BatteryLab이라는 업체에서 사제 배터리들을 테스트한 결과 노혼 배터리의 수명이 생각보다 좋지 않은 결과를 보여주었고 AYJ사의 배터리가 가장 좋은 효율을 보여주었다는 것이다. 하지만 몇 개의 배터리로 테스트를 한 결과인지 알 수 없어 참고 정도로만 하였다. 그러던 중 DEJI사의 배터리를 알게 되었다.
한국 총판도 있고, 여러 인증들을 받아서 이 업체에서 사기로 했다.(노혼은 이미 유명하여 짭이 많아서 이 브랜드를 선택했다.)
알리에서 사려고 하였으나 마침 옥션 쿠폰이 있어 국내에서 19000원 가량에 구입하였다.
사은품으로 배터리 테이프와 드라이버 핀셋 등을 함께 받았다.
액정을 열때는 헤어드라이기 보단 집에 남아도는 찜질팩이 최고인 것 같다. (전에 핫팩으로도 하였는데 나쁘지 않았다.)
여는 것만 잘하면 나머지는 ifixit이나 다른 유튜브 동영상을 적절히 검색하여 따라서 하면 된다. 하지만 우선 가장먼저 배터리를 연결해제 하는 것을 추천한다. 건조한 환경에서는 가끔 쇼트가나서 아이폰의 부품 몇개가 죽을 수 도 있다. (실제로 아이폰 7 지문인식을 날려먹기도 하였다.)
분해시 꼭 나사 위치를 정확히 해놓는 것이 좋다. 아니면 나사가 맞지 않거나 나사가 몇개 남는데 휴대폰이 동작하는 경우를 볼 수 있다.(실제로 아이폰3GS, 아이폰 4 사용시 경험하였다.)
유튜브 동영상으로 배터리 테이프를 제거하는 영상을 잘 보고 따라하길 바란다. (ifixtit 사진만 보고 참고할 시 저런 사태가 벌어질 수도 있다.)
참고로 ifixit에서는 디스플레이와 안테나, 탭틱 엔진을 분리하고 배터리를 분해하여라 하는데 그냥 배터리 케이블만 분리하고 바로 테이프를 제거하는 것이 훨씬 편했다. 괜히 동영상을 보지 않고 ifixtit만을 보았다가 탭틱엔진 분해시 케이블을 조금 찢어먹었다....
여튼 조립은 분해의 역순이라는 진리의 말대로 하면 (조립시 새 방수테이프와 배터리 테이프를 잘 붙여야한다.)
배터리 교체 완료이다.
교체 후 7일 정도가 되었는데
25사이클 정도 사용하였고, 아직 성능최대치는 100%이다. (저 기능을 사용하고 싶으면 개인정보보호 - 분석 및 향상에서 분석 공유를 활성화하고 분석데이터에서 log-aggregated 항목을 살펴보면 된다. 귀찮을시 iBackup과 같은 툴을 사용하길 바란다.)
참고로 대용량 배터리들도 있으나, 혹시 모를 스웰링 발생가능성을 배제할 순 없기 때문에 정품과 동일한 용량을 선택하였다. (내부 디자인도 신경을 쓰는 애플이 배터리 공간에 여유를 둔건 이유가 있을 것이다.. 괜히 배터리타임 조금 늘리려다 화면을 깨먹는 불상사를 발생시킬순 없기에..)
그리고 탭틱엔진을 날려먹어서 진동이 없지만 애플워치가 있는 덕분에 전화나 카카오톡을 확인하는데는 별 지장이없어 천천히 수리하기로 하였다... ㅠ
음... 사설을 가야겠다 ㅎㅎ...
(참고로 저 부품은 시리얼 넘버가 일치하지 않으면 작동을 하지 않으므로 icopy plus와 같은 기계로 원래 부품의 시리얼 넘버를 복사하여 알리발 부품에 붙여넣기를 해주어야 작동을 한다. 그렇지 않을 경우 홈버튼 진동만 오고 다른 진동은 작동하지 않는다고 한다.)
버거를 시키면 반으로 쪼개져서 나온다. 아마 채소들이 눅눅해지지 않게하기 위해서인 것 같다.
양이 겁나 많다. 다른 식당도 많았지만 여긴 더 배불렀던것 같다. 감자튀김은 그냥 아는 맛이니 먹는 양이 작으면 버거 단품을 추천한다. 버거는 쉐이크 쉑과 다르게 기름지다기 보단 담백한 고기였다. 빵은 어느정도 촉촉하나 목이 막히는건 똑같다. 맛은 있었지만 지나가는 길이 아니라면 도스버거를 가는게 나을 것 같다.
최신의 자동차들은 ECU라고 불리는 전자 제어장치를 장착한다. 차량에는 편의 기능을 위하여 장착된 ECU수가 많다. 이들간 통신을 위해 CAN이라는 단일버스 네트워크를 사용한다. CAN은 외부 네트워크에서 적용되는 보안기법에 취약하다. ICT와 융합된 커넥티드 카는 운행 중에도 외부네트워크와 항상 연결이 되어있고, 통신장치를 자동차에 장착할 수 있다. 커넥티드 카는 ECU들로 내부 네트워크를 구성한 자동차, 네트워크 서비스를 제공하는 Portal 그리고 자동차와 Portal을 연결해주는 통신 Link로 이루어져있다. 출고 시 기본 장착되는 통신장치 외에 third-party 통신장치가 추가 장착이 가능하다. 이 통신장치로 정보를 수집하거나 외부에서 원격으로 차를 조종할 수 있다. 운전자들은 스마트폰과 자동차간의 통신을 이용해 다양한 편의기능을 사용한다. 웹기반과 스마트폰 앱 기반 서비스로 자동차와 통신을 할 수 있다. 안드로이드 앱을 사용하는 경우, 역공학과 리패키징의 취약한 문제점이 있다.
이러한 After Market에서 판매되는 H/W와 S/W의 사용이 가능하다. 자동차 내부 네트워크와 자동차용 정비기기 사이의 통신을 지원하는 마이크로 컨트롤러인, ELM327기반의 무선통신 모듈을 사용하여 스마트폰과 자동차 내부 네트워크를 무선을 연결 할 수 있다. ELM327 제조사는 관련 H/W와 S/W를 제작할 수 있는 Data Sheet를 제공한다.
무기화
CAN의 보안 취약점과 안드로이드 앱의 역공학, 리패키징 취약점, 차량과 스마트폰과의 통신을 이용하여 무기화를 한다.
스마트폰 앱과 자동차간 통신이 가능한 점을 이용하여, 안드로이드 앱을 리패키징하여 악성앱을 제작한다. ADB Shell을 사용하여 정상적인 앱의 APK파일을 획득하고, 획득한 APK의 DEX(소스 코드를 컴파일한 결과물)파일을 획득한다. DEX파일이 가상머신에서 동작하는 바이트코드의 구조적 특징을 가진다는 점을 이용하여, 원본과 유사한 Java코드와 Smali코드를 얻는다. 분석을 하여 Smali코드에서 악성코드를 추가한다. 그리고 안드로이드 정책상 개발자 스스로 앱에 서명을 하여 배포하므로 임의로 서명을 하여 악성 앱을 배포할 수 있다.
자동차 진단 앱과 통신 모듈 ELM327의 통신을 이용하여, 앱에서 발생하는 통신데이터를 변경한다. 변조된 앱을 사용하여 ECU 강제 제어 데이터프레임을 CAN에 삽입하여, 정비용 CAN ID를 원하는 CAN ID로 변환한다. 모듈 Data Sheet를 참조하여 모듈을 제어할 수 있는 AT Command들을 획득한다. 이 AT Command들을 이용하여 실제 CAN으로 원하는 CAN ID로 변환하여 원하는 데이터를 전송한다.
CAN은 각 노드 간 통신시 암호화와 인증이 되어있지 않는 취약점이 있다. 앱으로 통신 모듈 ELM327과 블루투스로 통신될 때, Request-Response 메시지를 획득하여 자동차의 상태 정보를 획득한다. Java 기본함수 탐색을 통해 Smali 코드에 자동차 강제제어 코드를 삽입할 곳을 찾는다. 악성 앱에서 필요한 공격 Smali코드를 추출하고 공격 대상 앱에 적용하여 변조한다. 자동차의 상태 정보를 획득한 뒤, 특정 조건일 때, 변조된 앱으로 원래의 Request 메시지 대신 원하는 메시지로 변경하고 차량을 제어한다.
유포
자동차 정비 앱의 디자인을 바꿔 새로운 앱이 출시된 것처럼 가장한다. 그리고 가짜 광고를 통해서 자동차 정비 앱이 필요한 사용자들에게 홍보를 한다. 무료로 다운받을 수 있는 링크를 제공하여 사용자의 다운을 유도한다. 초기에는 정상적인 앱처럼 정상 작동을 하다 어느 시점이 지나면 코드가 동작이 되게 하여, 초기 사용자들이 좋은 평점을 남기게 한다. 그 평점을 이용하여 더 많은 사용자들의 다운을 유도한다. 또는 유료앱이 필요한 사용자들을 노린다. 악성 앱을 유명한 유료앱의 디자인으로 바꾸는 등 속이기 위한 위장을 하고, 블랙마켓, 앱에 대한 사전심사, 검사를 하지 않는 앱마켓 등에 뿌리고 사용자들의 다운로드, 설치를 유도한다.
악용 및 설치
사용자가 변조된 자동차 정비 앱을 다운로드, 설치 후 변조된 앱으로 자동차와 통신을 한다.
명령 및 제어
사용자가 변조된 앱을 다운로드, 설치 후 자동차와 통신을 함으로써, 악성코드가 심어진다. 그 후, 자동차는 사용자의 제어와 상관없이 심겨진 악성코드의 제어대로 움직이게 된다.
목적달성
공격자의 코드대로 차를 제어하여, 특정한 시점 또는 즉시, 운전자의 운전 제어를 방해한다.
.
공격 프로세스
사이버킬체인
사이버공격
설명
정찰
정보수집
자동차의 전자 제어장치와 내부 네트워크를 조사하고, 외부에서 접근할 수 있는 수단 등을 조사한다. 취약점이 나올만한 관련 정보도 모두 수집한다.
무기화
공격준비
정보수집 단계에서 수집한 정보들을 활용한다. 통신 모듈 ELM327로 앱, 자동차가 보안이 되지 않은 통신을 한다. CAN의 보안 취약점을 활용하여 자동차 내부 네트워크를 제어한다. 안드로이드 앱의 역공학, 리패키징을 이용하여 악성앱을 만든다. 위 두 취약점을 이용하여 앱으로 자동차 내부 네트워크를 제어하게 설계한다.
유포
유포
악성 앱을 새로운 앱처럼 홍보, 무료 다운로드 링크를 제공한다. 블랙마켓, 앱에 대한 사전 심사, 검사를 하지 않는 앱마켓에 악성앱을 유포한다.
악용
악용
사용자가 악성 앱을 다운로드하고 설치한다.
설치
설치
사용자가 악성 앱으로 자동차와 통신을 하면 ECU 강제 제어 데이터프레임이 CAN에 삽입된다.
명령 및 제어
명령 및 제어
악성 앱에 심어진 코드대로 자동차가 제어된다.
목적 달성
목적달성
특정 시점 혹은 항상, 운전자가 자동차를 제어하지 못하게 하거나 운전을 방해한다.
공격방법
정찰 단계에서 자동차의 공격점들을 찾아 무기화 단계에서 다음과 같은 취약점들을 이용하였다. 자동차 OBD-II 단자에는 여러 모듈을 장착할 수 있고 CAN은 추가된 ECU를 식별하지 못하며, 통신 참여를 제어하지 못한다. 정비 모듈을 사용하여 자동차 진단 앱과 통신을 할 수 있다. 안드로이드 역공학, 리패키징을 이용하여 악성 앱을 제작할 수 있다. CAN의 보안은 암호화/인증이 되지 않는다. 이러한 Attack Surface들을 찾아내어, 정상적인 앱을 역공학, 리패키징하여 악성코드를 추가한다. 이렇게 변조를 하여 악성 앱을 제작한다. 그리고 이 악성 앱을 유포, 설치한다. OBD-II 단자를 통해 통신 모듈을 추가한 뒤, 변조된 악성 앱으로 통신을 한다. AT Command로 원하는 데이터를 전송하여 자동차를 제어한다.
방어기법
정상적인 앱을 악성 앱으로 역공학하기 어렵게 한다. 정상적인 자동차 정비 앱을 만들 때, 식별자 변환, 제어 흐름, 암호화 기법, API 은닉 기법을 사용한다. 자동차 정비 앱에서 분석의 대상은 주로 개발상 사용되는 일부 문자열과 함수이기 때문에 위 기법들로 난독화 과정을 한다. 이러한 과정들로 APK의 중요 로직이나 코드, 리소스 등을 보호한다. 무기화 단계의 안드로이드 앱의 취약점을 방어하고, 유포, 악용, 설치 단계를 하지 못하게 하여 결국 명령 및 제어를 막는다. 따라서 목적달성을 실패하게 한다.
ELM327 통신 모듈이 제어 명령으로 정상적인 정비 ID 이외에 원하는 CAN ID의 데이터를 생성할 수 있어 자동차를 강제 제어 할 수 있다. 따라서 ELM327 모듈이 정비용 ID만 사용하도록 설계를 한다. 무기화 단계의 CAN의 보안 취약점을 방어한다. 따라서 설치 단계의 ECU 강제 제어 데이터프레임을 CAN에 삽입하지 못하게 한다.
OBD-II 단자는 여러 통신 모듈을 장착 할 수 있으므로 ELM327외에 다른 모듈이 취약점이 될 가능성이 있다. 따라서 CAN 데이터에 대한 접근제어를 해야한다. 자동차를 정비 중과 주행 중으로 구분을 한다. 정비 중일 경우 모든 CAN ID의 접근제어를 해제하고, 주행 중일 경우 특정 CAN ID데이터만 접근 가능하도록 필터링한다. 무기화 단계의 CAN의 보안 취약점을 방어하여 내부 네트워크에 접근, 제어를 하기 어렵게한다.
현재 ~디렉토리 $를 해주기 위해 getcwd를 사용하여 현재 디렉토리를 가져와 터미널에 출력하였다.
read systemcall을 사용하여 STDIN을 읽었다. 그리고 만약 엔터 \n만 치게된다면 다시 커맨드를 입력받을 수 있게 하였다.
명령어가 들어오면 execute_com를 실행하여 명령어를 실행하게 하였고, quit를 입력하면 myshell이 종료되게 하였다.
execute_com을 하려면 일단 입력받은 커맨드를 쪼개서 구분을 하여 명령을 처리해야한다. 따라서 get_tokens라는 토큰을 얻는 함수를 생성하였다. strtok함수를 이용하여 “ ”을 구분자로 하여 token화 하였다.
커멘드를 token으로 쪼개어 명령을 수행하는데, shell builtin 명령어들은 /bin에 저장되어있는 것이 아니라 bash가 동작할 때 수행하므로 각 명령어에 맞는 함수들을 사용하여 구현하였다.
shell builtin명령어들은 종류가 많이 있지만 각각 경우들을 비교하려면 수행시간이 길어지므로 cd와 pwd만 구현을 하였다.
따라서, strcmp함수를 사용하여 shell builtin명령어가 들어오면 builtin명령어인지 구분하여 실행을 한다.
그 외의 명령어들은 /bin에 있으므로 execvp를 사용하여 명령어를 실행한다. 환경변수 path에 디렉토리가 있으면 파일명만 입력하면 되므로 commands[0]을 인자로 넘겨준다.
리다이렉션의 경우, “from_file > to_file”의 형태이므로 STDOUT_FILENO가 to_file fd를 가리키게 한다.
그리고 “>” 앞의 명령어들을 실행하여 to_file에 그 결과들이 수행되게 한다.
백그라운드의 경우, fork를 한 후 부모프로세스는 자식프로세스를 wait하지 않게 하여 자식 프로세스가 백그라운드 프로세스로 돌아가도록 한다.
나머지 잘못된 사용을 하였을 시 잘못되었다고 예외처리들을 해주었다.
bash의 builtin 명령어들을 모두 구현하기 위해선 모든 builtin 명령어에 해당하는지 검사를 하고, 또 그에 따른 적절한 함수들을 사용해야하므로 코드가 길어지고 명령어 수행시간이 길어질 것 같았다.
따라서 cd, pwd와 같은 간단한 명령어만 수행하였다.
여기서 굳이 shell에서 builtin 명령어, 그 외 명령어로 구분지어 하나는 파일로 저장을 하고 하나는 쉘 내부에서 작동하게 하였는지 궁금하여 찾아보니, builtin 명령어들은 자주 사용되어 파일로 디스크에 저장해두면 매번 디스크에서 불러와야하므로 효율을 높이기 위해 램에 상주시키는 것을 알게 되었다.
Boot Sector의 크기는 2 Sector = 1KB(0x400)이므로 Super Block의 위치는 0x400부터 시작한다.
해당위치로 이동하면,
Log Block Size( 블록 크기 ) = 0x2000, Inode Per Group( 각 블록그룹에 속한 inode 수 ) = 0xef53, Block Per Group( 각 블록 그룹에 속한 block 수 ) = 0x8000을 얻을 수 있다.
Ext2에서 Root의 inode number는 2이다. 따라서 (inode number – 1)/block per group을 하면 Root의 inode가 속한 그룹은 0번임을 알 수 있다. 그리고 (inode number -1)%block per group을 하여 Root의 index가 1임을 알 수 있다.
그리고 Root안의 데이터를 보기위해 Group Descriptor Table을 보아 Group 0의 inode Table 시작위치를 얻는다.
첫 번째 Group Descriptor Table은 ramdisk의 1블록(4KB = 0x1000) 이후부터 시작하므로 해당 위치로 이동하면
각 그룹의 inode Table을 구하면
(단위 : block)
Group 0 = 0x23
Group 1 = 0x8023
Group 2 = 0x10002
Group 3 = 0x18023
이다.
Root가 속한 Group 0의 inode Table에서 1번째 inode를 찾는다. ( Inode의 크기는 0x100byte, index = 1 )
첫번째 블록 포인터인 0x223000을 찾아서 데이터 영역으로 이동을 한다.
Record len으로 디렉토리 엔트리의 크기를 알아내고, file type으로 디렉토리를 찾고, 이름을 얻는다. 그중 32153”6/82”에 해당하는 6번 디렉토리의 inode를 찾는다.
6번 디렉토리 inode number = 0x6066
속한 Block Group = (0x6066 – 1)/0x2000 = 3
Inode Table Index = (0x6066 – 1)%0x2000 = 101
6번 디렉토리가 Block Group 3의 inode Table의 101번째에 있음을 알 수 있다.
Block Group 3의 inode Table에서 101번째 inode로 이동을 한다.
=>0x18029600
Block pointer 0번을 얻고 이동을 한다.
=>0x8458000
6번 디렉토리가 있음을 확인할 수 있다.
학번의 끝이 682이므로 0x18029600에서 82번 뒤로 이동을 한다.
=>0x1802e800
Block Pointer 0 = 0x84aa000
Block Pointer 1 = 0x107ba000
Block Pointer 2 = 0x107d2000
Indirect Block Pointer 0 = 0x10204000
을 얻을 수 있다.
해당 블록의 위치로 이동을 하면 다음의 그림과 같이 데이터를 찾을 수 잇다.
마지막 indirect block pointer로 13번째 block의 inode를 찾아내고 이동하여 데이터를 찾았다.