네트워크 관점에서 보는 IoT 분석 방법

R&D

•

2024.10.10

1️⃣ IoT 시대의 보안

저전력 MCU의 성능이 발전하고 센서의 성능이 높아지며 사용자의 생체 정보를 분석하고, IoT 장비의 이용 패턴을 학습하여 지능적으로 판단하는 추세로 변하고 있다. 이런 장비들 또한 필수적으로 필요한 기능 중 하나는 네트워크를 통한 통신이다.


우리에게 익숙한 가전제품이 IoT화 되어 네트워크를 통한 연결 접점을 형성하고, 의료기기 및 산업용 제어시스템(PLC, HMI, SCADA)도 IoT화를 통해 제어 및 관리 기능을 포함하는 추세이다. 최근 IoT 장비 분석을 진행하면서 외부 연결 접점을 분석하고 이를 통해 어떤 취약점을 도출할 수 있을지 고민해보는 계기가 되었다.


IoT 장비의 특성상 필수적으로 네트워크를 경유하며, 목적지는 사용자의 스마트폰 또는 IoT를 대상으로 만들어진 IoT Cloud 서버가 될 것이다. 이런 통신 과정 중 공격자는 어떤 분석 과정을 통해 악의적인 행위를 하는지, 이번 블로그 포스팅을 통해 프로젝트 간 있었던 경험을 공유하고자 한다.



2️⃣ IoT 장비의 네트워크 분석 목표

IoT 장비에서 발생하는 네트워크 트래픽 분석의 목표는 다음과 같다.


  1. 통신 과정에서 발생하는 패킷 내부 데이터 형식을 파악

    • JSON으로 전송되는 경우

    • 자체 형식을 개발하여 HEX로 소켓통신 하는 경우

    • 전송 시 암호화 과정을 거치지 않아 Plain text를 확보할 수 있는 경우



  2. 1번의 과정을 통해 어플리케이션이 아닌 외부 제 3자의 통신 전송이 임의로 장비를 조작할 수 있는지 분석

    • 적절한 인증 과정이 존재하지 않는 것을 확인

    • 인증 과정의 우회 가능한 경우 확인


3️⃣ IoT 장비 간 네트워크 통신 유형

장비가 스마트폰과 연결되는 방법은 보통 Wi-Fi와 블루투스를 이용하게 된다. 간혹 LTE 모듈을 통해 통신사를 경유하여 연결되는 경우도 존재한다. 이 중에서 네트워크 트래픽 분석을 위해 Wi-Fi를 사용하는 경우를 설명할 것이다. IoT 장비 간 네트워크 분석을 위해서는 장비가 어떤 방법으로 통신하는지, 그 유형을 먼저 알아봐야 한다.



IoT 장비가 Wi-Fi를 통해 네트워크에 연결되는 유형은 크게 3가지로 볼 수 있다.


  1. 장비가 스마트폰과 1 대 1로 연결되는 경우(장비 AP모드로 동작)

    가장 간단한 경우는 AP 모드로 다른 블루투스 동작 없이 기기의 전원을 인가하면 Wi-Fi 모듈을 통해 공유기처럼 동작하고 스마트폰은 해당 장비의 Wi-Fi에 연결하여 내부망 방식으로 통신하게 된다. 이 경우 연결 구조가 간단하고 분석용 스마트폰을 이용하면 네트워크 분석이 비교적 용이하다.




  2. 장비가 주변 Wi-Fi에 연결되어 같은 네트워크 망에서 통신하는 경우(STA 모드)

    장비가 스마트폰과 동일하게 주변 Wi-Fi에 연결하여 연결된 Wi-Fi 내부망 통신으로 어플리케이션의 제어 명령을 수행한다. 해당 방식도 중간에 공유기가 추가된 상황이나, 첫 번째 상황과 마찬가지로 분석용 루팅 처리된 스마트폰을 이용하여 tcpdump 및 Proxy 기능을 통한 분석이 가능하다.




  3. 장비가 IoT Cloud를 경유하여 스마트폰과 동기화 되는 경우(STA 모드)

    해당 방법은 요즘 많이 사용되는 방식이다. 블루투스를 이용하여 IoT 장비가 연결하고자 하는 Wi-Fi의 정보를 스마트폰과 교환하며, IoT 장비는 Wi-Fi 연결에 성공하면 IoT Cloud와 통신하게 된다. 그 이후 스마트폰과 IoT Cloud 간 설정 변경 동기화 과정을 거쳐 스마트폰으로 IoT 장비를 제어할 수 있다. 이 경우 장비가 연결되는 Wi-Fi 공유기에서 네트워크 패킷 캡처 및 라우팅을 통한 Proxy 과정이 필요하며, IoT Cloud와 동기화 되는 상황으로 스마트폰에서의 분석은 IoT Cloud 서버로의 공격이 발생할 수 있어 주의가 필요하다.



