Frame counters in ABP mode

Hello !

I was wondering which version of the lorawan specification Loraserver implements and I can’t find out after searching.

I’m using ABP mode on a node of my LoRaWAN network in order to simulate a replay attack on it. This attack consists in replaying a packet with a random frame counter value after the node has been reset. After, the gateway will reject all the packets from that node which have a frame counter value smaller or equal to the value contained in the replayed packet.

The problem is that the counter is reset by the node’s side but not by the server’s side, which is normal according to the latest version 1.1.0. The counters shall not be reset in the node’s lifetime. However, my node does not implement the latest version, it is the 1.0.1 version or 1.0.2, it depends.

So I would like to know if it was possible that the lorawan server functions as mentioned in the 1.0.1 or 1.0.2 specification or not? And also is the loraserver functioning with the latest specification?

Thanks you for your attention,


LoRa Server currently implements LoRaWAN 1.0.2. Please note that also according 1.0.x, a frame-counter must always increment! This was better documented in LoRaWAN 1.1, but is not a new behavior. See of LoRaWAN 1.0.2 (… provided the value received has incremented compared to the current counter …).

Thank you for your quick response !

Good to know that. I totally agree with you on that point. But sometimes it happens a node is reset and therefore the counter value must be set to zero, in OTAA but also in ABP mode. I found this quotation from the 1.0.2 specification :

“After a JoinReq – JoinAccept message exchange or a reset for a personalized
end-device, the frame counters on the end-device and the frame
counters on the network server for that end-device are reset to 0.”

So, yes the counter must always increment but if a reset occurs, the counter must be reset on both sides. It is only with the last specification that the frame counter in ABP mode must be persistent whenever the node is reset.

I hope you understand what I mean.

Yes, but I think what is mentioned there is an out-of-band reset, not a reset of a device because of e.g. powerless. In case of OTAA there will be a new exchange of keys, which is not the case with OTAA. Therefore it would mean that allowing a reset on FCnt=0, everybody would be able to replay your uplink frames, over and over…

Anyway, there is no way that the network-server can know (without compromising security) that the device was reset. In LoRaWAN 1.0.x there is no such message to signal that. You could enable the skip frame-counter mode when ABP activating your device, but know that this also compromises the security as it opens the door for replay attacks.

Okay I did not understand in the proper way these lines. Yes of course it introduces a security problem but for me that was a vulnerability in the 1.0.2 specification, and that is why I wanted to make an example of replay attack. So now I am curious to know how can you detect an out-of-band reset? I mean what would be the difference between this out-of-band reset and a “physical” reset on a node?

You are right I was thinking about this and I cannot figure out how the server could know if a device is reset in ABP. That is why the quotation given just before seems a little bit obscure to me … Yes this would be a terrible vulnerability in my network.

Therefore, I guess replay attack examples that I saw on the net were not implementing LoRaWAN specification correctly.

I agree this is a bit obscure and could be interpreted in different ways :slight_smile: I took the secure way :wink: In LoRaWAN 1.0.x there is no way to tell them apart.

One way I’ve heard other people handling this is storing a frame-counter every X interval in the flash. So on FCnt=0 store 100 in the device flash (keeping the real FCnt at 0), once you reach 100 store 200 (keeping 100 as a real value), and so on…

That way you don’t have to flash every FCnt increment and in case your device would be reset, it would jump to the frame-counter as stored in its flash memory. E.g. when it is at 50 and it would be reset, it would read its flash and sets it to 100. So instead of the network-server rejecting the first 0 … 50 frame-counter values (as they already occurred), it will see 50 frames “packet-loss” as the frame-counter jumps from 50 to 100.

That way you’re able to recover a reset and you would not wear out your flash memory as fast as doing a save on each FCnt increment.

1 Like

Yes totally this is a little philosophical :smile: Okay so there is no way to replay attack your network-server (you were right I think). Alright, it is a little bit annoying as therefore no reset will be possible.

Oh I see it is an efficient way to keep the counter persistent. You can also avoid the server from replay attacks I guess. But it is confusing because the fact to keep the counter in the flash is typical to the 1.1.0 specification. You have this quotation :

“ABP devices have their Frame Counters initialized to 0 at fabrication. In ABP devices the
frame counters MUST NEVER be reset during the device’s life time. If the end-device is
susceptible of losing power during its life time (battery replacement for example), the frame
counters SHALL persist during such event.”

So, of course the 1.0.x specification does not forbid to store the counter in the flash as it is not mentioned in it but this action looks like you are closer to the 1.1.0 specification, if I could say that.

Yes it could be a good way to resolve this problem !

Let me add some thoughts about FCnts in ABP mode. Possibility to reset FCnt on server is neccessary - it allows to inform the server that a node has lost LoRaMac settings set previously through Mac commands and is using default values. Values like additional channels, rx window params etc must be set by the server again.

Commercial servers like Actility or Swisscom detects that situation by receiving FCntUplink = 0. Server accepts messages with FCnt higher then previous or equal to 0.

I encourage you to think about this solution, because now there is no way to inform server about losing LoRaMac params.


HI brocaar,
For ABP is it disable or enable frame counter validation?

Hi amarnadh,

if you don’t know the counter of your device, you should disable it (as you already did).


That would compromise security, as brocaar has written earlier, so I do understand if he would not like to add this feature:

I just realised it is possible to manually reset frame counter on serever side for single device by writing 0 and (Re)Activating the device. That should do for most of the cases.

One thought: if that should be done automatically (which it shouldn’t be done at all by the specification), one could possibly send a custom message payload after the reset. Server would have to decode the message payload and if it was reset payload, server could reset the frame counter.
Would that compromise the security?

That’s just an theoretic idea, I understand the only right way is that end node has to manage the frame counter correctly even after hard reset.

What if someone recorded your custom message and replayed it as the start of their sequence of replay attack messages?

OTAA “moves the problem” in that the frame counter resets in each new session, but the session itself originates in a join request that must use a fresh, never-before-used join nonce. So the node is still required to keep track of something.

Hi, please allow me to refresh this never-ending story.

Thing is, if we have a “dummy” module, which resets its fCnt and mac parameters on restart, we simply have to disable frame counter validation because we can not fix the firmware.
That means the door for reply attacks are wide open and we are also quite limited with possible network settings. Note that OTAA is currently not an option too as quite a few devices are already deployed.

That leaves me with previous idea of manual frame counter reset and device re-activation (which resets mac parameters) . This process should not rely on fCnt reset only, but also on custom message payload as mentioned earlier.

This would of course still leave some space for reply attack, but chances of recording the right message is much smaller than disabled frame counter.

So I made a simple python script to test this:

The script subscribes to device’s /up event via MQTT and if frame counter reset occurs, it parses the data to see if it really is a reset.

This works with disabled frame counter validation, but, obviously, does not with validation enabled as the the frame counter check discards the message, so the message is not published to /up topic at all.

If validation is enabled and fCnt reset occurs, it gets published to device’s /error event. Problem with that is there is no data/payload in /error event, so I can not check if it was reset or not.

Any ideas how to handle this?