2009-11-10 109 views
14

我知道我们可以轻松提取uuid版本号。有没有可靠的方法来提取信息,如时间戳,MAC地址?您可以从UUID中提取什么样的数据?

谢谢!

+1

你问的是什么UUID的味道,以及什么语言?如果没有这些信息,我会说你必须知道如何生成UUID(版本)才能知道可以提取哪些内容。 – 2015-11-24 19:27:31

回答

2

您可以查看Uuid的版本,但只有在确定Uuid有效时才能信任该版本(请参阅http://tools.ietf.org/html/rfc4122)。该版本会告诉你你有什么样的Uuid,并用它来提取特定的信息。

7

不一定是一种可靠的方式,因为根据UUID的种类,它可能完全由随机位生成,或者是基于时间戳的,或者基于MAC地址。所以你可能会得到一些信息,但你不能保证你能得到任何东西。

对此的官方参考是RFC 4122,它应该可能会为您提供足够的信息来提取数据,尽管您可能不应该过度依赖它。

3

如果是版本1的UUID,则MAC地址将是最后十二个十六进制数字。

+1

但是,确定任意UUID格式的字节块是否实际上是版本1 UUID或只是随机数据的方式并不一定可靠。所以充其量你必须把你的MAC地址拿回来。 – 2009-11-10 17:19:28

+0

@DanielPryden假设正在遵循标准,UUID中包含UUID版本号。 v1 UUID始终为xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx。见https://en.wikipedia.org/wiki/Universally_unique_identifier#Format – YeB 2018-01-12 15:26:57

+0

@YeB:你说的没错。但我的观点是:如果你看到*看起来像是一个UUID的字节块,你不能确定它*是一个UUID,因此版本字段不一定是可靠的。也就是说:如果您尝试从UUID中提取数据,则需要注意攻击者可能预先确定其发送的位,而与标准所说的内容无关。这意味着,正如我八年多前所说的那样:“充其量,你最好不得不把MAC地址拿回来”。 – 2018-01-12 15:57:46

33

甲符合标准的UUID可以是几种变体之一,它看起来像这样:

AAAAAAAA-BBBB-CCCC-DDDD-FFFFFFFFFFFF

的DDDD部分的第一(十六进制)位确定变种。

如果它是8,9中的一个,A,B它符合当前规范 (0-7保留用于向后兼容,C,D保留给Microsoft,并且E,F保留给未来使用)

如果它符合当前规范,检查其确定UUID版本的CCCC部分的第一个数字:

  1. 基于时间具有独特的或随机的主机标识符(MAC)
  2. DCE安全版本(带有POSIX UID)
  3. 基于名称(MD5散列)
  4. 随机
  5. 基于名称(SHA-1散列)

版本4被简单地随机选择。

版本3和5是通过哈希生成的,并丢掉了一些位,这意味着您基本没有机会从中恢复任何信息。有关如何构建它的详细信息可在RFC4122UUID Generator webpage中找到。

我找不到任何版本2的UUID,所以我没有检查如何提取数据。

版本1由时间戳和当前主机MAC地址生成。 (如果您设置了MAC地址的“广播/多播”位,标准还允许使用随机地址。)

下面的Perl文档片断从版本1的UUID解析MAC地址和时间:

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"; 
}; 

最后但并非最不重要的,有几个指定的UUID,例如用于GPT partitions

+0

您在第二行代码中有一个错误。它应该是: $ uuid =〜s/- // g; 否则,该脚本将只会替换第一次出现的' - '。除此之外,感谢您分享此代码。 – metator 2013-10-03 16:35:08

+0

@metator:第二行可能意味着音译删除所有短划线:'-'。在Perl 5.18中正确的代码是'$ uuid =〜tr/- // d;'(相当于Unix命令'tr -d -')。同样,每行都缩进四个空格,这在复制代码时很烦人。 – pabouk 2014-11-25 14:50:00

+0

我在RFC 4412中没有看到任何建议你对变体编码的解释是正确的。它只用三位来确定变体,而不是一个整数。 – Melab 2016-08-13 18:06:31

3

我知道我们可以很容易地提取uuid版本号。有没有可靠的方法来提取信息,如时间戳,MAC地址?

是的,是的;如果UUID是版本1或版本2(如RFC 4122中所述)。还有一个备用(非RFC 4122)版本4,被称为“COMB”,其中包含可以解析的时间戳(以及随机值),并且可以显示创建日期/时间。

奖励:Mahonri Moriancumer的UUID and GUID Generator and Forensics

1

OSSP uuid tool可以解码所有版本的UUID。在基于Debian的Linux系统上,您可以使用apt-get install uuid进行安装;对于其他发行版,软件包名称可能会有所不同。

要解码UUID,使用-d(解码)标志:

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

对于版本1点的UUID,这给MAC地址和时间戳 - 因为那是什么在V1 UUID。

相关问题