안드로이드 앱 자동화 (상점 스크랩, 도어락 자동화) – 1편

Table of Contents

안드로이드 앱 자동화 (상점 스크랩, 도어락 자동화) - 1편

1. 서론

어느날 친구녀석이 전화를 걸어왔다.

...
친 : 야 꿈늑아 너 혹시 도어락 자동화 같은거 해 본 적 있냐?
친 : 이거 인터넷으로 제어 가능한거라
친 : 연습실 예약 들어오면 자동으로 해당 시간에 고객 전화번호로 비밀번호 넣고싶은데
나 : 아... 잘 모르겠는데 뭔지 좀 봐야 알수 있을거 같아.
나 : 도어락은 어떻게 제어 하는데?
친 : 스토어에서 직방 도어락 검색해서 앱 깔면 돼.
나 : 앱이라고? 혹시 PC 용은 없어?
친 : 모르겠는데? 일단 앱부터 깔아봐.
...

이때는 몰랐다. 이게 이렇게 기나긴 삽질이 될 줄은.....

일단 친한 친구 부탁이기도 하고 해서 간단한거면 빠르게 작업하고 마칠까 생각했...었다.

해서 간단하게 가능성 테스트 부터 해 보기로 했다.

코드 참고 등은 2편 부터 보시는걸 추천 드린다.

2. 구상

간단하게 큰 그림부터 그려보자!

  • 우선 친구녀석은 제주도에서 댄스 연습실을 경영한다.

  • 도어락은 "직방" 브랜드에서 판매되는 기종이다.

  • 입점된 "네이버 스마트 스토어" 에서 주문을 읽어온다.

  • 읽어온 주문에서 전화번호를 발췌하여 도어락에 전송한다.

  • "아마도" 네트워크 패킷을 스니핑 해 보면 오가는 데이터 분석이 가능할듯?

  • 그러면 아마도 자동화가 가능하지 않을까?

  • 그럼 간단하게 스프링부트 어플리케이션으로 만들어서 구동하면 되겠네!

  • 간단하겠네! ㅋㅋㅋ

2. 기초조사 (가능성 테스트)

여기까지 대충 생각해보고 다음과 같은 테스트를 해 보았다.

  • 우선은 도어락 앱 에서 어떤 신호를 내보내는지 파악해 볼 필요가 있다.
    이게 제일 중요하다. 이거 안되면 시작도 못하고 끝나는거다.

  • 안드로이드 에뮬레이터(android-x86) 를 구동해서 도어락 앱을 구동시킨다.
    에뮬레이터는 qemu 를 사용했다 (호스트머신에서 세부 조작이 가능하기 때문)

  • 호스트머신은 Lubuntu 22.04.4 LTS (Jammy Jellyfish) 설치.

  • 안드로이드 에뮬레이션 셋팅은 다음과 같다. (전에 공부할때 쓰던 템플릿이라 불필요한 셋팅이 많다...)

#!/bin/bash
QEMU_HOME=/home/user/qemu
QEMU=qemu-system-x86_64
VM_HOME=${QEMU_HOME}/Android
DISK1=${VM_HOME}/disk.img DISK1F=raw
ODDR=${QEMU_HOME}/tools/empty.iso
MON=${VM_HOME}/.mon
LOG=${VM_HOME}/.log 
PCP=${VM_HOME}/.pcap
SPICE=5903