4️⃣ IoT 장비 네트워크에 적용할 수 있는 보안

해당 파트에서는 공격자가 Wi-Fi를 Dictionary Attack(사전 대입 공격), Brute Force Attack(무차별 대입 공격) 또는 공개된 Wi-Fi 연결 등의 방식으로 연결 가능하다는 것을 전제로 진행하였다. IoT 장비에 적용할 수 있는 네트워크 보안 기법은 다음과 같다.


4.1. IoT 장비와 스마트폰 간 직접 통신 암호화


IoT 장비에서 스마트폰과 이루어지는 통신에 공개키 암호화 과정을 코드화하여 AP 모드에 적용한 사례가 있었다. 이와 같이 통신에 사용되는 값에 대해 공개키 암호화를 하면 중요 정보 또는 제어 명령이 공개되거나 재전송되는 공격을 방지할 수 있다.



4.2. SSL 인증서 적용


웹 서버와 마찬가지로 가장 보편적으로 이용할 수 있는 방어 기법으로 SSL 인증서 적용이 있다. 이를 통해 통신에 사용되는 구간을 암호화하여 중요 정보 또는 제어 명령이 공개되는 것을 방지할 수 있다.



4.3. HPKP(HTTP Public Key Pinning)


IoT 장비에 인증서 보안을 적용하더라도 Proxy 기능을 이용하여 사설 인증서를 통해 네트워크를 경유하여 전송되는 암호화된 정보를 확인할 수 있다.


Proxy 도구를 사용하게 되면 사설 CA(Certificate Authority)를 사용하게 되고, 만약 IoT 장비와 연결되는 스마트폰 또는 IoT Cloud에서 이런 사설 CA 검증이 없다면 암호화된 통신 내용이 Proxy 도구를 통해 노출될 수 있다. 이런 문제를 해결하기 위해 HPKP(HTTP Public Key Pinning)이라는 기술을 사용하게 된다.


HPK Pinning 기술은 서버에서 요청이 들어오는 CA 기관 중 허용된 기관 여부를 판단하여 등록된 CA에 존재하는 인증서로 들어온 연결에 한해서만 연결하도록 한다.



5️⃣ 상황 별 네트워크 분석

5.1. IoT 장비와 스마트폰 간 1 대 1 통신 분석


해당 상황은 장비가 AP 모드로 동작하여 스마트폰과 1:1 환경으로 연결되거나(3.의 첫 번째) STA 모드로 동작하여 중간에 공유기가 존재하는 경우(3.의 두 번째)에 적용된다.


이 상황에서 패킷 수집 및 중간자 공격은 비교적 간단하다. 분석용 스마트폰이 있다면 해당 스마트폰으로 IoT 장비와 연결을 시도하고, 스마트폰에서는 TCP Dump를 통해 패킷을 확보할 수 있다. 또한 스마트폰에서 Proxy 기능을 이용하여 중간자 공격을 시도할 수 있다.


