Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIFARE Classic Anti-Copy Detection #1345

Closed
quantum-x opened this issue Jun 27, 2022 · 32 comments
Closed

MIFARE Classic Anti-Copy Detection #1345

quantum-x opened this issue Jun 27, 2022 · 32 comments
Assignees
Labels
Feature Request New feature or user-story you wanna add to flipper NFC NFC-related UI Affects UI

Comments

@quantum-x
Copy link
Contributor

quantum-x commented Jun 27, 2022

Background
In France, almost every apartment building uses RFID Access Control based on MIFARE Classic 1K badges.
The keys to decode these badges are well known (and in Flipper's library), and the badges can be easily cloned / emulated.

However, in France many Access Control Manufacturers now include anti-copy algorithms in the badge contents.

While the implementation differs between manufacturers, the overall technique remains the same.
Each time a badge is scanned on the building, a counter in the badge contents is updated.
The next time the badge is scanned, the Access Control Reader checks the contents of the counter.
If the counter is not at the expected value, the badge is rejected.

The problem
When badges with anti-copy are cloned - the contents between original badge and the new clone (or emulation) become desynchronised. When de-synchronisation is detected, the copy will work, but the original badge will no longer work.

If the badge was emulated the original will no longer work, and the emulation will no longer work either (because its contents weren't updated during the emulation).

Depending on the brand of the badge, typically only one badge is de-activated. However some brands (such as Immotec) will deactivate all badges associated with an apartment when cloned badges are detected.

Although this problem is concentrated in France, it is also present in Belgium, UK, Germany and Australia.

As more and more people in Europe will be getting their hands on Flippers, I feel it's important to discuss the issue, to prevent people unintentionally breaking their residential badges / locking themselves out..

Suggestions for a solution
The anti-copy algorithms for each brand and model have a unique fingerprint, and can be detected.
I am unsure the best way to implement (if at all) some type of detection / protection.

  • It could be an additional script that can be run against a saved Mifare Classic dump that checks for Anti-Copy
  • It could be implemented into the Emulation function, to prevent (or at least warn) of anti-copy presence
  • It could be implemented into the Write function (not yet implemented, but on the to-do list) to prevent (or at least warn) of anti-copy presence.

I have the full list of signatures for all brands and models with anti-copy for all of Europe, and will happily contribute this information.

@quantum-x quantum-x added the Feature Request New feature or user-story you wanna add to flipper label Jun 27, 2022
@gornekich gornekich self-assigned this Jun 27, 2022
@quantum-x
Copy link
Contributor Author

@gornekich Let me know your thoughts on how to implement for the entire community, and next steps so I can provide the anti-copy detection rules.

@gornekich
Copy link
Member

Hello @quantum-x . Thanks for information!

For now we ignore counter related commands during emulation. I can see that this can cause problems, and we try to add working with counters soon. I guess it will solve the issue, when user just copy the card to flipper and no longer use the original card.

Further we will add users possibility to synchronize both variants of card. It will come after we add write functionality. Flipper can detect if the data was updated during emulation, and I think it's a good point to notify user about it. I will talk with our UX designers and come back with solution.

I'm not sure I understood you correctly about additional script that can be run against a saved Mifare Classic dump that checks for Anti-Copy Could you explain the solution in more details?

@quantum-x
Copy link
Contributor Author

Hi @gornekich
Thanks for the reply.

To be clear, the anti-copy algorithms in are not simply consecutive counters (0x01, 0x02, 0x03 etc), it's heavily obfuscated data that is written 'randomly' over the badge.

Regarding 'Additional Script that can be run against a Mifare Classic Dump':

  • When a user saves a dump to the Flipper, in the 'Actions' menu (Currently has "Emulate", "Edit UID and Name", "Delete", "Info", etc - it could be interesting to add a "Detect Anti-Copy" function.
  • Users could run this script against a dump to check if the badge has anti-copy signatures
  • This script could also be automatically run before a user emulates or writes a dump, to prevent (or warn) users that the badge contains anti-copy.

In France, ~20% of badges on the market have anti-copy.
Currently if I emulate a badge with anti-copy, both the original badge and the emulation will be de-activated.

As EU customers are starting to receive their Flipper devices, there is a very high risk that customers will de-activate their building badges by mistake, with no warning, and no way to repair the badge except to buy a new one (~50EU - 100EU) from the building manager.

Detection is reliable and "easy" to implement, perhaps we should try to implement this quickly.

@gornekich
Copy link
Member

Hello @quantum-x

We discussed with our team this issue and our priority is to support all commands during Classic emulation.

Regarding anti-copy algorithms, we need at least badges dumps. It would be nice if you send a few dumps with anti-copy signatures and provide an algorithm to detect the signature.

Further, it would be perfect to get these badges and may be readers on hands for tests. Is it possible for you to send them to us?

@quantum-x
Copy link
Contributor Author

quantum-x commented Jun 28, 2022

Hi @gornekich
Thanks for the internal discussion. I understand your team's priorities - and if Mifare Classic Emulation and writing can't be integrated, then integrating anti-copy detection is moot.

Regarding detection and rules, I have full rule-sets for detecting all types of known anti-copy on the market.
It should be mentioned that this comes from the development team at Parklink Development Limited (a company for which I am director).

We are happy to open-source this code, as it's important for the community. If possible, we'd appreciate acknowledgement for the hard work of the dev team
Contributors are myself (@quantum-x) @danielebruneo and @triplesprawl from Parklink Development Limited.

There are five brands using anti-copy:

  • Intratone (COGELEC Brand)
  • Hexact (COGELEC Brand)
  • Comelit
  • Noralsy
  • Urmet

Each brand has different generations of algorithms.

The match function ingests an ASCII HEX representation of the binary dump of a badge.
Code is as follows :

Common method

        function hex_substring($hexDump,$startByte,$endByte){
            if($endByte<$startByte){
                return "";
            }
            return substr($hexDump,$startByte*2,($endByte-$startByte)*2+2);
        }

COGELEC Brands

Generic detection for COGELEC Brands

    public function match()
    {
        return
            $this->hex_substring($this->hex_dump, 0x03c0, 0x3c5) == "484558414354" && // 3c0-3c5 == HEXACT
            $this->hex_substring($this->hex_dump, 0x03c9, 0x3cf) == "434f47454c4543" && // 3c9-3cf == COGELEC
            $this->hex_substring($this->hex_dump, 0x02c0, 0x2cf) != "00000000000000000000000000000000" && // 2c* rolling counter block not empty
            $this->hex_substring($this->hex_dump, 0x02d0, 0x2df) != "00000000000000000000000000000000" && // 2d* rolling counter block not empty
            $this->hex_substring($this->hex_dump, 0x02e0, 0x2ef) != "00000000000000000000000000000000" && // 2e* rolling counter block not empty
            $this->hex_substring($this->hex_dump, 0x02c0, 0x2cf) != "ffffffffffffffffffffffffffffffff" && // 2c* rolling counter block not ff
            $this->hex_substring($this->hex_dump, 0x02d0, 0x2df) != "ffffffffffffffffffffffffffffffff" && // 2d* rolling counter block not ff
            $this->hex_substring($this->hex_dump, 0x02e0, 0x2ef) != "ffffffffffffffffffffffffffffffff"    // 2e* rolling counter block not ff
        ;
    }

Intratone

    public $regexp = '^[0-9A-F]{1412}(?:(?!00|FF)[0-9A-F]{2}).+?684578616374202D20434F47454C4543';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Hexact

Hexact A

    public $regexp = '484558414354787788008FA1D601D0A2(?!0000000000000000000000000000000000000000000000000000000000000000).+?000000000000000000000000000000004845584143547877880089347350BD36';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Hexact B


    public $regexp = '^[0-9A-F]{1376}484558414354787788008FA1D601D0A204D26';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Hexact C

    public $regexp = '^[0-9A-F]{1376}484558414354787788008FA1D601D0A2^[0-9A-F]{4}6';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Comelit

Comelit A

    public $regexp = '[0-9A-F]{2}0000014A6352684677';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Comelit B

    public $regexp = '^[0-9A-F]{216}(?:(?!0000)[0-9A-F]{4})*?[0-9A-F]{4}4A63526846777877';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Comelit C

    public $regexp = '[^00]{3}[0-9]{2}00[0-9]{2}4A6352684677';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Noralsy

Noralsy A

    public $regexp = '675A3241377078778800395244733978';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Urmet

Urmet A

    public $regexp = '^[0-9A-F]{1888}8829DA9DAF767F[0-9A-F]{109}[5|A]';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

Generic


    public $regexp = '^[0-9A-F]{1888}050908080008FF078069FFFFFFFFFFFF[0-9A-F]{8}20202020';

    public function match()
    {
        return
            preg_match('`' . $this->regexp . '`mis', $this->hex_dump);
    }

We can provide dumps to test against if required.

Please note, there are some badges that match A/C rules that do not have anti-copy enabled, but this false positive rate is ~2% maximum.

Hopefully these methods should remove some workload from your dev-team.
Please let me know if I can provide any further assistance.

@hedger hedger added NFC NFC-related UI Affects UI labels Jul 20, 2022
@Foul
Copy link
Contributor

Foul commented Aug 16, 2022

got one dump made some times ago from a Cogelec/Intratone badge with all keys.. could help ?
Intratone.zip

@quantum-x
Copy link
Contributor Author

got one dump made some times ago from a Cogelec/Intratone badge with all keys.. could help ? Intratone.zip

This one should indeed trigger the A/C Intratone ("COGELEC") algo.

@LoganMcClay
Copy link

Hello @quantum-x, to see if a badge is really protected, the data should change if dumped before then after a badge is used to enter ? I have a spare Urmet badge with the pattern matching, but the content doesn't seems to be updated when used.

@quantum-x
Copy link
Contributor Author

@LoganMcClay The content doesn't necessarily update on each scan.
Depending on the brand, either the badge contents contains the counter, or the access control system contains the counter.

With that said there is a 'before and after' difference between badges that don't have anti-copy enabled, and badges that do have anti-copy enabled - this is what the above algorithms detect.

@LilianHori
Copy link

Ok so my badge is from immotec and first thing I did when I received my flipper was trying to copy it (obviously I didn't read this thread before). It seems it didn't work as I was unable to open my door with my flipper, I will go and test if my badge still work. Should I just stop everything for now about it, should I delete the saved nfc ? This sure is a huge problem and need to be told to EU users

@Foul
Copy link
Contributor

Foul commented Aug 28, 2022

how does it work when there are several users/badges for the same building to synchronize everything?

@quantum-x
Copy link
Contributor Author

quantum-x commented Aug 28, 2022 via email

@Foul
Copy link
Contributor

Foul commented Sep 2, 2022

another user posted :

I know this remote, and talked to the vendor of it.
It is not transmitting a usual signal like other remotes do.
This one sends only 3 little bursts of the signal, like Horman BiSecur, which are hard to catch.
And it is AES encoded.
There will be no way to handle this remote with Flipper or any other cloning device or solution!

😥

@Foul
Copy link
Contributor

Foul commented Mar 28, 2023

The one with permanent access could be interesting ;)

@Foul
Copy link
Contributor

Foul commented Mar 28, 2023

Did you test it successfully ?

@Foul
Copy link
Contributor

Foul commented Mar 28, 2023

Link to Pastbin.

@quantum-x
Copy link
Contributor Author

HI here, If somebody it's interested, i have two badge intratone with anty-copy , i'll can make a completly dump And I have an old card of a packet distributor who is desactived but she had a permanent acces during a certains day before. I dumped it too. I'm curious to know more about that card and how work the badge of emergency service. I'll can make test with my two badge and try to modify card and test it.

This is a thread about providing detection of anti-copy algorithms put in place by French Access Control manufacturers to prevent Flipper Zero owners for inadvertently erasing their original cards when they make private copies, or when they make in-scope penetration tests.

@Foul @Yomi2023 @Sweedn You are discussing the VIGIK Service cards, which is out of scope of this thread.
Furthermore, duplication of these cards is illegal and has lead to multiple arrests. I'd suggest removing these posts, or moving the discussion into another forums.

@chinlung
Copy link

chinlung commented Aug 6, 2023

I want to propose another anti-copy situation: the original card is a Mifare Classic 1K card, SAK:08, KeyA/B are FFFFFFFFFFFFF, so it can be copied and stored by F0, but when F0 simulates, systems like the elevator system and access control system cannot read the content normally (no response at all). Later, I found information on the Internet saying that these systems "may" have a firewall, and need to use a card type called "CUID" (probably the so-called magic card) to work normally. In practice, a copied card using CUID can pass through the above systems normally.

Is it possible for F0 to update the firmware to read data normally through the above systems? Thank you.

@jerome-jutteau
Copy link

jerome-jutteau commented Oct 20, 2023

Hi!

got one dump made some times ago from a Cogelec/Intratone badge with all keys.. could help ? Intratone.zip

Thanks for providing the dump and thanks a lot to contributors such as @quantum-x for the hard work.

A first interesting thing to note about this dump is what we see at 0x03c0 -> 0x03cf:

xxd Intratone.dmp
...
000003c0: 6845 7861 6374 202d 0143 4f47 454c 4543  hExact -.COGELEC
...

hExact is different from HEXACT string so this should not match with:

$this->hex_substring($this->hex_dump, 0x03c0, 0x3c5) == "484558414354" && // 3c0-3c5 == HEXACT

Hope this help

@skotopes
Copy link
Member

skotopes commented Jan 3, 2024

Looks like NFC plugin system solves this issue. Please contribute plugins ;-)

@skotopes skotopes closed this as completed Jan 3, 2024
@anonymous10download
Copy link

What do you mean by the "NFC plugin system", and how does it solve the issue?
I've been monitoring this issue for an extended period.

@skotopes
Copy link
Member

skotopes commented Jan 5, 2024

@anonymous10download NFC plugin system currently covers card data parsing, helps to identify and visualize known systems data. For example: #3325

@ThothOverMatter
Copy link

This was very informative ! thank you for all the contributors ! I’m an expat living in Paris and have obviously run into the same issue everyone else has run into on this forum. Any information on updated capabilities would be valued greatly by myself and many other EU users I’m sure. Is Flipper working on a work around, or should EU users look at this as a dead end?

@quantum-x
Copy link
Contributor Author

As per @skotopes post, Flipper now has plugin / parsing architecture for NFC.
This represents the hardest part of implementing an anti-copy detection plugin.

If someone is available to work on the structure of the plugin, I can contribute up-to-date algorithms for all known brands. Feel free to contact me.

@Leptopt1los
Copy link
Contributor

Leptopt1los commented Feb 3, 2024

As per @skotopes post, Flipper now has plugin / parsing architecture for NFC. This represents the hardest part of implementing an anti-copy detection plugin.

If someone is available to work on the structure of the plugin, I can contribute up-to-date algorithms for all known brands. Feel free to contact me.

@quantum-x contact me via discord (leptopt1los). I will need a description of the algorithms and dumps for tests

@gagzzz
Copy link

gagzzz commented Apr 26, 2024

hello,
i'm also interested but rather for the proxmark3. If there was a working anti-copy detection plugin for the Flipper it would probably end up being adapted to work with proxmark3.

Also i wonder if Silca, Copybadge and rebadge do this kind of check as well, i think i've heard copybadge and rebadge sometimes copied protected badges, but i recall a silca copier owner saying it would detect the anticopy straight away. But i also do think Silca is less "intrusive" in the way it clones badges, as it requires an internet connection to work, iirc.

@Leptopt1los, @quantum-x, did you get in touch together?

♥ everyone

@JohnN6
Copy link

JohnN6 commented Apr 27, 2024

Copybadge.fr claim to be able to re-activate badges which have been disabled when a clone-copy has been used.
This seems to imply that they have direct access to Intratones master database system. It is uncertain to me if when a copied Vigik is used and then disabled, after they re-enable it, whether you now have two working badges or just one.

I haven't dared to try. They say at https://www.copybadge.eu/copybadge/comprendre-les-systemes-anti-copies/

Les badges de la marque Intratone (groupe Cogelec), sont ceux dont le système anti-copie est le plus efficace.
La plupart des centrales anti-copies sont connectées à un module GSM qui permet à la marque Intratone d’effectuer des mises à jour à distance pour désactiver les copies et empêcher la reproduction de ses badges. À ce jour, il est impossible de les reproduire.
Lors d’une copie, le second badge d’immeuble présenté sera refusé par la centrale. Si l’utilisateur teste la copie en premier, elle sera acceptée, néanmoins l’original qui sera présenté ensuite sera considéré comme une copie et sera refusé. Nous avons la possibilité de réactiver à distance un badge Intratone désactivé.

@BlackBird63030
Copy link

BlackBird63030 commented Apr 27, 2024

Hi, but what about Hexact badges ? I got a dump of my own badge and i want to emulate it. Any ideas please ?
Hexact.zip

@no-usernames-left
Copy link

This seems to imply that they have direct access to Intratones master database system.

More than an implication, I would say; they make pretty clear that they do.

@JohnN6
Copy link

JohnN6 commented Apr 27, 2024

As to Hexact, I think you will need to dump the badge, use it, dump it again use it again for at least 17 cycles and compare all the copies to see if there are changes recorded on your Hexact fob,. It seems that some have no anti-copy local on-fob storage used and others have that set up. IT is a choice made when the building system is set up.

The copy companies suggest that unless co-propietaires ( co-owners ) have agreed and been informed of an exclusivity forbidding copying of entrance badges then they have ( in France ) a right to be able to make and use copies.

Rebadge say they check if copies are allowed, so it might be possible to use them for a test ?
I don't have a Hexact fob so can't help more than this,

@BlackBird63030
Copy link

BlackBird63030 commented Apr 28, 2024

do you think that the code at the top may be useful ? for the anticopy detection

@BlackBird63030
Copy link

public function detectAntiCopyFromFile($filePath)
{
$hexDump = file_get_contents($filePath);

// Hexact A
$regexpA = '484558414354787788008FA1D601D0A2(?!0000000000000000000000000000000000000000000000000000000000000000).+?000000000000000000000000000000004845584143547877880089347350BD36';

// Hexact B
$regexpB = '^[0-9A-F]{1376}484558414354787788008FA1D601D0A204D26';

// Hexact C
$regexpC = '^[0-9A-F]{1376}484558414354787788008FA1D601D0A2^[0-9A-F]{4}6';

if (preg_match('`' . $regexpA . '`mis', $hexDump)) {
    return "Badge de type Hexact A avec anti-copy";
} elseif (preg_match('`' . $regexpB . '`mis', $hexDump)) {
    return "Badge de type Hexact B avec anti-copy";
} elseif (preg_match('`' . $regexpC . '`mis', $hexDump)) {
    return "Badge de type Hexact C avec anti-copy";
} else {
    return "Badge Hexact sans anti-copy ou type inconnu";
}

}

$filePath = "chemin/vers/le/fichier/badge_dump.hex";
echo detectAntiCopyFromFile($filePath);

there some code for hexact badges

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request New feature or user-story you wanna add to flipper NFC NFC-related UI Affects UI
Projects
None yet
Development

No branches or pull requests