【问题标题】:What kind of data can you extract from a UUID?您可以从 UUID 中提取哪些类型的数据?
【发布时间】:2017-05-10 20:34:23
【问题描述】:

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

谢谢!

【问题讨论】:

  • 您要问的是什么风格的 UUID,什么语言?如果没有这些信息,我想说你必须知道 UUID 是如何生成的(版本)才能知道可以提取什么。

标签: uuid


【解决方案1】:

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

AAAAAAA-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

【讨论】:

  • 您在第二行代码中有一个错误。应该是:$uuid =~ s/-//g;否则,脚本只会替换第一次出现的“-”。除此之外,感谢您分享此代码。
  • @metator:第二行可能是为了删除所有破折号的音译:-。在 Perl 5.18 中工作的正确代码是 $uuid=~tr/-//d;(相当于 Unix 命令 tr -d -)。此外,每行都缩进了四个空格,这在您复制代码时很烦人。
  • 我在 RFC 4412 中没有看到任何内容表明您对变体编码的解释是正确的。它只使用三个位来确定变体,而不是整个十六进制。
  • 这段代码上报的clock id和OSSP uuid不同。不知道哪个是正确的。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 但不一定有可靠的方法来确定任意 UUID 格式的字节块实际上是版本 1 UUID 还是只是随机数据。因此,充其量您只能对获得的 MAC 地址持保留态度。
        • @DanielPryden 假设遵循标准,UUID 版本号包含在 UUID 中。 v1 UUID 始终为 xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx。见en.wikipedia.org/wiki/Universally_unique_identifier#Format
        • @YeB:你是对的。但我的观点是:如果你看到一大块 看起来 像 UUID 的字节,你不能确定它 UUID,因此版本字段不一定可靠。也就是说:如果您尝试从 UUID 中提取数据,则需要注意攻击者可能会预先确定他们发送的位,而与标准所说的无关。这意味着,正如我在八年前所说的那样:“充其量你只能对你得到的 MAC 地址持保留态度”。
        【解决方案6】:

        您可以查看 Uuid 的版本,但只有在您确定 Uuid 有效的情况下才能信任该版本(请参阅https://www.rfc-editor.org/rfc/rfc4122)。该版本会告诉你你拥有什么样的 Uuid,并且使用它你可以提取特定的信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-11
          • 1970-01-01
          • 2011-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-17
          相关资源
          最近更新 更多