본문 바로가기
SeSAC/어플리케이션 보안 & 취약점 진단

[SeSAC 성동캠퍼스 1기] 어플리케이션 보안 & 취약점 진단 5, 6일차

by zivvon 2023. 11. 21.
목차 접기

어플리케이션 보안 & 취약점 진단

[ Android 안드로이드 ]

 

▶ Frida : JS Injection을 이용해 Windows, macOS, Linux, ios, Android, and QNX 기반의 네이티브 앱에 대한 후킹이 가능한 파이썬 라이브러리

- DBI(Dynamic Binary Instrumentataion) 도구

- 스크립트를 이용한 대화형 가능

- PC뿐만 아니라 모바일 플랫폼도 지원하여 모바일 악성코드 분석이나 CTF 풀이에도 많이 활용됨

 

1. 설치
pip install frida
pip install frida-tools​

 


 

💡오늘의 실습!

ip 세탁하기!

 

import requests

# ip 세탁
proxies = {
    "http" : "socks5h://127.0.0.1:9150",
    "https" : "socks5h://127.0.0.1:9150"
}

response = requests.get("http://ip-api.com/line", proxies = proxies)
print(response.text)

바뀐 IP와 국가!

 


 

[ Android 안드로이드 ]

 

▶ 안드로이드 역사

- Linux 커널 기반

- 구글 제작 및 배포 (Android Open Source Project)

- 주로 Java 언어로 제작

~> Native C, C++ 가능

~> 최근 Kotlin

 

▶ 안드로이드 아키텍처

 

- 커널 계층

~> 리눅스 커널을 기반으로 제작된 OS

~> h/w, 네트워크, 파일 시스템 접근 등 시스템 전체의 중심 역할 수행

~> 보안 설정, 메모리 관리, 전원 관리, 네트워크 시스템 관리, 장치 드라이버 관리

 

- HAL(Hardware Abstraction Layer)
~> 하드웨어 추상화

~> Java API 프레임워크에 기기 하드웨어 기능을 노출하는 표준 인터페이스 제공

~> 카메라 또는 블루투스 모듈과 같은 특정 유형의 하드웨어 구성 요소 제공

 

- 네이티브 C/C++ 라이브러리 계층

~> 네이티브 라이브러리를 제공하기 위한 계층

~> FreeFont : 폰트, Webkit : 브라우저 엔진, Media : 코덱, SQLite : 경량 DB

~> C 또는 C++ 코드가 필요한 앱 개발시 Android NDK 사용

 

- 런타임 계층

~> ART (구 Dalvik)

~> 자바 바이트 코드를 *DEX 포맷으로 패키징 후 실행

* DEX(Dalvik EXcutable)

~> Dalvik은 *JIT 채택

* JIT(Just In Time) : 앱이 실행되는 순간 사용되는 코드를 컴파일, 설치는 빠르지만 실행이 느림

~> AOT(Ahead of TIme) : 앱 설치 시 모든 코드를 컴파일, 실행 빠르지만 배터리 속도가 느림

 

- JAVA API 프레임워크 계층

~> JAVA API가 존재

~> 안드로이드 OS 기능은 해당 API를 통해 접근

~> Activity Manager, Content, Provider, Telephony Manager, Resource Manager, Notificaiton Manager

 

- 어플리케이션 계층

~> 시스템 어플리케이션

  • /system 디렉토리에 존재, 사용자가 제거/변경 불가
  • 안드로이드 핸드폰 구매 시 내장
  • SMS 메시지 어플리케이션 등이 해당

~> 사용자 어플리케이션

  • /data 디렉토리에 존재, 사용자가 제거/변경 가능
  • 각각의 어플리케이션은 샌드박스에 설치되어 영향을 주거나 데이터 통신 불가
  • 각 어플리케이션의 권한을 가진 리소스에만 접근 가능
  • 카카오톡과 같은 일반 어플리케이션 등이 해당

▶ 앱 컴포넌트

- 앱 컴포넌트는 안드로이드 앱의 필수적인 구성 요소로 각 독립된 형태로 존재하며 정해진 역할 수행

- 각 구성 요소는 시스템이나 사용자가 앱에 들어올 수 있는 진입점

- "Intent"는 다른 앱 컴포넌트로부터 작업을 요청하는 데 사용할 수 있는 메시징 객체

 

▶ 액티비티

- 사용자와 상호작용 위한 진입점

- 사용자 인터페이스(UI)를 포함한 화면 하나를 나타냄

 

▶ 서비스

- 백그라운드에서 앱을 계속 실행하기 위한 다목적 진입점

- 사용자 인터페이스(UI)를 제공하지 않음

