안드로이드 MCP: Claude로 클라우드 안드로이드(ReDroid) 앱 조작하기

요즘은 핸드폰에 모든 것을 저장한다. 은행/카드 등 모든 정보가 저장되어 있고, 핸드폰을 분실하면 은행 업무부터 막힐 것이다.

PC는 데이터를 클라우드(MS OneDrive)에 저장해 두면, Windows가 설치된 다른 PC에서 내 OneDrive 계정으로 로그인만 해도 대부분 복원된다. 하지만 핸드폰은 글쎄… 폰이 없는 상태에서는 아무것도 할 수 없다.

그래서 폰 환경 자체를 클라우드에 두는 방법을 시도했다. 이 글의 주제는 MCP다. 클라우드 안드로이드(ReDroid)에서 Claude가 MCP로 앱을 조작하게 해 본 과정과 결과, 그리고 그 과정에서 다시 생각하게 된 시큐어 코딩 이야기를 정리한 것이다. 원래는 이 환경을 바로 실사용하려 했지만, 보안 사고를 계기로 지금은 꺼 두었고 다시 켤 때는 VPN 안에서만 접근하도록 하기로 했다. 그 계획은 뒤쪽에 따로 적었다.

클라우드에 둔 폰에는 MCP(Model Context Protocol)도 연결했다. Claude가 화면을 보고 탭하고 스와이프하게 하는 방식인데, 써 보니 특히 금융 앱에서 쓸모가 커 보였다. 금융 앱은 잔액 변동이나 거래 내역을 주기적으로 확인해야 하는데, 개인이 직접 쓸 수 있는 API는 거의 없다(오픈뱅킹·마이데이터는 사업자용이다). PC(Windows)에서는 서비스마다 설치된 개별 보안 프로그램 때문에 자동화가 어렵다. 반면 안드로이드는 보안 프로그램과의 결합이 PC만큼 강하지 않아서, 화면을 읽고 조작하는 방식이 기술적으로 가능하다. 내가 써 본 범위에서의 판단이다.

먼저 밝혀 둔다. 이 글은 보안 우회 방법을 다루지 않는다. 테스트는 모두 내 기기와 내 계정으로, 소액으로만 진행했고 개인정보는 가림 처리했다.

글이 길어서 읽는 순서를 먼저 적어 둔다.

  1. ReDroid 구성과 금융 앱 실행 결과
  2. MCP 활용 사례: 앱 설치와 매뉴얼, 퍼즐게임, 은행 이체, 은행 앱 동시 실행, 금융 앱 조회 자동화에 대한 생각
  3. 앱이 실행 환경을 믿는 방식, SELinux, 시큐어 코딩 이야기
  4. 운영 환경(Oracle Free Tier)과 VPN 전용 접근 계획, 정리

왜 ReDroid인가

클라우드에서 안드로이드를 돌리는 후보는 세 가지였다.

  • Waydroid: 로컬에서 화면을 가진 환경에 특화. 클라우드에서는 화면이 필요 없어서 제외
  • Cuttlefish: Google의 가상 디바이스. 커스터마이징 등을 고려해 제외
  • ReDroid: Docker, podman, Kubernetes로 여러 인스턴스 실행 가능. arm64와 x86_64 지원, Android 8.1부터 16까지 이미지 제공

결국 화면 없이 컨테이너로 띄울 수 있고 ARM 서버에서도 돌아가는 ReDroid를 선택했다.

전체 구성

flowchart LR
  CL["🤖 Claude<br/>MCP 클라이언트"] -->|"스크린샷 · 탭 · 스와이프 · 키"| MCP["MCP 인터페이스"]
  MCP --> RD["📦 ReDroid 컨테이너<br/>클라우드 안드로이드"]
  PH["📱 내 폰 / 💻 PC<br/>웹브라우저 카메라 · 센서"] <-->|"WebSocket"| RD
  RD --> APP["📲 앱"]
  style RD fill:#ffe6cc,stroke:#f57c00
  style CL fill:#dbe7ff,stroke:#2563eb

그림 1. ReDroid에 MCP로 Claude를 연결하고, 카메라 등 센서는 내 폰이나 PC의 웹브라우저에서 WebSocket으로 공급하는 구성