아래 사진은 루팅 처리된 분석용 스마트폰에서 Tcpdump를 통해 어플리케이션과 IoT 장비 간 발생하는 패킷을 캡처한 결과이다.




위 그림을 보면 JSON 형식을 이용해 장비 간에 평문으로 데이터 통신을 하는 것을 알 수 있다. 해당 정보를 이용하여 공격에 악용할 수 있다.


더하여 STA 모드로 동작하여 중간에 공유기가 존재하는 경우(3.의 두 번째) 스마트폰에서 패킷 수집이 불가능할 때(Rooting 탐지 등), 공유기를 스마트폰으로 변경하여 아래의 사진과 같은 망 구성으로 패킷을 수집하고 중간자 공격을 시도할 수 있다.





5.2. IoT 장비와 어플리케이션 간 암호화 통신 분석


해당 상황은 장비가 AP 모드로 동작하여 스마트폰과 1:1 환경으로 연결되거나(3.의 첫 번째) STA 모드로 동작하여 중간에 공유기가 존재하는 경우(3.의 두 번째)에 적용된다. 만약 4.1에서 언급했던 공개키 암호화 과정이 코드로 만들어 어플리케이션과 통신을 하는 경우, 모든 키를 구해 암호를 해독하는 것은 매우 번거로운 일이다.


아래 사진은 통신 간 공개키 암호화가 적용된 패킷이다.




패킷 내용을 보면 암호화 처리되어 내용을 알아볼 수 없는 값이 전송되는 것을 확인할 수 있다. 이때는 Frida Hook을 통해 어플리케이션에서 전송되는 데이터 영역이 암호화되기 전 지점에 Hook을 걸어 정보를 확인하고 이를 수정하는 코드를 작성하는 것도 하나의 방법이다. Frida Hook 스크립트를 작성하는 방법은 이 글의 주제를 벗어나 다루지 않는다.


아래는 Hook에 사용된 코드이다.


// hook.js

const S = "java.lang.String";
const B = "java.nio.ByteBuffer";
const I = "int";
const requestInfo = "";

const DASHCAM_RESPONSE_LISTENER = 'e1.b';
const DASHCAM_API = '-';
const SYSTEM_SETTING_API = 'c1.p'; // 'd.b.a.a.SystemSettingApi' // d.b.a.a.m
const JSON_OBJECT = 'org.json.JSONObject';
const BASE_API = 'c1.b';
const BASE_BO = '-';
const DASHCAM_CONSTANTS_ENUM = '-';




setImmediate(function () {
    Java.perform(function () {
        // SystemSettingApi 클래스 가져오기
        var BaseApi = Java.use(BASE_API); // d.b.a.a.m

        // A Method 후킹 (AE_SET_SETTING(2206))
        BaseApi.a.overload(JSON_OBJECT, BASE_BO, DASHCAM_CONSTANTS_ENUM, DASHCAM_RESPONSE_LISTENER).implementation = function (jSONObject, baseBO, dashcamConstantsEnum, dashcamResponseListener) {
            // console.log("a method called with arguments:");
            console.log("Response: " + jSONObject.toString());
            // console.log("BaseBO: " + baseBO.toString());
            // console.log("DashcamConstantsEnum: " + dashcamConstantsEnum.toString());
            console.log("DashcamResponseListener: " + dashcamResponseListener.toString());

            var result = this.a(jSONObject, baseBO, dashcamConstantsEnum, dashcamResponseListener);

            // console.log("Result: " + result);
            // console.log("BaseBO (after method call): " + baseBO.toString());

            return result;
        };


        var DashcamApi = Java.use(DASHCAM_API);

        DashcamApi.g0.overload('java.lang.String', DASHCAM_RESPONSE_LISTENER).implementation = function (str, dashcamResponseListener) {
            console.log("Request: " + str);

            try {
                var jsonObject = JSON.parse(str);
                console.log("Parsed JSON Object: " + JSON.stringify(jsonObject, null, 2));
            } catch (e) {
                console.log("Failed to parse JSON string: " + e);
            }
            
            var result = this.g0(str, dashcamResponseListener);

            console.log("Result: " + result);

            return result;
        };

        DashcamApi.h0.overload('java.lang.String', DASHCAM_RESPONSE_LISTENER).implementation = function (str, dashcamResponseListener) {
            try {
                var jsonObject = JSON.parse(str);
                console.log("Request: " + JSON.stringify(jsonObject, null, 2));
            } catch (e) {
                console.log("Failed to parse JSON string: " + e);
            }

            var result = this.h0(str, dashcamResponseListener);

            return result;
        };


    });
});

