26

I know that we could easily extract the uuid version number. Is there a reliable way to extract information like timestamp, MAC address?

Thanks!

Chris Frost
  • 1,069
  • 2
  • 10
  • 7
  • 1
    What flavor of UUID are you asking about, and what language? Without that info, I'd say you have to know how the UUID was generated (version) to be able to know what is available to extract. – Sandy Simonton Nov 24 '15 at 19:27

6 Answers6

52

A standard-conforming UUID may be one of several variants, it looks like this:

AAAAAAAA-BBBB-CCCC-DDDD-FFFFFFFFFFFF

The first (hex)digit of the DDDD part determines the variant.

If it is one of 8,9,A,B it is conforming to the current spec (0-7 are reserved for backward compatibility, C,D are reserved for Microsoft, and E,F are reserved for future use)

If it conforms to the current spec, check the first digit of the CCCC part which determines the UUID version:

  1. Time-based with unique or random host identifier (MAC)
  2. DCE Security version (with POSIX UIDs)
  3. Name-based (MD5 hash)
  4. Random
  5. Name-based (SHA-1 hash)

Version 4 is simply randomly chosen.

Version 3 and 5 are generated by hashing and throwing away some bits which means you have basically no chance in recovering any information from it. Details on how to build it can be found in RFC4122 or at the UUID Generator webpage.

I could not find any version 2 UUIDs so I didn't check how to extract the data.

Version 1 is generated from a time-stamp and current host MAC address. (The standard also allows to use a random address instead if you set the "broadcast/multicast" bit of the MAC address.)

The following perl snipped parses the MAC address and Time from a version 1 uuid:

my $uuid="AAAAAAAA-BBBB-CCCC-DDDD-FFFFFFFFFFFF";
$uuid=~tr/-//d;
my $time_low=hex substr($uuid,2* 0,2*4);
my $time_mid=hex substr($uuid,2* 4,2*2);
my $version =hex substr($uuid,2* 6,1);
my $time_hi =hex substr($uuid,2* 6+1,2*2-1);

my $time=($time_hi*(2**16)+$time_mid)*(2**32)+$time_low;
my $epoc=int($time /10000000) - 12219292800;
my $nano=$time-int($time/10000000)*10000000;

my $clk_hi  =hex substr($uuid,2* 8,2*1);
my $clk_lo  =hex substr($uuid,2* 9,2*1);
my $node    =substr($uuid,2*10,2*6);

$node=~/^(..)(..)(..)(..)(..)(..)$/ || die;
$node="$1:$2:$3:$4:$5:$6";

print "time: ",scalar localtime $epoc," +",$nano/10000,"ms\n";
print "clock id: ",$clk_hi*256+$clk_lo,"\n";
print "Mac: $node\n";

my $byte=hex $1;
if(hex($1)&1){
    print "broadcast/multicast bit set.\n";
};

And last but not least, there are several assigned UUIDs, for example for GPT partitions.

Sec
  • 7,059
  • 6
  • 31
  • 58
  • You have a bug on the second line of code. It should be: $uuid =~ s/-//g; Otherwise, the script will only replace the first occurrence of '-'. Other than that, thanks for sharing this code. – metator Oct 03 '13 at 16:35
  • @metator: The second line was probably meant to be transliteration to remove all dashes: `-`. The correct code working in Perl 5.18 is `$uuid=~tr/-//d;` (equivalent of Unix command `tr -d -`). Also every line is indented by four spaces which is annoying when you copy the code. – pabouk - Ukraine stay strong Nov 25 '14 at 14:50
  • I saw nothing in RFC 4412 to suggest your explanation of variant encoding is correct. It only used three bits to determine the variant, not a whole hexit. – Melab Aug 13 '16 at 18:06
  • The clock id reported by this code is different from OSSP uuid. Not sure which one is correct. – Luc May 10 '17 at 12:34
8

Not necessarily a reliable way, because depending on the kind of UUID it is, it may be generated totally from random bits, or be timestamp-based, or be based on the MAC address. So you may be able to get some of that information, but you can't guarantee you can get anything.

The official reference for this is RFC 4122, which should probably give you enough information to extract data, although you probably shouldn't rely on it too heavily.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
7

The OSSP uuid tool can decode UUIDs of all versions. On Debian-based Linux systems you can use apt-get install uuid to install it; for other distributions, the package name might be different.

To decode a UUID, use the -d (decode) flag:

uuid -d AAAAAAAA-BBBB-CCCC-DDDD-FFFFFFFFFFFF

For version 1 UUIDs, this gives the MAC address and timestamp -- since that's what's in a v1 uuid.

Luc
  • 5,339
  • 2
  • 48
  • 48
6

I know that we could easily extract the uuid version number. Is there a reliable way to extract information like timestamp, MAC address?

Yes, and Yes; if the UUID is version 1 or version 2 (as described in RFC 4122). There is also an alternate (non-RFC 4122) version 4, dubbed "COMB" that includes a time-stamp (as well as random values) that can be parsed, and the creation date/time can be revealed.

Bonus: Mahonri Moriancumer's UUID and GUID Generator and Forensics.

Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28
3

If it's a version 1 UUID, the MAC address will be the last twelve hex digits.

James Cronen
  • 5,715
  • 2
  • 32
  • 52
  • 1
    But there isn't necessarily a reliable way to determine if an arbitrary UUID-formatted chunk of bytes is actually a version 1 UUID or just random data. So at best you'd have to take the MAC address you get back with a grain of salt. – Daniel Pryden Nov 10 '09 at 17:19
  • @DanielPryden Assuming the standards are being followed, UUID version number is included in the UUID. A v1 UUID is always xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx. See https://en.wikipedia.org/wiki/Universally_unique_identifier#Format – LaVache Jan 12 '18 at 15:26
  • @YeB: You are correct. But my point is: if you see a chunk of bytes that *looks* like it's a UUID, you can't be certain that it *is* a UUID, and therefore the version field is not necessarily reliable. That is: if you're trying to extract data from UUIDs, you need to be aware of the possibility of an attacker predetermining bits they send, independent of what the standard says. That means, as I said more than eight years ago: "at best you'd have to take the MAC address you get back with a grain of salt". – Daniel Pryden Jan 12 '18 at 15:57
2

You could look at the version of the Uuid, but that can only be trusted if you are sure the Uuid is valid (see https://www.rfc-editor.org/rfc/rfc4122). The version will tell you what kind of Uuid you have, and using that you can extract specific bits of information.

Community
  • 1
  • 1
Stephen Newell
  • 7,330
  • 1
  • 24
  • 28