Modbus 프로토콜

JENJULYJOY·2025년 12월 8일

산업보안

목록 보기
5/6

Modbus

공장 컨베이어, 온도 센서, 펌프, 밸브, PLC등에 사용되는 가장 오래된 프로토콜 중 하나이다.
단순하지만 장비 제어와 모니터링에 필요한 기능들을 수행할 수 있기에 사실상의 표준 프로토콜의 지위를 얻게 되었고, 현재까지 산업용 전자 장치들을 서로 연결하는 목적으로 널리 사용된다. 무료이며 설치와 유지보수가 용이하다.

1-1. Modbus 특징

-암호화 및 인증 없음(평문)
-단순하고 신뢰성이 높지만 보안이 적용되지 않음
*여기에서 신뢰성이 높다는 건 보안이 아니라 동작 안정성(Operational Reliability)에 해당된다. 공장 가동에 있어서 중단되지 않고 예측대로 작동하는 것을 의미한다.

1-2. Modbus Function Code

Modbus 통신에서 PLC에게 무슨 작업을 할지 지시하는 명령 종류
🔗참고사이트

e.g.
PLC야 값 읽어와 → Function Code 03
PLC야 펌프 켜 → Function Code 05
PLC야 온도를 75도로 설정해 → Function Code 06

[예시 상황]
03 (Read) → 현재 온도: 79°C
06 (Write) → 현재 온도: 80°C
공격자가 06을 300°C로 설정 → 폭발 가능

1-3 Function code 별 탐지 규칙

📌Snort/Suricata Modbus 탐지 규칙 구조

alert tcp any any -> any 502 (msg:"Modbus FC06 Write detected"; flow:to_server,established; content:"|06|"; offset:7; depth:1; sid:10001; rev:1;)

FC 03 - Read Holding Register (정찰 탐지)

alert tcp any any -> any 502 (
    msg:"ICS - Modbus Read Holding Register (FC=03)";
    flow:to_server,established;
    content:"|**03**|"; offset:7; depth:1;
    sid:20001; rev:1;
)

해킹의 정보 수집단계에서 자주 사용됨

FC 05 - Write Single Coil (물리 제어 가능)

alert tcp any any -> any 502 (
    msg:"ICS - Modbus Write Single Coil (FC=05)";
    flow:to_server,established;
    content:"|**05**|"; offset:7; depth:1;
    classtype:attempted-user;
    sid:20005; rev:1;
)

공격자가 밸브 ON/OFF 모터 정지 시도 시 탐지해야하는 룰

FC 06 - Write Single Register (Stuxnet 계열에서 자주 사용)

alert tcp any any -> any 502 (
    msg:"ICS - Modbus Write Single Register (FC=06)";
    flow:to_server,established;
    content:"|**06**|"; offset:7; depth:1;
    classtype:attempted-dos;
    sid:20006; rev:1;
)

RPM 변경, 온도 변경, 속도제어 → 위험도 매우 높음

FC 16 - Write Multiple Registers (가장 위험)

alert tcp any any -> any 502 (
    msg:"ICS - Modbus Bulk Register Write (FC=10/16)";
    flow:to_server,established;
    content:"|10|"; offset:7; depth:1;
    classtype:attempted-admin;
    sid:20016; rev:1;
)

공격자가 한번에 여러 설정값 변경 -> 작동 중단, 재해 발생 가능

1-4. 탐지룰 Threshold

정상 운영 중에도 write는 가끔 사용하므로 횟수 조건을 추가해주는것이 좋다.

threshold: type threshold, track by_src, count 10, seconds 5;

평소에 한번 사용되는 write가 10회 이상 연속 발생할 경우 의심한다.

참고 사항
💡Write 계열(05/06/15/16)은 탐지가 아니라 막아야 하는 트래픽으로서 방화벽+ICS IDS+OT 정책으로 지정된 시스템만 허용한다.
💡Read 계열(01~04)은 정상 운영되는 트래픽이지만 과도한 Read는 정찰 공격을 의심해보아야 한다.

1-5. 안전하게 Modbus 사용하는 방법

🔗참고사이트

  • Modbus/TCP 는 암호화와 인증을 지원하지 않아, 산업 현장에서는 방화벽, 네트워크 분할, IDS/IPS 등 다층 방어 체계를 반드시 도입해야 한다
  • ACL(Access Control List) 기반으로 허용된 IP, 인터페이스만 통신하도록 한다.
  • Modbus gateway 보안 강화를 위해서는 백리스트보다 화이트리스트, VPN, ACL, 로그 모니터링을 적용한다.
  • 네트워크 세분화 (segmentation) 및 로그/모니터링을 활성화한다.

1-6. Modbus 통신 확인하기

⚙️필요한 도구
1. Simply Modbus
Modbus Client Tester(SCADA/HMI 역할)
2. Ananas
Modbus Master(Slave/PLC 역할)

