PACS from a hacker’s perspective. Attacks on RFID-based physical access control systems

Date: 11/03/2025

Hacking electronic turnstiles installed at building entrances is a popular trick shown in many movies. This article discusses RFID-based physical access control systems (PACS) and demonstrates how easily the most commonly used identifier, EM4100, can be faked.

Terms

  • PACS (physical access control system) is a set of equipment designed to restrict access to a protected facility. The minimum configuration of such a system is a drunken security guard RFID-based electronic lock;
  • RFID (radio frequency identification) is a technique that automatically identifies objects using radio signals stored on transponders (RFID tags); and 
  • RFID tag is an assembled data storage device. It includes an integrated circuit (chip) to perform operations with signals and data, an antenna that transmits and receives the signal, and an optional battery (not very common since it’s expensive and in many cases excessive).

More information is available in Wikipedia.

EM410X is a very popular series of identifiers developed by EM Microelectronics. In everyday life, they are used in multiple ways: from physical access control systems to animal tags.

The series includes chips with EM4100, EM4102, EM4105, and EM4200 identifiers that differ in memory size (from 64 to 128 bits) and application field​​.

Identifier Memory size UID size Application field
EM4100 64 bits 5 bytes PACS, logistics
EM4102 64 bits 5 bytes Animal tags
EM4105 128 bits 8 bytes Animal tags
EM4200 128 bits 8 bytes PACS, logistics

Officially, all these identifiers operate at a frequency of 125 kHz, but, in reality, they can use frequencies in the range of 100-150 kHz.

The most widespread (and easy to understand) identifier is EM4100; so, let’s examine it in more detail.

EM4100 structure

The data structure in EM4100 identifiers is as follows.

(Red) header bits, (green) parity bits added to strings, (yellow) parity bits added to columns, (light blue) client version or ID, (dark blue) data bits, and (violet) breakpoint bit. The scheme is valid for Manchester code
(Red) header bits, (green) parity bits added to strings, (yellow) parity bits added to columns, (light blue) client version or ID, (dark blue) data bits, and (violet) breakpoint bit. The scheme is valid for Manchester code

The most important element in this scheme is the group of light and dark blue bits that together make up 5 bytes (40 bits) and act as a unique identification code of a RFID tag.

Done with theory. Let’s examine attacks on such systems.

Attack vectors targeting EM4100-based PACS

None of the EM410X modifications use cryptography or any other protection technique. Accordingly, all attack vectors exploit either fundamental flaws of these identifiers or their unsafe operation.

Let’s try to hack a stand-alone (i.e. not integrated with other systems) PACS with contactless readers. This is the easiest target making it possible to understand and implement such an attack.

From a practical perspective, your goal is to gain physical access – at least once! – to restricted premises protected using this technology.

Copying original pass

Since EM410X doesn’t protect the transmitted data in any way, its copying is pretty simple.

Such aspects as obtaining a valid pass for copying and the cloning process are beyond the scope of this article. In different situations, they can vary greatly. More information is available in special guides published on such portals as Lab401 and Dangerous Things.

But for a true hacker, this variant is too easy, isn’t it? Why don’t you create extra valid passes without the need to obtain their original physical copies?

Generating new UIDs on the basis of existing ones

Imagine an abstract organization whose PACS uses EM4100 identifiers. Try to guess how does the security department purchase them: a bunch at once or each identifier separately?

OK, let’s try another tack. What would be easier for a security specialist who configures the system: enter each identifier into the database separately or register them at once as a group?

Most likely, you already got the point. If you know the UID of one of the valid passes, then the ‘adjacent’ UIDs will most likely be recognized by the system as valid, too.

Here is an example: imagine that you have an identifier whose UID is 12 00 EC DA A1. In theory, if you increase (or reduce) the high-order byte, you should also get a valid identifier value for the system. The subsequent UIDs have the following values:

12 00 EC DA A2
12 00 EC DA A3
12 00 EC DA A4
12 00 EC DA A5
12 00 EC DA A6
...

With a high degree of probability, all of them should be valid.

Is that always true? Not necessarily. In real life, the system may not have some identifiers from this list or they can be blocked. Each specific value must be verified practically, which makes your task even more exciting, right?

Brute-forcing identifier values

The list provided in the previous section raises a logical question: perhaps, it would be faster and more reliable to use brute-forcing? In fact, this is a viable option that can be implemented using such handy solutions as Flipper Zero, Proxmark III, or Arduino-based DIY devices. The only downside of this method is that security guards won’t idly stand and watch you bringing a strange device to the reader…

By the way, can you count the total number of possible ID values to be brute-forced? If you immediately answer: 2565, then my congrats!

But wait a minute… is it always 2565?

A few words about readers

So far, you were focused only on identifiers and problems plaguing them. But what about readers that ‘decide’ whether to allow a particular person to enter the protected premises or not?

For your information: although the number of bytes that make up a UID never changes (it’s always five), this doesn’t mean that all of them are used in validation.

To understand how can this be possible, I suggest reading the article about Wiegand, a widespread interface used for communication between an identifier reader and a controller.

In simple terms, most cheap and old access control systems use Wiegand-26, which transmits only 24 data bits (and 2 parity bits). As you understand, this reduces the pool of possible identifier values to 2563.

No doubt, this is still a lot. Although there is another way to reduce this number to 256 or eliminate the need to brute-force at all…

Compromise in one photo

Remember those weird numbers inscribed on your RFID card?

Of course, they are inscribed there for a reason. These numbers are part of the UID, but in decimal format.

Let’s examine the card shown above:

  • 0008671306 = 0x0084504A – 4 UID bytes;
  • 132 = 0x84 – client ID separately; and 
  • 20554 = 0x504A – 2 high-order bytes separately.

The original UID is 4E 00 84 50 4A.

info

In all identifiers that I encountered, the second byte was always zero. No idea whether this is a coincidence or an unspoken agreement between the manufacturers.

In other words, using a single photo of an identifier, you can create its copy that will be valid for the security system or reduce the number of values ​​to be brute-forced to 256. Not bad, right?

Protection

Now that you are aware of various attack vectors targeting PACS, you probably have a question: is it possible to protect against such attacks or at least mitigate their consequences?

Yes and no. Manufacturers of such systems have developed techniques making it possible to detect ‘clones’, but the implementation of additional validation systems is impractical; the simplest solution is to switch to Mifare 1k – no less popular identifiers that support cryptography (to be addressed in the next article).

See you soon!


Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>