컨테이너에는 카메라 같은 하드웨어가 없다. 그래서 내 폰이나 PC의 웹브라우저를 WebSocket으로 안드로이드에 연결해, 브라우저의 카메라와 각종 센서를 그대로 이용했다. 구조는 WebSocket으로 가상 센서 구현하기에 정리해 두었다.

ReDroid의 신분증 촬영 화면에 웹브라우저의 카메라 영상이 들어가는 모습. 상단에 외부 장치 ON/OFF 스위치, 하단에 안드로이드 Home/Recent 버튼 표시
신분증 촬영 화면에 가상 카메라로 웹브라우저의 카메라 영상이 들어가는 모습 (① 외부 장치 ON/OFF 스위치, ② 안드로이드 버튼)

그림 속 표시는 다음과 같다.

  • ① 외부 장치 연결 스위치: 안드로이드에 연결하는 외부 장치(마이크, 스피커, 카메라)를 켜고 끄는 스위치. 화면의 Mic, Speaker, Camera 버튼이 해당
  • ② 안드로이드 버튼: 하단의 Home과 Recent는 안드로이드의 홈과 최근 앱 버튼. 화면 위에서 터치로 누르는 방식

금융 앱 실행 결과

금융 앱은 설치와 실행이 까다로웠다. 앱별 결과는 아래와 같다.

앱LineageOS 실제 디바이스ReDroid (에뮬레이터 환경)
앱 A사용 가능실행 환경 검사로 실행되지 않음
앱 B—실행됨, 소액 이체까지 진행

작성자 환경에서의 결과이며, 앱 버전과 환경에 따라 달라질 수 있다. —는 이 글에서 다루지 않은 항목.

앱 A가 LineageOS를 올린 실제 디바이스에서는 되는데 에뮬레이터에서는 실행되지 않았다는 점이 눈에 띈다. 앱 코드는 같고 달라진 것은 실행 환경뿐이기 때문이다. 이 차이는 아래 ‘앱은 실행 환경을 어떻게 믿는가’에서 정리한다.

MCP 활용 사례

화면 캡처와 터치 같은 조작을 MCP로 노출하면 Claude가 화면을 보고 사람처럼 앱을 조작할 수 있다. MCP로 연 도구는 스크린샷, 탭, 스와이프, 키 입력 네 가지뿐이다. 사람이 폰을 쓰는 동작과 같다. 이 구성으로 성격이 다른 사례 4개를 시도해 보았다.

사례보여주려는 것결과
① 앱 설치와 매뉴얼 작성탐색과 문서화영상과 PDF
② 퍼즐게임 플레이판단과 조작2048 완성
③ 은행 이체고위험 작업과 안전장치은행 이체 성공
④ 은행 앱 2개 동시 실행운영 관점의 교훈결론만 기록 (영상 비공개)

활용 사례 ① 앱 설치와 매뉴얼 작성

메뉴와 설정이 여러 개 있는 일반 앱을 대상으로, Claude가 Play 스토어에서 앱을 찾아 설치하고 주요 화면을 둘러본 뒤 초보자용 사용 매뉴얼을 쓰게 했다. 대상은 네이버 파파고다. 로그인 없이 쓸 수 있고 화면 이동이 많아서 매뉴얼로 정리할 내용이 많은 앱이다.

  • 환경 구성: 일본어 메뉴판 이미지를 OBS 가상 카메라의 입력으로 쓰고, 웹브라우저에서 웹캠을 OBS 가상 카메라로 선택했다. 이 영상이 WebSocket을 거쳐 안드로이드의 카메라 영상으로 들어간다
  • 흐름: 설치, 실행, 이미지 번역 메뉴 탐색과 언어 설정(일본어→한국어), 촬영, 화면별 캡처, 매뉴얼 작성. 카메라 권한은 이미 허용된 상태라 권한 팝업은 나오지 않았다
  • 결과물: 캡처 이미지와 설명이 짝으로 묶인 12쪽 PDF 매뉴얼

(영상은 2배속이며, 개인정보 보호를 위해 채팅의 접속 정보와 앱 목록을 가림 처리했다.)