#hook.py

import frida
import sys

Hook_package = "-"
Hook_package2 = "-"

def on_message(message, data):
    print("{} -> {}".format(message, data))


jscode = open("hook.js", encoding='UTF8').read()

try:
    device = frida.get_usb_device(timeout=10)
    
    # pid = device.spawn([Hook_package])
    # print("App is starting.. pid:{}".format(pid))
    # process = device.attach(pid)
    # device.resume(pid)
    
    pid = device.get_process(Hook_package2).pid
    process = device.attach(pid)
    print("Attach.. pid:{}".format(pid))
    
    script = process.create_script(jscode)
    script.on('message', on_message)
    print("[-] Running FR1DA!")
    script.load()
    sys.stdin.read()

except Exception as e:
    print(e)


5.3. IoT 장비가 AP로 동작하나 제한적 연결 분석


해당 상황은 IoT 장비가 블루투스를 통한 어플리케이션 연결 여부를 확인하여 딱 1대의 기기만 Wi-Fi를 연결하게 설계된 IoT 장비들이 존재한다. 이러한 경우 분석용 스마트폰과 노트북을 이용하는 것도 방법 중 하나다.


요즘 스마트폰은 듀얼 밴드를 지원하여 한 쪽은 핫스팟 기능으로 AP 모드를 동작시켜 분석용 노트북을 연결하고, 다른 쪽 밴드는 Wi-Fi 연결에 사용하여 하나의 공유기처럼 동작한다.


아래 그림과 같이 5GHz 대역을 AP 모드로 동작시키고 2.4GHz는 IoT 장비의 Wi-Fi에 연결되는 것으로, AP 대역 IP와 외부 Wi-Fi는 가상 NAT로 동작하기 때문에 결국 스마트폰 IP로 IoT 장비에 도달하게 된다. 스마트폰 AP에 외부 장비를 연결하면 단 1개만 연결 가능한 제한을 벗어날 수 있다.




위 상황에서 분석용 스마트폰은 IoT 장비에 블루투스를 이용하여 어플리케이션 연결을 진행하고 먼저 장비 Wi-Fi에 연결한다. 그 후 2.4GHz와 5GHz 중 사용되지 않는 대역으로 핫스팟을 동작시켜 여러 대의 분석 기기가 IoT 장비와 통신할 수 있다.



5.4. STA 모드로 주변에 존재하는 Wi-Fi에 연결되어 IoT Cloud와 통신 분석


IoT Cloud를 구축하여 사용하는 경우, 대부분은 SSL 인증서를 통해 HTTPS 연결로 처리될 것이다. 이런 경우에는 분석이 까다로워진다. Proxy 기능을 사용자가 사용할 수 있다면 좋겠지만, 대부분의 IoT 장비에는 Proxy 기능이 없을 확률이 높다. 이때 시도해볼 수 있는 것은 iptables를 사용 가능한 공유기 2대를 사용하는 방법이다.


우선 간단한 개념을 먼저 설명하자면, 1번 공유기는 외부망에 연결된 공유기에 NAT로 연결되어 있다. 2번 공유기는 분석을 위한 PC가 연결되어 있는 상황이다.


