从UUID中可以提取哪些数据?

26

我知道我们可以轻松提取UUID版本号。有没有可靠的方法来提取时间戳、MAC地址等信息?

谢谢!


1
你在问什么类型的UUID,使用的是哪种编程语言?没有这些信息的话,我认为你必须先了解UUID是如何生成的(版本),才能知道有哪些可以提取的内容。 - Sandy Simonton
6个回答

52

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

AAAAAAAA-BBBB-CCCC-DDDD-FFFFFFFFFFFF

DDDD部分的第一个(十六进制)数字确定了变体。

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

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

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

版本4只是随机选择的。

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

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

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

以下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分区


你在代码的第二行有个bug。应该写成: $uuid =~ s/-//g; 否则,脚本只会替换第一个'-'。除此之外,感谢分享这段代码。 - metator
@metator:第二行可能是要进行音译以删除所有破折号:“-”。在Perl 5.18中正确的代码是$uuid〜tr / - // d;(相当于Unix命令tr -d -)。此外,每一行都缩进了四个空格,当你复制代码时这很烦人。 - pabouk - Ukraine stay strong
我在RFC 4412中没有看到任何东西表明你有关变体编码的解释是正确的。它只使用了三个比特来确定变体,而不是整个十六进制位。 - Melab
这段代码报告的时钟ID与OSSP UUID不同。 不确定哪个是正确的。 - Luc

8

这并不一定是一种可靠的方法,因为取决于UUID的类型,它可能完全由随机位生成,也可能基于时间戳或基于MAC地址。因此,您可能能够获取其中的一些信息,但不能保证您能获取到任何内容。

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


7

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

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

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

对于版本1的UUID,这会给出MAC地址和时间戳——因为这就是v1 UUID中的内容。

6

我知道我们可以很容易地提取uuid版本号。是否有一种可靠的方法来提取时间戳、MAC地址等信息?

是的,如果UUID是版本1或版本2(如RFC 4122所述),则可以提取时间戳和MAC地址等信息。还有一种非RFC 4122标准的替代版本4,称为“COMB”,其中包括时间戳(以及随机值),可以解析并揭示创建日期/时间。

附加奖励:Mahonri Moriancumer的UUID和GUID生成器和取证工具


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

1
但是,并没有一种可靠的方法来确定任意UUID格式的字节块是否实际上是版本1的UUID还是随机数据。因此,你最好对收到的MAC地址持保留态度。 - Daniel Pryden
假设遵循标准,UUID版本号将包含在UUID中。 v1 UUID始终为xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx。请参见https://en.wikipedia.org/wiki/Universally_unique_identifier#Format - LaVache
@YeB:你说得对。但我的观点是:如果你看到一大块字节,看起来像是UUID,你不能确定它就是UUID,因此版本字段不一定可靠。也就是说:如果你试图从UUID中提取数据,你需要意识到攻击者可能会预先确定他们发送的位,而与标准规定无关。这意味着,正如我八年前所说:“最好你要对收到的MAC地址持怀疑态度”。 - Daniel Pryden

2

您可以查看Uuid的版本,但只有当您确定Uuid有效时才能信任它(请参见https://www.rfc-editor.org/rfc/rfc4122)。版本将告诉您您拥有哪种类型的Uuid,并使用它,您可以提取特定的信息位。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接