결과: Claude가 Play 스토어에서 파파고를 설치하고, 이미지 번역으로 일본어 메뉴판을 한국어로 번역해 본 뒤, 12쪽짜리 사용 매뉴얼을 만들었다. 캡처마다 빨간 박스와 화살표를 넣고 단계별 설명과 목차를 붙였다. 만들어진 매뉴얼은 여기(PDF)에서 볼 수 있다. 3쪽은 앱 목록을 가리느라 이미지로 처리해서 글자 선택은 되지 않는다.

활용 사례 ② 간단한 퍼즐게임 플레이

게임에는 매뉴얼이 필요 없고 플레이 자체가 볼거리다. 2048이나 스도쿠처럼 턴제로 진행되는 퍼즐은 화면 캡처와 조작이 오가는 지연이 문제 되지 않고, 상태가 명확해서 판단이 맞았는지 바로 확인할 수 있다.

  • 흐름: 스크린샷으로 판을 읽고, 다음 수를 계산해서 스와이프하는 과정을 반복
  • 모델: Opus로 돌려 보았다. Sonnet이 그때그때 상황에 맞춰 수를 두었다면, Opus는 스스로 퍼즐을 푸는 프로그램을 만들고 그 프로그램으로 해법을 찾아 문제를 풀었다. 이 점이 인상 깊었다

결과: 2048 타일에 도달했고 점수는 20,352점이었다. 승리 화면은 사람이 넘겨 주었다. (영상은 2배속이며, 중간 구간은 녹화가 유실되어 앞부분과 결과 화면만 담았다.)

활용 사례 ③ 은행 이체: 사람이 개입해야 하는 지점

은행 앱에서 Claude로 이체를 진행해 본 결과가 아래 영상이다. (영상은 2배속이며, 개인정보 보호를 위해 가림 처리했다. 테스트는 내 기기와 내 계정 사이의 100원 소액 이체로만 진행했다. 특정 은행 앱을 평가하려는 것이 아니라 에이전트가 어디서 멈추는지를 보려는 실험이다.)

테스트하면서 확인한 점은 다음과 같다.

  • 모델 선택: Haiku로는 화면을 제대로 이해하지 못해서 Sonnet으로 변경
  • 중복 이체 경고: 앱이 ‘오늘 동일한 이체 건이 있다’는 경고를 띄우자 Claude가 임의로 진행하지 않고 멈춰서 사용자에게 확인
  • 간편비밀번호 단계: Claude가 비밀번호를 추측해서 입력하지 않겠다고 밝히고 사용자에게 요청
  • 키패드 점검: 비밀번호를 전달받은 뒤, 숫자를 누를 때마다 키패드 배열이 바뀌는지 먼저 확인하고 나서 입력했다. 경우에 따라 매번 키패드가 바뀌는 앱도 있다는 것을 이미 알고 있다는 점이 놀라웠다

비밀번호 단계는 실제로 써 보면 중요하다. 이번에는 비밀번호를 대화로 전달해 Claude가 입력하게 했지만, 비밀 값은 대화에 남기지 않는 것이 맞다. 환경변수나 Vault 같은 비밀 저장소에 두고 꺼내 쓰는 방식이 더 낫다고 본다. 이 영상에서도 해당 구간은 가렸다.

①②는 ‘Claude가 할 수 있는 일’을 보여 주고, ③은 ‘어디까지 맡기면 안 되는가’를 보여 준다. 중복 이체 경고에서 멈추고 비밀번호를 추측하지 않은 것처럼, 돈이 오가는 단계는 사람이 최종 승인하는 구조가 맞다고 생각한다. 참고로 은행 앱을 자동화하는 것은 약관상 제한될 수 있고 보안 위험도 있으므로, 이 글은 실험 기록이지 따라 해 보라는 권장이 아니다.

활용 사례 ④ 은행 앱 2개 동시 실행: 그래서 클라우드 폰을 껐다

ReDroid를 하나 더 띄워 같은 은행 앱을 두 개 실행해 보았다. 예상과 다른 결과가 나왔지만, 자세한 내용은 적지 않는다. (내 기기와 내 계정으로 소액만 테스트했고, 영상은 공개하지 않는다.)