일반적인 경우에는 다음 그림과 같이 [IoT 장비 → 1번 공유기 → 2번 공유기 → IoT Cloud] 순서로 통신이 진행된다.




IoT 장비에서 IoT Cloud에 패킷을 보낼 때, 1번 공유기에서 NAT를 통한 2번 공유기 대역으로 캡슐화가 이루어지고, 2번 공유기에서 해당 패킷은 외부망인 AR 라우터 대역 IP로 변환되는 캡슐화가 이루어진다.


만약 IoT 장비가 443 포트를 목적지로 하여 IoT Cloud와 통신하는 경우라면, 2번 공유기에 다음의 1번 명령어를 사용해 iptables를 적용하여 1번 공유기를 통해 들어가고 나오는 패킷을 2번 공유기에 연결된 PC IP로 패킷을 강제 리다이렉트 시킨다.


# 1. iptables 라우팅 룰 추가
iptables -t nat -A PREROUTING -p tcp -j DNAT --to 분석PC_IP:PORT#인바운드 패킷 라우팅
iptables -t nat -A OUTPUT -p tcp -j DNAT --to 분석PC_IP:PORT#아웃바운드 패킷 라우팅

#-----------------------------------------------------------------

# 2. iptables 라우팅 룰 제거
iptables -t nat -D PREROUTING -p tcp -j DNAT --to 분석PC_IP:PORT
iptables -t nat -D OUTPUT -p tcp -j DNAT --to 분석PC_IP:PORT

해당 설정을 완료하면 IoT 장비 → IoT Cloud 간 발생하는 패킷의 흐름은 다음 그림과 같은 [IoT장비 → 1번 공유기 → 분석용PC → IoT Cloud] 순서의 흐름을 가진다.



위 그림이 가능한 이유는 패킷이 네트워크 트리 구조를 역으로 올라가는 순서를 가지기 때문이다.


일반적으로 네트워크의 iptables는 다음과 같은 흐름을 가진다.



PREROUTING을 통해 들어온 패킷은 INPUT 필터를 거쳐 응용 프로그램으로 전달된다. 이후 응용 프로그램의 응답은 OUTPUT 필터를 거쳐 POSTROUTING으로 전달되며, 이후 외부로 나가는 구조이다.


이때 위 구문을 통해 iptables 명령으로 라우팅을 걸어주면 패킷의 흐름은 다음과 같다.



PREROUTING과 OUTPUT 필터에서 target Proxy를 거쳐가는 환경이 구축되었다. 해당 iptables가 설정된 환경에서는 다음과 같은 순서를 가진다.

  1. IoT 장비에서 발생한 패킷이 1번 공유기를 거쳐 2번 공유기에 들어왔을 때, iptables에 의해 목적지가 분석용 PC IP로 지정된다.

  2. 2번 공유기에서 분석용 PC에 패킷이 도달한다.

  3. 분석용 PC에 도달한 패킷은 분석용 PC를 출발지로 하는 캡슐화 과정을 거쳐 IoT Cloud를 목적지로 하는 패킷으로 변환된다.

  4. 패킷은 목적지 IP를 찾아서 2번 공유기를 경유해 IoT Cloud가 존재하는 외부망으로 나갈 수 있게 된다.

  5. 응답 패킷은 이의 역순으로 다시 IoT 장비에 도달하게 된다.


위 설정이 완료된 경우 분석용 PC에 Proxy 설정이 되어 있을 때 세션이 맺어지면 Proxy 도구를 통해서 중간자 공격이 가능하다. 다만 HPKP 보안이 적용된 기기는 인증서 확보 과정이 필요하다.


HPKP가 적용되면 사설 CA를 거부하여 세션이 연결되지 않고 RST패킷으로 끊어진다. 장비의 펌웨어를 분석하여 IoT Cloud 통신에 사용되는 인증서를 확보하고 분석용 PC에 적용하여야 정상적인 세션 연결이 가능하다.