- 사용자가 다른 앱을 실행하고 있는 동안 백그라운드에서 동작 ex) 음악 재생, 네트워크 통한 통신 

 

▶ 브로드 캐스트 리시버

- 시스템이 정기적인 사용자 플로우 밖에서 이벤트를 앱에 전달하도록 지원하는 컴포넌트

- 대다수의 브로드 캐스트는 시스템에서 발생 (화면 꺼짐, 배터리 부족, 사진 캡처, 카톡 등)

- 일반 앱도 브로드 캐스트를 사용하여 사용자 인터페이스를 표시하지 않지만, 상태 표시줄 알림을 생성

 

▶ 콘텐츠 프로바이더

- 콘텐츠 제공자는 파일 시스템, SQLite, 웹상이나 앱이 접근할 수 있는 다른 영구 저장소에 저장 가능한 앱 데이터의 공유형 집합을 관리

- 사용자의 연락처 정보를 관리하는 콘텐츠 제공자를 제공

 

▶ Android Rooting 안드로이드 루팅

- 안드로이드 루팅

Q. 루팅(Rooting)이란?

A) 모바일 기기에서 구동되는 안드로이드 운영체제(OS) 상에서 최상위 권한(루트 권한)을 얻음으로 해당 기기의 생산자 또는 판매자 측에서 걸어 놓은 제약을 해제하는 행위

ㄴ ios 운영체제에서는 탈옥(Jailbreak)라고 함

 

~> 루트 접근 권한을 얻어 완전히 제어하는 것이 루팅

~> 루팅된 디바이스에서 $가 아닌 #루트 쉘을 가진 UID 0이 존재

 

Q. 왜 안드로이드 루팅을 하는지?

A) 사용하는 사용자마다 목표가 다름(하드웨어 제조업체 및 이동 통신사 제한을 풀어 디바이스를 완전히 제어), 더 아름다운 테마를 사용하기 위해, 루트 권한 없이 설치할 수 없는 앱을 설치하기 위해, 파일 시스템과 앱을 감시하기 위해(침투 테스팅)

 

- 안드로이드 루팅 단점

~> 디바이스의 보안 손상 : 루팅된 디바이스에서 루트 넙근 권한이 있는 악성 앱에는 이 제한이 없어 실행 중인 다른 앱에서 데이터 접근 가능

~> 장치 벽돌 : 루팅 프로세스는 디바이스를 손상시켜 쓸모 없게 될 수 있음

~> 무효 보증 : 루팅된 디바이스는 보증이 무효화 됨, 루팅한 후에는 보증기간 중이어도 수리비용 지불할 수도

 

- 샌드박스 SandBox

: 보호된 영역 내에서 프로그램을 동작시키는 것으로, 외부 요인에 의해 악영향이 미치는 것을 방지하는 보안 모델

: Google "제대로 구성된 장치에서 샌드박스를 벗어나려면 리눅스 커널의 보안을 손상시켜야 한다."

 

- 리눅스 기반 시스템의 root 권한은 모든 작업을 수행할 수 있는 최고 사용자 수준

- 안드로이드/리눅스에서는 소수 핵심 유틸리티만 root 권한으로 실행됨

- 장치를 Rooting하면 실행 중인 모든 앱에서 root 권한으로 사용 가능

 

▶ JVM & DVM

- JVM(Java Virtual Machine) : 자바 바이트 코드를 실행하기 위한 자바 가상 머신

~> 자바 바이트 코드는 JVM이 이해할 수 있는 언어로 JVM만 설치되어 있으면 어떤 자바 운영체제에도 실행 가능

~> JVM은 플랫폼에 의존적 (리눅스, 윈도우, MacOS의 JVM은 각각 다름)

~> 자바 바이트 코드는 플렛폼에 독립적 (컴파일된 자바 바이트 코드는 어떤 JVM에서든 동작 가능)

 

~> 스택 기반

  • 연산할 때 스택 사용
  • PUSH, POP과 유사한 연산자 사용
  • Java Code 예제는 Stack을 이용하고 있음
  • Windows 시스템도 Stack 기반

 

- DVM(Dalvik Virtual Machine) : 안드로이드 어플리케이션을 실행하기 위한 달빅 가상 머신

~> 모바일 디바이스 환경에 최적화 되어 개발된 가상머신으로 낮은 메모리에서 실행되도록 설계

~> 자바 바이트 코드로 변환되는 동일한 과정을 거친 후 추가적인 단계 진행

~> DEX 컴파일러가 class 파일을 dex로 변경하여 DVM에서 실행 가능하게 생성

      ㄴ .java 파일은 자바 소스 코드, .class 파일은 자바 바이트 코드

 