이것이 앱 쪽의 문제인지는 내가 판단할 수 없고, 이 글에서 따질 일도 아니다. 다만 환경을 운영하는 입장에서 분명해진 것이 있다. 로그인된 금융 앱이 올라간 환경은 그 자체가 민감한 자산이라는 점이다. 이 환경이 통째로 털리면 복제폰처럼 쓰일 수 있다는 걱정을 무시할 수 없다.

그래서 클라우드 폰은 지금 꺼 두었다. 다시 켤 때는 뒤쪽의 VPN 전용 접근 계획대로 막아 둔 상태에서만 쓸 생각이다. 앱 보안에 관해 확인이 필요한 부분이 생기면 블로그가 아니라 해당 금융사에 직접 알리는 것이 맞다고 생각한다. 그래서 이 사례는 영상 없이 결론만 적는다.

왜 금융 앱에 MCP가 잘 맞는다고 보는가

서론에서 말한 금융 앱 이야기를 조금 더 정리하면 다음과 같다. 내가 써 본 범위에서의 개인적인 판단이다.

  • 개인용 API가 거의 없다: 오픈뱅킹·마이데이터는 사업자용이라, 개인이 내 내역을 확인하려면 앱을 직접 열어 봐야 한다
  • Windows에서는 자동화가 어렵다: PC에서는 금융 서비스마다 개별 보안 프로그램이 설치되어 있어서 화면을 읽고 조작하는 식의 자동화를 붙이기 어렵다
  • 안드로이드는 화면 기반 접근이 가능하다: 안드로이드에도 보안 프로그램이 없는 것은 아니지만(V3 같은 앱 설치를 요구하기도 한다), PC처럼 보안 프로그램과 매우 강하게 결합된 상태는 아니어서 화면을 캡처하고 터치하는 MCP 방식이 기술적으로 가능하다
  • 내 화면을 대신 읽는다: Claude가 사람처럼 화면을 보고 읽으므로, 내가 앱에서 볼 수 있는 내 잔액과 내역을 정리하는 용도로 쓸 수 있다

다만 보안 프로그램과의 결합이 약하다는 것이 ‘검사가 없다’는 뜻은 아니다. 앞서 본 앱 A처럼 앱 자체가 실행 환경을 검사하는 경우는 여전히 있고, 그래서 에뮬레이터에서 실행되지 않기도 한다. 따라서 현실적인 활용 범위는 조회로 한정하는 것이 맞다고 생각한다.

  • 조회 위주: 잔액과 거래 내역을 주기적으로 확인하고 변동이 있으면 알려 주는 용도
  • 자금 이동은 사람이: 이체처럼 돈이 움직이는 단계는 위 사례 ③처럼 사람이 최종 승인
  • 비밀번호는 대화에 남기지 않기: 사용자가 직접 입력하거나 환경변수·Vault 같은 비밀 저장소에서 꺼내 씀
  • 약관 확인: 서비스마다 자동화 이용을 제한할 수 있으므로 사용 전에 확인

주기적으로 실행하는 조회 자동화는 아직 구상 단계이고, 해 보면 결과를 이어서 정리할 생각이다.

앱은 실행 환경을 어떻게 믿는가 (추정)

금융 앱이 실행 환경을 확인하는 대표적인 방법 중 하나가 Google Play Integrity API이다. 공식 문서 기준으로 판정(verdict)은 다음과 같이 나뉜다.

  • MEETS_DEVICE_INTEGRITY: 정품 인증 안드로이드 기기. Android 13 이상에서는 부트로더가 잠겨 있고 제조사 인증 이미지가 올라가 있다는 하드웨어 기반 증명이 필요
  • MEETS_STRONG_INTEGRITY: 위 조건에 더해 최근 1년 이내 보안 업데이트가 적용된 기기 (Android 13 이상 기준)
  • 에뮬레이터와 루팅 등으로 변조된 기기: 위 판정을 받지 못함

앱 A가 정확히 어떤 검사를 쓰는지는 내가 확인하지 못했다. 다만 실제 디바이스에서는 되고 에뮬레이터에서는 안 된다는 패턴은 이런 기기 증명 계열의 검사와 잘 맞는다. ReDroid는 제조사가 인증한 이미지와 잠긴 부트로더를 가진 기기가 아니기 때문이다. 어디까지나 정황에 기반한 추정이다. 중요한 점은 이런 판정을 앱이 아니라 앱 서버가 검증하도록 설계되어 있다는 것이다.