아래는 통신에 사용되는 인증서가 확보되지 않은 상황에서, HPKP 기술이 적용된 IoT 장비와 IoT Cloud 간 통신에서 중간자 공격(MITM: Man In the Middle attack)이 Proxy를 통해 발생한 패킷이다.




사설 CA를 통해 연결 요청을 보내면, 위 그림에서 보는 것과 같이 Description: Unknown CA가 발생하고 RST 패킷이 발생하는 것을 확인할 수 있다.


이러한 과정으로 HPKP라는 Pinning 기술이 적용된 IoT Cloud에서 사설 CA 연결을 거부하며 외부에서의 중간자 공격을 방어한다.


이러한 경우, 장비의 펌웨어에서 IoT Cloud 통신 간 사용되는 인증서를 추출하여 Proxy 도구에 해당 인증서를 사용하도록 적용해야 중간자 공격을 성공할 수 있다.



TLS는 키 교환 알고리즘을 통해 암호화되어 인증서를 전송하기 때문에 네트워크 패킷 캡처를 통해서는 인증서 확보가 불가능하다.


[IoT 장비 ↔ 스마트폰] 환경에서는 펌웨어 분석에 실패하더라도 어플리케이션 분석이라는 경우의 수가 남아있지만, [IoT 장비 ↔ IoT Cloud : IoT Cloud ↔ 스마트폰] 환경에서는 Cloud 분석을 진행할 수 없어 펌웨어 분석밖에 시도할 방법이 없다.


따라서 인증서를 확보할 수 없다면 해당 보안 기법이 적용된 환경에서 중간자 공격은 불가능할 것이다.



6️⃣ 분석을 통해 얻은 것

이번 글에서는

  1. 1대1 통신 간 분석용 스마트폰을 이용하는 방법

  2. 통신 간 암호화가 적용되었을 때 Firda Hook을 이용한 방법

  3. 제한적 Wi-Fi 연결이 가능한 경우 모바일 핫스팟을 이용하는 방법

  4. 쉘 접근이 가능한 공유기 2대를 이용한 중간자 공격 방법

에 대해서 알아보았다.




이 방법을 통해 해커는 다음과 같은 공격을 행할 수 있다.

  1. 장비의 제어 명령어 전송을 통한 초기화 및 비정상적 동작(DoS) 유발

  2. 내부 부적절한 System 함수 처리 Chaining을 통한 Command Injection

  3. 일반 사용자에게 공개되지 않는 민감 정보 확보


위 분석 기법들을 통해 여러 IoT 장비에서 통신에 사용되는 정보들을 확인할 수 있었고, 암호화가 걸리지 않는 상황에서는 악의적인 명령 전송을 통해 장비의 이상 동작을 유발할 수 있었다. 또한 암호화를 적용하더라도 평문으로 제어가 가능한 장비 또한 존재했다.


이번 프로젝트에서 네트워크 분석에 관한 다양한 분석 기법을 공부하며 공격에 악용할 수 있는 기법을 알게 되었고, 네트워크 보안의 필요성을 다시 한번 느꼈다. IoT에서 모든 제어는 외부 통신으로 이루어지는 만큼, 네트워크 보안의 필요성을 다시 한번 느끼고 공부할 수 있는 계기가 되었다.


이번 글을 통해 IoT 장비의 네트워크 보안이 생각보다 취약한 장비들도 많다는 것을 깨달았으며, 다른 공격 기법에 대해 더욱 심도 있는 학습을 통해 블로그에서 내용을 나눌 수 있도록 하겠다.


Solutions

Services

Tech Blog

R&D

ZIEN

Contact Us

대표자명

조영민

Address

서울특별시 금천구 서부샛길 606 대성디폴리스 A동 1606, 1607호

Telephone

070-4571-9854

E-mail

support@zi-en.io

Ⓒ ZIEN Inc. All rights reserved.