[실습]
0. Simply Modbus를 설치하고 PC재부팅을 한 번 한다.
(설치 후에 재부팅을 안하면 프로그램이 애초에 열리지 않음)
ananas는 그냥 켜두기만 하면 된다.

  1. Simply Modbus의 좌측 상단 설정을 아래와 같이 변경한다.
Mode: TCP
IP Address: 본인 IP주소
Port: 502
Slave ID: 0

참고로 나는 인터페이스(IP)에 대해 502 포트를 열어뒀기 때문에 내 PC가 가진 모든 IP로 통신이 가능했다.

netstat -ano | findstr :502
  1. register 설정도 아래와 같이 변경한다.
First Register: 0
No. of Regs: 10
Function Code: 3 (Read Holding Registers)
Use defaults register size: 체크 ON
  1. NOT CONNECTED → CONNECTED → SEND 버튼 클릭

여기까지 했는데 진행이 안될 때. . .
원인 1. 방화벽이 막고 있음

Windows 검색 → 제어판 → Window Defender 방화벽
고급설정 → 인바운드 규칙 → 새 규칙
→ 포트(port) 선택 → TCP / 502
→ 허용 → 완료

원인 2. IP 주소가 잘못되었을 가능성

원인 3. Ananas 서버가 실제로 Listen 중인지 확인



전체 설정 후 정상적으로 통신하는 것을 확인했다.


내가 설치한 Simply Modbus은 데모 버전이라서 일정 횟수 이상(대략 10회정도) SEND를 누르면 경고창이 뜨는데 프로그램을 재시작하면 해결된다.

다음은 실습을 하면서 알게 된 사실을 정리한 내용이다.

Modbus의 구조

Modbus는 Server-Client(Master-Slave) 구조이다.
서버는 값을 저장하고 있는 저장소같은 역할을 하고, 클라이언트는 그 값을 읽어드린다.

내가 사용한 프로그램의 역할

Ananas는 Sever(Slave) 역할을 하는 프로그램이며, OT 장비로 비유하면 센서로부터 받아들인 신호를 통해 장비를 작동시키는 제어장치인 PLC이다.
프로그램엔 레지스터의 값이 저장되어 있고 클라이언트가 값을 물어보면 응답한다.
Simply Modebus는 Client(Master)의 역할을 하는 프로그램으로, 값을 Read 하거나 Write한다. Server에게 어떤 값을 달라고 요청하고 그 값을 받아서 화면에 표시한다.
즉, 수집된 데이터를 운영자에게 시각적으로 보여주는 SCADA나, 사람이 이해하기 쉬운 그래픽 화면으로 데이터를 표시하고 제어하는 인터페이스인 HMI와 비슷하다.

화면에 뜬 값이 의미하는 것


이미지 출처: http://comfilewiki.co.kr/
1) MBAP Header(7bytes)
클라이언트가 요청을 보낼 때 넣은 값

00 01

Protocol ID
Modbus는 항상 0000 사용

00 00

Length
뒤에 따라오는 전체 PDU 길이(23bytes)

00 17

Unit ID(Slave ID)
Slave ID = 0 을 의미(Modbus TCP에서는 거의 의미 없음)

00

2) PDU
Function Code
Holding Register Read(0x03)이 성공했다는 의미

03

Byte Count
데이터 부분에 20바이트(=레지스터 10개)가 들어있다는 의미
0x14 = 20

14

3) Register Data (20 bytes = 10 registers)
Ananas 서버에서 값을 바꾸지 않았기 때문에 전부 0

00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00


Ananas의 Register 0의 value를 123으로 변경하고 결과가 달라지는지 확인해보았다.


123은 16진수로 0x007B이므로 응답안에 00 7B가 들어간다.
Ananas에서 변경된 값을 읽어와 응답값을 잘 바꿔주는 것을 확인할 수 있었다.



<험난했던 Modbus 테스트 환경 구축 과정>

처음에 ModbusPal로 Slave 설정까지 마쳤지만, 해당 버전이 TCP 서버 기능을 제대로 지원하지 않아 통신 테스트가 어려웠다. 이후 Modbus Poll, QModMaster 등 여러 툴을 시도했으나 TCP 기능이 없거나, 라이선스 제한으로 기능 사용이 어려웠다.

최종적으로 Ananas를 서버로 사용하고,Simply Modbus TCP Client를 클라이언트로 설정하여 정상적으로 Read Holding Registers 응답을 수신할 수 있었다.

이 과정에서 포트 점유 확인, 방화벽 설정, 네트워크 대역 체크 등 여러 단계를 거쳤고, 결과적으로 Modbus TCP 통신 구조(서버–클라이언트 방식)에 대한 이해도 함께 높아져서 좋다.

profile
Information Security🔐 & Industrial Security⚙️

0개의 댓글