소주제: SELinux, 앱이 쓰는 건 처음 봤다

이 과정에서 새로 눈에 들어온 것이 SELinux다. Android 공식 문서 기준으로 SELinux는 root 권한 프로세스까지 포함한 모든 프로세스에 강제 접근 제어(MAC)를 적용하는 장치이고, ‘명시적으로 허용하지 않은 것은 거부’가 기본 원칙이다.

  • Enforcing: 위반을 기록하고 실제로 차단. Android는 이 모드로 출하되며 Android 5.0 이후 완전 적용
  • Permissive: 위반을 기록만 하고 차단하지 않음. 정책 개발과 디버깅용
  • 앱 샌드박스: Android 4.3부터는 앱마다 고유한 UID에 더해 SELinux가 샌드박스의 경계를 정의

그동안 SELinux는 OS(프레임워크) 쪽이 앱을 가두기 위해 쓰는 도구라고만 생각했다. 그런데 이번에 금융 앱이 자기가 돌고 있는 환경의 SELinux 상태까지 신호로 살펴본다는 것을 알게 됐다. 가둬지는 쪽인 앱이 거꾸로 환경을 확인한다는 발상이 신선했고, 보안 설계 관점에서 배울 점이 많았다. 참고로 SELinux는 안드로이드에서는 기본이지만, Ubuntu에서는 AppArmor를 사용한다. ReDroid는 이런 일반 리눅스 위에서 돌아가므로, 이러한 환경 차이에 대한 인식이 필요하다.

컨테이너는 호스트 커널을 공유하는데, ReDroid 공식 문서에도 Fedora 38 호스트에서는 SELinux를 먼저 꺼야 한다고 적혀 있다. 즉 컨테이너 환경의 SELinux 상태는 실제 폰과 다를 수 있고, 앱이 이를 환경 신호로 쓴다면 실제 기기와 에뮬레이터를 구분하는 단서가 될 수 있다. 어디까지나 가설이다.

금융 앱이 실행 환경을 이렇게까지 따지는 이유는 반대로 생각하면 이해가 된다. 이 앱이 어떤 환경에서 돌고 있는지를 모르면 앱 내부의 보호 장치를 믿을 수 없기 때문이다. 여기서 시큐어 코딩 이야기로 넘어간다.

시큐어 코딩에 대한 생각/경험

예전에 하드웨어 소모품 인증 같은 보안 모듈 개발에 참여한 적이 있다. 보안은 두더지 잡기가 아니라 톰과 제리다. 이미 고객에게 간 코드는 언젠가 풀릴 가능성이 높고, AI 때문에 그 속도는 더 빨라질 것이다. 공개된 자료도 같은 이야기를 한다.

  • OWASP 모바일 보안 검증 표준(MASVS)에는 변조와 역공학에 대한 저항(MASVS-RESILIENCE)이 별도 영역으로 있다. 난독화와 변조 탐지는 막는 장치가 아니라 시간을 버는 장치다
  • 2022년 USENIX Security에서 삼성 갤럭시(S8~S21) 하드웨어 키스토어의 설계 결함(CVE-2021-25444, CVE-2021-25490)이 보고됐다. 하드웨어 안의 키도 구현이 틀리면 뚫린다 (패치는 2021년 8월과 10월)
  • Play Integrity도 판정은 앱이 아니라 앱 서버가 검증한다. 클라이언트 안의 검사는 결국 클라이언트가 가장 잘 속일 수 있기 때문이다

그래서 내 결론은 제로 트러스트(Zero Trust)다. 기기도, 앱도, 네트워크도 기본으로 믿지 않고 매번 검증한다는 원칙이다.

  • 핵심 판단은 서버에서: 금액 한도, 이상 거래 탐지, 기기 증명 검증
  • 뚫린다는 전제: 탐지하고 폐기하고 갱신할 수 있는 경로를 처음부터 설계
  • 에이전트도 예외가 아니다: AI가 앱을 조작하더라도 돈이 움직이는 단계는 사람이 승인하고, 비밀 값은 대화에 남기지 않는다