~> 레지스터 기반

  • 연산할 때 레지스터 사용
  • CPU 레지스터 기반으로 피연산자가 저장
  • PUSH, POP 연산자 없이 간단한 명령어로 동작
  • DEX를 디컴파일 하여 smali 코드에서 확인

~> Dalvik의 명령어 수가 더 적고, 코드 길이는 더 긺

 

 

 

▶ ART(Android RunTime)

- 퍼포먼스 개선 등을 위해 구글이 DVM에서 ART로 변경

- 성능 향상을 위한 DVM의 "JIT 컴파일" 프로세스를 "AOT 컴파일"로 변경

- 2016년도 안드로이드 누가 7.0 이후 JIT와 AOT 컴파일 모두 사용

- AOT 컴파일, GC(Garbage Collection) 개선

 

▶ JIT & AOT

- JIT(Just In Time) : 동적 변역(Dynamic Translation)이라고도 함

~> 앱 최초 실행하는 시점에 기계어로 번역

~> 하드웨어 부하로 배터리 시간 등 부정적인 영향

  • 장점 : 용량 낮고, 설치 속도 빠름
  • 단점 : 실행 속도 느리고, 배터리와 CPU 사용 많음

- AOT(Ahead Of Time)

~> 2014 안드로이드 롤리팝(5.0 API 21) 이후 ART(AOT)가 적용

~> 앱 설치 시점에서 컴파일 수행

~> 전력 소비 줄이며 성능을 2배 향상

  • 장점 : 실행 속도 빠르며, 배터리와 CPU 사용 적음
  • 단점 : 용량 높고, 설치 속도 느림

▶ JIT + AOT

- 2016 안드로이드 누가(7.0 API 24) 이후 ART에서는 JIT와 AOT 컴파일 모두 사용

- JIT와 AOT 모두 사용하여 설치시에는 무조건 JIT를 사용하고 차후 상황에 따라 유연하게 적용되어 사용됨

 

▶ JVM & DVM & ART의 컴파일 과정

 

 

▶ 코드 서명

- JAR 서명 기법을 이용해 어플리케이션간 신뢰 관계 설정을 위해 APK 파일 서명

- 서명을 통한 설치된 대상 어플리케이션의 인증서와 업데이트 할 어플리케이션 비교

 

▶ 권한

- 샌드박스를 이용하여 어플리케이션 설치 시 고유한 UID/GID를 할당

- 생성되는 디렉토리 및 파일은 소유자 및 그룹 외 내용 확인 불가

 

▶ APK(Android Package Kit) : 안드로이드에서 프로그램 형태로 배포되는 형식의 파일

- JAR를 확장한 포맷이며, Zip 압축 포맷을 가짐

- CAFE Signature

- 패키지 파일 설치 경로

/data/app/패키지명
/data/data/패키지명

 

▶ DEX 구성 ⭐

- Dalvik Excutable = DEX

- Java로 짜여진 Class

- Class들의 모임

 

▶ META-INF

- Signature File

- 공개키를 담은 인증서

 

▶ res

- 어플리케이션이 사용하는 리소스(레이아웃, 문자열 등) 존재

 

▶ AndroidManifest.xml

- 패키지 정보, 권한, 앱의 구성 요소(Activity 등) 정보를 포함한 파일

 

~> Activity : 일반적으로 하나의 뷰를 설명, 해당 Activity의 속성 정의

~> Service : 백그라운드에서 실행되는 서비스

~> Broadcast Receiver : 안드로이드 내부 이벤트 핸들링을 위한 컴포넌트 ex) 문자수신, 배터리 부족

~> Content Provider : 어플리케이션간 데이터 공유를 위한 컴포넌트

 

▶ Classes.dex

- 어플리케이션 실행을 위한 코드가 존재

 

▶ Resources.arsc

- 컴파일된 리소스(문자열, 스타일 등)가 존재

 


 

💡오늘의 실습!

강사님이 만든 사이트에 GET, POST 요청 보내기

 

1. requests 모듈 설치
pip install requests​

2. py 코드 짜기
- GET 방식
import requests

data = {
    "id" : "admin",
    "password" : "p@ssw@rd"
}

proxies = {
    "http" : "socks5h://[ip 주소]:[포트번호]",
    "https" : "socks5h://[ip 주소]:[포트번호]"
}

response = requests.get("url", 
                         data = data, proxies=proxies)
print(response.text)

- POST 방식
import requests

data = {
    "id" : "admin",
    "password" : "p@ssw@rd"
}

proxies = {
    "http" : "socks5h://[ip 주소]:[포트번호]",
    "https" : "socks5h://[ip 주소]:[포트번호]"
}

response = requests.post("url", 
                         data = data, proxies=proxies)
print(response.text)

 

 


 

오늘의 후기! :