By RUGERO Tesla (@404Saint).
A packet-level security study of IEC 60870-5-104, combining protocol architecture, raw APCI/ASDU experimentation, implementation boundary testing, and a controlled comparison against IEC 62351 security mechanisms.
IEC 60870-5-104 is one of those protocols where understanding the security problem requires going below the usual “port 2404 is exposed” discussion.
A TCP connection is only the beginning. Before an ASDU is exchanged, the protocol establishes its own link state through APCI control frames. Once data transfer is active, numbered I-frames carry telemetry and commands, while S- and U-frames maintain the session and its state. That structure makes the protocol interesting to study from the wire level.
For this research, I built an isolated IEC 60870-5-104 laboratory around lib60870-C, wrote raw Python protocol harnesses rather than relying exclusively on a high-level IEC 104 client, captured the resulting traffic with Wireshark, and then compared the cleartext behavior against a separate TLS/mTLS security laboratory. The objective was not simply to demonstrate that IEC 104 is “insecure.” It was to determine where the security boundary actually exists at each layer, what the implementation enforces, what it does not enforce, and what changes when security extensions are introduced.
The complete research artifacts, including notes, scripts, PCAPs, and screenshots, are available in the iec104-research directory.
1. Starting With the Protocol: IEC 104 Before Security
IEC 60870-5-104 extends the IEC 60870-5 telecontrol family over TCP/IP. The protocol architecture separates the TCP transport from the IEC 104 application protocol and its APCI framing. (SIST E-Commerce)
At the wire level, an IEC 104 APDU begins with:
+--------+--------+-------------------------------+
| 0x68 | Length | APCI / ASDU |
+--------+--------+-------------------------------+
The APCI contains four control octets.
Those control fields determine whether the frame is an:
- I-format frame : application information and ASDU payload
- S-format frame : receive acknowledgements
-
U-format frame : link control such as
STARTDT,STOPDT, andTESTFR
The distinction matters because a TCP socket does not automatically mean that IEC 104 application data can be exchanged. The IEC 104 state machine has to be activated first.
2. Phase 1 : APCI State Activation
The first research phase focused exclusively on the link state.
The laboratory target was: 127.0.0.1:2404. After establishing TCP connectivity, the session remained in the stopped state.I then transmitted the raw U-format activation frame:
lib60870-C / cs104_server_no_threads68 04 07 00 00 00, which represents: STARTDT ACT. The server responded: 68 04 0B 00 00 00, or: STARTDT CON. The important observation was not the bytes themselves. It was what wasn't present. There was no identity negotiation, credential exchange, cryptographic challenge, or authentication step between TCP establishment and link activation.
The transition was effectively:
TCP Connected
│
▼
STOPPED
│
│ STARTDT ACT
▼
STARTDT CON
│
▼
DATA TRANSFER ACTIVE
The base IEC 104 protocol therefore provides the state transition mechanism, but not an authentication boundary.
The research notes document the complete U-format control set and additional state behavior, including TESTFR and STOPDT.
Figure 1. Wire-level observation of the IEC 104 link activation sequence during Phase 1.
This became the baseline for the rest of the investigation:
If link activation itself is unauthenticated, what can a client do once the channel reaches the data-transfer state?
3. Phase 2 : Moving From Link State to the ASDU Address Space
Once the link was active, the research moved into the ASDU layer. IEC 104 uses Information Object Addresses (IOAs) together with Common Addresses (CAs) to identify application data. The test harness therefore moved from U-format control frames to I-format ASDUs.
Several Type IDs were particularly relevant:
| Type ID | ASDU | Purpose |
|---|---|---|
11 |
M_ME_NB_1 |
Measured value, scaled |
45 |
C_SC_NA_1 |
Single command |
100 |
C_IC_NA_1 |
General Interrogation |
One of the first things visible in the capture was that the server was not simply responding to individual requests. It was also producing cyclic telemetry.
For example:
RX | Type 11 | CA 1 | IOA 110 | 0xcc0300
RX | Type 11 | CA 1 | IOA 110 | 0xcd0300
RX | Type 11 | CA 1 | IOA 110 | 0xce0300
The payload changed monotonically, providing a simple observable representation of a live counter. The capture also demonstrated why IEC 104 research cannot be implemented as a simplistic send() → recv() exchange. Multiple APDUs can exist inside the TCP byte stream.
A client therefore needs to maintain an application-level stream parser capable of separating:
TCP Stream
│
├── APDU
├── APDU
├── APDU
└── APDU
Rather than assuming one socket read corresponds to one IEC 104 frame.
Figure 2. Captured ASDU traffic during telemetry and Information Object Address enumeration.
An invalid Common Address was also tested. The laboratory server did not terminate the connection when presented with CA: 9999. Instead, the request produced an IEC 104 response while the transport sequence continued. This was an implementation behavior worth recording because protocol error handling is often just as important as the normal path.
4. Phase 3 : What Happens When the State Machine Is Abused?
The third phase deliberately moved away from normal protocol operation.
Three areas were tested:
- I-frames before
STARTDT - I-frames after
STOPDT - Manipulation of
N(S)andN(R)sequence values
The first result was actually reassuring. An I-format frame sent before link activation caused the server to close the connection. Likewise, after: STOPDT ACT STOPDT CON attempting to send another I-frame resulted in connection termination rather than continued command processing. So the state machine itself was not completely permissive.
The implementation distinguished between:
STOPPED
│
└── I-frame → rejected
STARTED
│
└── I-frame → processed
The sequence-number behavior was more interesting. IEC 104 uses N(S) and N(R) to provide ordered transfer and acknowledgement. The standard specifies sequential progression of these counters. (iTeh Standards)
In the laboratory, however, the server accepted experimentally supplied forward jumps such as N(S) = 5000 and N(S) = 32767 without immediately resetting the connection. That does not mean that every IEC 104 implementation will behave this way. It means that this particular lib60870-C configuration demonstrated tolerance that deserved investigation.
The protocol defines sequence semantics. The implementation determines how strictly those semantics are enforced.
Direct Control Execution
The more consequential observation in Phase 3 involved Type ID 45, C_SC_NA_1. A direct Single Command was transmitted toward: IOA: 5001 with the laboratory actuator configured to represent a breaker-like control point.
The command was accepted without a preceding Select operation.
Client
│
│ Type 45 / IOA 5001
│ Direct Execute
▼
RTU
│
└── State changed
This demonstrated that the tested configuration did not enforce Select-Before-Operate as a mandatory prerequisite for that control point.
That finding is configuration and implementation-specific, but its security implication inside the laboratory is straightforward: network reachability plus knowledge of the addressing scheme was sufficient to reach a control function.
Figure 3. Phase 3 testing of APCI state enforcement, sequence handling, and direct control execution.
5. Phase 4 : Testing the Parser Boundary
After understanding the normal protocol and control paths, I moved down toward malformed input. The objective was to determine how the implementation behaved when the bytes no longer represented well-formed IEC 104 traffic. Several boundary conditions were tested.
Invalid start octet
Instead of: 68, the frame began with: 99 . The connection was closed.
Exaggerated length
A frame advertised a much larger payload than the bytes actually transmitted: 68 FF ... The server waited for additional stream data until the socket timeout rather than processing an incomplete APDU.
Unsupported Type ID
A Type ID of: 255 was supplied. The server remained operational and continued transmitting valid telemetry.
Truncated ASDU
An incomplete application payload was supplied. Again, the process remained stable.
Illegal U-format direction
A client-originated confirmation frame such as STARTDT CON was tested where an activation request was expected. The server did not treat it as a valid state transition.
These tests produced an important distinction between security failure and parser robustness.The target did not crash during the malformed-input testing. That is a positive implementation property.
At the same time, some invalid inputs were silently discarded rather than producing explicit diagnostic responses.
Figure 4. Malformed APCI and ASDU boundary testing against the laboratory implementation.
The resulting picture was therefore more nuanced than simply calling the stack “vulnerable.” The implementation showed reasonable structural resilience while simultaneously exposing security weaknesses elsewhere.
6. The Security Boundary Was Not at APCI
After four phases, the architecture of the problem became much clearer. The IEC 104 link state machine provided protocol state. It did not provide identity. The ASDU layer provided application semantics. It did not automatically provide authorization. The sequence counters provided ordering. They did not provide cryptographic authenticity. And the parser correctly rejected a number of malformed structures. It still could not distinguish a legitimate master from an unauthorized one based on the base protocol alone. That distinction is critical in OT security.A protocol can be perfectly capable of answering:
“Is this frame structurally valid?”
without being capable of answering:
“Is this station authorized to send this command?”
7. Phase 5 : Introducing IEC 62351
The final research phase changed the security model rather than continuing to attack the cleartext implementation. A separate Python laboratory was created around a TLS-wrapped IEC 104 environment.
The cleartext baseline used: TCP/2404 while the secure environment used: TCP/19999 with mutual TLS. IEC 62351-3 provides security profiles for TCP/IP-based power-system protocols, including IEC 60870-5-104. IEC 62351-5 specifically addresses security for IEC 60870-5 and derived protocols. (IEC 61850)
The important conceptual change was:
CLEAR
------------------------------------------------
TCP
│
IEC 104
│
APCI
│
ASDU
│
Control
SECURED
------------------------------------------------
TCP
│
TLS / Authentication
│
IEC 104
│
APCI
│
ASDU
│
Control
Instead of trying to make APCI itself become an authentication mechanism, security is introduced around the communication channel and, where applicable, through application-layer security mechanisms. The newer IEC 60870-5-7 technical specification describes the security extensions that apply IEC 62351 mechanisms to IEC 60870-5-101 and IEC 60870-5-104.
8. Mutual TLS Changes the First Question
In the cleartext laboratory, the first meaningful exchange was:
TCP connection
↓
STARTDT ACT
↓
STARTDT CON
In the secure laboratory, a client first had to satisfy the TLS authentication boundary.
An unauthenticated client attempting to establish the secure channel received:
[SSL: TLSV13_ALERT_CERTIFICATE_REQUIRED]
tlsv13 alert certificate required
That is a fundamentally different failure point. The unauthorized client does not reach IEC 104 link activation. It fails before the application protocol becomes usable. With a valid certificate, the secure channel was established using: TLS_AES_256_GCM_SHA384 and IEC 104 traffic subsequently operated inside that encrypted channel.
Figure 5. Secure laboratory client validating certificate-based authentication and the protected IEC 104 channel.
Figure 6. Secure laboratory server enforcing the TLS authentication boundary.
This also changed what passive packet capture could reveal. In the cleartext laboratory, the PCAP contains the actual IEC 104 structures.
A packet analyst can see:
STARTDT
Type ID
CA
IOA
Command values
Telemetry
Inside TLS, the network observer sees the transport conversation and TLS records rather than the IEC 104 application payload.
9. Encryption Alone Does Not Solve Authorization
This is where the final phase becomes more interesting. Encryption protects the channel. It does not automatically decide whether an authenticated station should be allowed to operate a particular control point. The secure laboratory therefore added an authorization layer.
The test client authenticated as: CN=scada-master and attempted to operate: IOA: 5001. The request reached the secure server, where the laboratory authorization logic evaluated the role mapping.
The result was:
Authenticated Session Established
│
▼
Control Request: IOA 5001
│
▼
Authorization Check
│
├── Not permitted
▼
Access Denied
The server produced: 68 04 47 00 00 00 and the laboratory logged the operation as an RBAC violation. This produced an important contrast with Phase 3.
Cleartext laboratory
Reach port 2404
↓
STARTDT
↓
Send Type 45
↓
Control executed
Secured laboratory
Establish TLS
↓
Authenticate client
↓
Evaluate authorization
↓
Control request rejected
The two mechanisms therefore address different problems. Authentication asks who is communicating and Authorization asks what that identity is allowed to do.
IEC 62351-8 defines the role-based access-control component of the IEC 62351 security family, while IEC 62351-5 provides security mechanisms specifically for IEC 60870-5-derived protocols. (IEC Webstore)
10. Putting the Research Together
The six research notes can therefore be reduced to a fairly simple security model.
| Layer | Research Question | Laboratory Observation |
|---|---|---|
| TCP | Can the endpoint be reached? | TCP/2404 accepted connections |
| APCI | Can the link be activated? |
STARTDT ACT/CON without identity verification |
| ASDU | What application data exists? | Telemetry and IOA structures observable |
| Control | Can commands be issued? | Direct Type 45 execution observed |
| State | Does the implementation enforce protocol state? | Yes, for several tested transitions |
| Parser | Does malformed input crash the process? | No crashes observed |
| Security extension | Can communication be authenticated and protected? | mTLS blocked unauthenticated clients |
| Authorization | Can authenticated identities be restricted? | Laboratory RBAC rejected unauthorized control |
This is the part of the research I found most useful. The cleartext implementation was not simply “bad.” It had a functioning protocol state machine. It handled several malformed inputs safely. It maintained sequence counters. It processed telemetry correctly. The problem was that protocol correctness and security authorization are different properties.
11. What the Packet Captures Added
The PCAPs were important because the conclusions were not based solely on application output. They provide a second layer of evidence alongside the Python harness output.
For example, Phase 1 can be reduced to actual bytes:
68 04 07 00 00 00
68 04 0B 00 00 00
While Phase 3 exposes the I-frame containing the tested command. Phase 5 then provides the contrast: the IEC 104 application payload is no longer directly visible to a passive observer because the communication is encapsulated inside TLS. That progression from raw APCI bytes to encrypted application traffic is really what the entire research series is about.
12. Building the Laboratory
The cleartext target was built from lib60870-C.
The basic environment was:
git clone https://github.com/mz-automation/lib60870.git
cd lib60870/c
mkdir build && cd build
cmake ..
make
The server used for the experiments was: cs104_server_no_threads
A second build layout was also used during the laboratory work:
cd ~/Desktop/iec104-lab/build
cmake ../lib60870/lib60870-C
make
./examples/cs104_server_no_threads/cs104_server_no_threads
Packet capture was performed directly against the loopback interface.
For the cleartext target:
wireshark -k -i lo -f "tcp port 2404"
and for the secure laboratory:
wireshark -k -i lo -f "tcp port 19999"
The captures were then retained as phase-specific PCAPNG artifacts.
The secure laboratory also generated its own local CA and server/client certificates, allowing the entire authentication experiment to remain inside the controlled research environment.
13. What I Would Take Away From This Research
There are several conclusions I would carry into an actual IEC 104 security assessment.
1. Start before the ASDU
Jumping directly into Type IDs and IOAs misses the protocol state machine. STARTDT, STOPDT, TESTFR, and the I/S/U distinction establish the context in which application traffic becomes meaningful.
2. Separate protocol behavior from implementation behavior
The standard defines the protocol semantics. The implementation decides how strictly those semantics are enforced. The sequence-counter observations and malformed-frame behavior are good examples.
3. Treat addressing as security-relevant
Once the Common Address and IOA structure becomes known, the application layer becomes considerably easier to reason about. Telemetry enumeration is therefore not merely an informational exercise.
4. Do not confuse encryption with authorization
TLS prevents passive observers from reading the IEC 104 payload and, with mutual authentication, establishes a cryptographic identity boundary. It does not by itself determine whether an authenticated station should be allowed to operate a particular breaker.
5. Test the whole path
The useful security boundary was not found in a single packet.
It emerged across:
TCP
↓
APCI
↓
ASDU
↓
IOA
↓
Control Function
↓
Authentication
↓
Authorization
That is why I structured the research as a sequence rather than a single packet-dissection exercise.
Conclusion
IEC 60870-5-104 is straightforward to understand once its layers are separated. TCP provides the transport. APCI provides framing, sequencing, acknowledgements, and link-state control. ASDUs provide telemetry and control semantics. But none of those layers, in the baseline laboratory implementation, established the cryptographic identity or authorization boundary required for secure operation.
That became visible from the first experiment. From there, the research progressed through telemetry enumeration, IOA discovery, direct command execution, sequence manipulation, malformed-frame testing, and finally the introduction of TLS and authorization controls. The result is not a claim that every IEC 104 implementation behaves exactly like the laboratory target. It is a demonstration of how to interrogate the protocol and its implementation systematically.
Start with the architecture. Move to the wire. Validate the state machine. Map the application layer. Test the boundaries. Then introduce the security controls and repeat the same observations. That helped in distinguishing that IEC 104 uses TCP/2404 and actually understanding where the protocol's security boundary begins and where it doesn't.
Research Artifacts
The complete laboratory is available in the industrial-protocol-labs repository.
The IEC 104 research directory contains:
iec104-research/
├── certificates/
├── notes/
├── pcaps/
├── screenshots/
└── scripts/
The research notes cover the architecture primer, four cleartext protocol/security investigations, the secure-extension contrast, and the complete laboratory reproduction procedure. All experiments were performed against isolated laboratory systems under my control. The observations above describe the tested lib60870-C configuration and the accompanying research environment; they should not be interpreted as universal behavior of all IEC 60870-5-104 implementations.






Top comments (0)