다시 밝혀 두면, 이 글은 보안 우회 방법을 설명하는 글이 아니다. 테스트는 내 기기와 내 계정으로, 소액으로만 진행했다.

운영 환경: Oracle Cloud Free Tier

Oracle Cloud Free Tier가 ARM 인스턴스(Ampere A1)를 지원하므로, 그 환경에 ReDroid를 올려서 사용하면 된다. 공식 Always Free 리소스 문서 기준으로 알아 둘 점은 다음과 같다.

  • ARM(VM.Standard.A1.Flex) 한도: 월 1,500 OCPU 시간과 9,000 GB 시간, Always Free 테넌시 기준 2 OCPU와 메모리 12GB에 해당. 한 인스턴스에 몰아 쓰거나 1 OCPU 인스턴스 2개로 분할 가능
  • 스토리지: 부트 볼륨과 블록 볼륨을 합쳐 200GB, 아웃바운드 전송 월 10TB
  • 리전: Always Free 컴퓨트는 홈 리전에서 생성해야 하며, A1 인스턴스는 한국 북부(춘천) 리전 제외
  • 유휴 인스턴스 회수: 7일간 CPU 95퍼센타일, 네트워크, 메모리(A1)가 모두 20% 미만이면 유휴로 판단되어 회수될 수 있음

이 사양에서 ReDroid는 매우 쾌적하게 돌아갔고, 두 개를 띄웠을 때도 사용에 문제가 없었다. 다만 유휴 회수 조건은 상시로 띄워 두는 용도에서는 신경 써야 한다. ReDroid 자체의 준비물은 문서 기준으로 다음과 같다.

  • 호스트 커널: binder 모듈(binder, hwbinder, vndbinder)과 ashmem_linux 로드 필요
  • 실행: Docker에서 --privileged로 컨테이너 실행, adb 포트 5555 사용
  • MCP 등을 사용하려면 별도의 안드로이드 빌드 필요

공개 전에 보안부터: VPN 안에서만

이 환경은 금융 앱과 로그인 정보가 올라가는 곳이라 노출되면 피해가 크다. 보안 사고를 계기로 바로 실사용하려던 계획을 접었고, 지금은 꺼 둔 상태다. 다시 켤 때는 외부에서 직접 접근할 수 없게 막은 상태로만 쓸 생각이다. 아래는 그 계획이다.

  • 접근 경로: VPN(WireGuard, Tailscale 등 후보)에 접속한 기기에서만 접근 가능하도록 제한
  • 포트 노출 금지: adb(5555)와 원격 화면 중계 등 모든 서비스 포트를 공인 IP에 직접 열지 않음. ReDroid 문서도 adb 포트를 공개 네트워크에 노출하지 말라고 경고
  • 방화벽: Oracle 쪽 네트워크 규칙(보안 목록 등)에서 VPN 대역과 필요한 포트만 허용
  • 환경 복사 주의: 금융 앱이 설치된 환경의 백업, 스냅샷, 이미지도 로그인 정보가 남아 있을 수 있으므로 같은 수준으로 보호하고 외부에 두지 않음
  • 사용 방식: 소액 테스트 위주, 비밀번호는 대화에 남기지 않고 직접 입력하거나 비밀 저장소에서 꺼내 씀

VPN 구성은 아직 계획 단계이고, 적용하고 나면 방법과 확인 결과를 이어서 정리할 생각이다.

정리

  • 화면 조작 도구 네 개만 MCP로 열어 줘도 Claude는 앱 설치, 화면 탐색, 매뉴얼 작성, 게임 플레이까지 해냈다
  • QA 관점에서 쓸모가 크다고 본다. 사람이 하던 탐색적 테스트와 화면별 기록, 매뉴얼 작성을 에이전트가 맡고, 사람은 결과를 검토하는 구조가 가능하다
  • 경계도 분명했다. 돈이 움직이는 단계는 사람이 승인하고, 비밀 값은 대화에 남기지 않고, 중요한 판정은 서버에 둬야 한다
  • 로그인된 앱이 올라간 환경은 그 자체가 민감한 자산이다. 그래서 지금은 꺼 두었고, 다시 켤 때는 VPN 전용으로만 쓴다

참고 자료

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다