CMD="${QEMU} \
  -name Android \
  ${__GLOBAL_SETTINGS__}\
  -nodefaults \
  -no-user-config \
  -enable-kvm \
  -global kvm-pit.lost_tick_policy=discard \
  -global PIIX4_PM.disable_s3=1 \
  -global PIIX4_PM.disable_s4=1 \
  -object iothread,id=iothread0 \
  -object filter-dump,id=pcap0,netdev=netdev0,maxlen=65535,file=${PCP} \
  -rtc base=localtime,clock=rt,driftfix=slew \
  -audiodev driver=spice,id=adspice,timer-period=7000,out.frequency=11025,out.channels=1,out.format=u8 \
  -boot menu=on \
  -monitor unix:${MON},server,nowait,nodelay \
  -qmp tcp:*:4444,server,nowait,nodelay \
  -D ${LOG} \
  ${__MACHINE_SETTINGS__}\
  -machine pc,accel=kvm,kernel_irqchip=on,igd-passthru=on,hpet=off  \
  -cpu qemu64 \
  -smp 4,sockets=1,cores=2,threads=2 \
  -m 4G \
  ${__MOTHERBOARD_SETTINGS__}\
  -device pci-bridge,id=pci.1,bus=pci.0,addr=0x1c.0,chassis_nr=3,multifunction=on \
  -device pci-bridge,id=pci.2,bus=pci.0,addr=0x1c.1,chassis_nr=4,multifunction=on \
  -device pci-bridge,id=pci.3,bus=pci.0,addr=0x1c.2,chassis_nr=5,multifunction=on \
  -device pci-bridge,id=pci.4,bus=pci.0,addr=0x1c.3,chassis_nr=6,multifunction=on \
  ${__DEVICE_SETTINGS_PCIE__}\
  -device qxl-vga,id=vga-pri,bus=pci.0,addr=0x02.0,multifunction=on,ram_size=67108864,vram_size=67108864,vgamem_mb=16 -spice port=${SPICE},disable-ticketing=on \
  -device AC97,id=sound0,bus=pci.0,addr=0x1c.4,audiodev=adspice \
  -device virtio-scsi-pci,id=scsi0,iothread=iothread0,ioeventfd=on,num_queues=4,bus=pci.0,addr=0x1c.5,multifunction=on \
  -device qemu-xhci,id=usb2,bus=pci.0,addr=0x1c.6,multifunction=on \
  -device qemu-xhci,id=usb3,bus=pci.0,addr=0x1c.7,multifunction=on \
  ${__DEVICE_SETTINGS_PCI__}\
  -device virtio-net-pci,netdev=netdev0,id=net0,bus=pci.2,addr=0x02.0,mac=52:54:00:12:34:04 -netdev user,id=netdev0,net=192.168.1.0/24,host=192.168.1.1,dhcpstart=192.168.1.2 \
  -device usb-ehci,id=usb0,bus=pci.3,addr=0x01.0,multifunction=on \
  -device piix4-usb-uhci,id=usb1,bus=pci.3,addr=0x01.1,multifunction=on \
  ${__DEVICE_SETTINGS_ISA__}\
  -device pvpanic,id=panic0,bus=isa.0 \
  -chardev file,id=parallel,path=${VM_HOME}/.lpt \
  -device isa-parallel,chardev=parallel,bus=isa.0,iobase=0x378,irq=7,index=0 \
  -chardev spicevmc,id=spicechannel,name=vdagent \
  -device virtio-serial-pci,bus=pci.4,addr=0x10.0 \
  -device virtserialport,chardev=spicechannel,name=com.redhat.spice.0 \
  ${__USB_SETTINGS__}\
  -device usb-tablet,id=usb-tablet,bus=usb0.0,port=2 \
  ${__STORAGE_SETTINGS__}\
  -drive file=${DISK1},if=none,media=disk,id=drive1,format=${DISK1F},cache=none,aio=native,discard=ignore,readonly=off \
  -device virtio-blk-pci,drive=drive1,bootindex=2 \
  -drive file=${ODDR},if=none,media=cdrom,id=drive-cd,format=raw \
  -device ide-cd,drive=drive-cd,bus=ide.0,bootindex=1 \
  -daemonize
"
${CMD}
sleep 1
echo "hostfwd_add netdev0 tcp::5555-:5555" | socat - unix-connect:${MON} > /dev/null
  • 무슨 은행앱도 아니고 루팅감지가 되어있어 언루팅까지 해 주어야 한다.
    언루팅은 Impactator unroot (com.andreacioccarelli.impactor) 가 제일 깔끔했다.

  • 자 이제 패킷을 캡쳐해보자 (qemu 셋팅에 filter-dump 설정으로 pcap 덤프가 된다)

  • 임시 비밀번호 하나를 등록하고

  • wireshark 를 틀어 pcap 파일을 들여다 본다...

  • 뭔소린지 모르겠다..

당연하겠지만 아마도 암호화 통신을 하는것 같다. 그래도 뭔가 힌트는 있겠지 기대했는데... Human-Readable 한 문자는 노출되지 않았다.

"할수 없지 뭐." 가장 기본이 되는게 패킷 분석인데 힌트가 될만한게 없으니 친구한테 보고한다.

...
나 : 야 이거 아무래도 안되겠는데? 날패킷 뜯어봤는데 읽을수 있는게 없어.
나 : 일 하면서 개인 프로젝트로 진행하기는 무리일듯해
친 : 아. 그래? 그정도로 어려운거야?
친 : 나는 오토마우스 정도로 생각했는데.
친 : 안쓰는 핸드폰 하나 붙여서 클릭 자동화 하는 방식으로는 어떻게 안되나?
나 : ..... (곰곰히 생각해 본다)
나 : 오토마우스? 아... 그거면 어떻게 좀 될수도 있겠는데?
...

.... 아무래도 낚여 버린거 같다....

그래서 이 험난한 "도어락 자동화 프로젝트 (안드로이드 앱 자동화 )" 프로젝트의 여정이 시작하게 되었다..

[ 2편에서 계속.. ]

[ 관련 소스 저장소 ]

답글 남기기

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