如何在文本中隐藏秘密消息 – 不是在图片和音频中,是在文本中:隐写术(3)

  • 从传递秘密消息到数字化的金丝雀陷阱
from peterdevito

如果您错过了关于隐写术的早前内容,可以在下面回顾:

如上,您已经学到了如何在图像和音频中隐藏秘密消息的方法,但这还不是隐写术的全部。

使用零宽度字符,您可以将秘密信息隐藏在纯文本内部,从而更安全地传递秘密消息;绕避关键字审查。甚至可以弄清楚谁在网上泄漏文件。一定程度上这对吹哨人不利。

Unicode 是文本的标准化编码格式,特别是UTF-8,大多数Web浏览器都使用 Unicode。因为 Unicode 需要支持世界上几乎所有书面语言,所以存在一些违反直觉的字符,例如零宽度不连接符零宽空格。例如前者在波斯语中使用,因为需要显示正确的印刷体形式。

于是您可以使用零宽度字符在任何未对零宽度字符做过滤的网页内插入不可见的隐形文本。

这个思路是选择两个任意的零宽度字符并将它们指定为1和0,然后将任何消息拆分为单个字符,然后以零宽度字符(分别为1和0)将其编码为二进制形式,从而将其隐藏在纯文本中。

最佳实践是在单词之间的空格中添加零宽度二进制码。否则,拼写检查倾向于认为该单词拼写错误。

Plain ‌​‌​‌​​​‍‌​​‌​‌‌‌‍‌​​‌​​​​‍‌​​‌‌‌‌​‍‌‌​‌​​‌‌‍‌‌​‌‌‌‌‌‍‌​​​‌​​​‍‌​​‌​‌‌‌‍‌​​‌‌‌‌​‍‌​​​‌​‌‌‍‌‌​‌‌‌‌‌‍‌​​‌​‌​​‍‌​​‌​‌‌​‍‌​​‌​​​‌‍‌​​‌‌​‌‌‍‌​​‌‌‌‌​‍‌‌​‌‌‌‌‌‍‌​​‌​​​‌‍‌​​‌​‌‌​‍‌​​‌​​​‌‍‌​​‌​‌​‌‍‌​​‌‌‌‌​‍‌‌​‌‌‌‌‌‍‌​​​‌‌​​‍‌​​‌​‌‌‌‍‌​​‌​‌‌​‍‌​​​‌​‌‌‍‌‌​‌‌‌‌‌‍‌​​‌​‌‌​‍‌​​​‌‌​​‍‌‌​‌‌‌‌‌‍‌​​​‌​‌‌‍‌​​‌​‌‌‌‍‌​​‌​‌‌​‍‌​​​‌‌​​‍‌‌​​​​​​‍‌‌​‌‌‌‌​‍‌‌​​​​​​‍‌‌​‌‌‌‌​text, nothing to see here

要查看隐藏了什么,复制这个文本 “plain text”,把它贴到这个工具上 online zero-width detention tool 上即可。

您可以用它来做什么?

在普通的文本中隐藏信息的能力本身就非常有用,您可以传输机密信息在队友之间、或者简单地绕避关键字审查,比如在微信上。但使这种技术真正精妙的是,它能在重新格式化后存活下来,并且,无论文本被复制粘贴到哪里,秘密消息都能携带。隐藏的字符在 nano 等文本编辑器中都不会暴露。

这应该是秘密通信的首选方式。

你可以使用经典的间谍伎俩,在公共空间发布一篇文章、或某种类型的文本文档。例如,你可以在 Craigslist 广告中隐藏一条秘密信息,然后让一个单独的接收者或一群合作者定期检查当地的 Craigslist 广告,寻找特定的关键词。他们会知道如何检查其中是否存在隐藏的秘密信息。

当必须确保两个接头人之间没有直接的联系时,这是一种交换信息的有益方法。

一个灾难案例 …… 当事人也许可以事先通过隐写术处理这则消息

稍微古老一点的用例是传统的金丝雀陷阱。如果您曾经读过任何神秘小说,那肯定能对这种陷阱的工作方式很熟悉。这是一种侦测情报泄露的方法,就是故意将不同版本的机密情报泄露给嫌疑人,然后观察信息的走向以判断泄密者究竟是谁。根据版本,您会知道哪个人泄漏了信息。

这是一种很经典的手段。众所周知,国会助理通过在提供给其他办公室和游说者的文件中故意使用拼写错误的单词或其他小的语法错误来泄露数据。

但是这样做的问题是,如果有人能掌握两个不同的版本,他们马上就会知道你要干什么了。这种情况下零宽度字符就可以派上用场了。

通过使用零宽度字符,一般人即使掌握了两个不同版本的文档或文本,也不太可能注意到那里面藏着什么;当然,如果有人通过截图或用打印机复印以泄漏信息,同样会被抓住。对于吹哨人来说,这是非常危险的 —— EXIF数据会直接指向你的设备,以及许多打印机采用的微点,这些微点可以唯一地识别打印的东西。

最后,零宽度字符可以用来改变 URL。不幸的是由于ICANN的规定,你不能注册一个零宽度字符的域名。不过,在本地网络的IDN欺骗中,它是相当有用的 —— IDN欺骗是钓鱼式攻击的手法之一。它利用国际化域名可以以 Unicode 字符命名网址的特性,通过同形异义字实现诱骗点击。

它也可以只用来破坏一个URL。下面是 GitHub URL 的例子。

https://github.com/holdTheDoorHoid
https://github.com/hold​TheDoorHoid

它俩看起来可能完全相同,但是,第二个链接在 “hold” 之后使用了零宽度字符,这会阻止其正常工作 —— 这个链接是打不开的。

下面介绍一下如何实际使用这种技术。

使用真实加密以提高安全性

必须首先强调这点:如果您想要保证自己的信息安全,仅仅将信息编码成零宽度二进制码是不足以加密的。任何人只要有合适的程序,就可以轻松破译您的秘密信息。

您真正应该使用的是对称或非对称加密方案。如果只有一个目标人是预期的接收者,那么像PGP这样的非对称加密方案将最有效。但如果信息接收者是一群人,可能要使用对称加密。

它是基于这样的原理,即:几乎没有人会在秘密空间中寻找秘密。

也就是说,与其使用PGP加密零宽度的消息,不如在PGP加密的邮件中使用零宽度字符作为额外的验证层。

你可以使用两种方式来做到这点。

第一种方式是一封普通的邮件正文,而实际的信息隐藏在零宽度中。

另一种方式是,在第一句中隐藏特定的代码字,然后让响应者在他们的第一句中使用该代码字或一个响应代码字。

显然第二种策略更好。因为如果有人确实掌握了与您接头的人的PGP密钥,那么他们极有可能会想要寻找零宽度字符,当对方没有使用正确的代码字回应时,您就可以立即预知到危险。

选项1:在线直接创建零宽度消息

要开始发送零宽度信息,打开 Steganographr 页面,在 “私密信息” 字段中粘贴您的(可以是加密的)信息,在 “公开信息” 字段中粘贴一个极为普通的或完全不重要的信息,然后点击 “Steganographize”。

然后,您将能够复制新生成的消息并按需进行处理。只需将其复制并粘贴,它仍将完整保留隐藏在其中的秘密消息。

当接头的人需要显示隐秘消息时,同样可以使用 Steganographr。滚动到底部,将文本粘贴到 “公开私密消息” 的字段中,然后单击 “Desteganographize”。

但是,这里的一个问题是,我们必须相信该网站不会保存这些消息或借此伤害你。幸运的是,Steganographr 开源,因此您可以简单地将其复制并托管在自己的网站上。

尤其是,您可以编辑源码。要进行更改只需要将十六进制值更改为所需的新字符即可。

// Convert the ones, zeros, and spaces of the hidden binary data to their respective zero-width characters
function bin2hidden($str) {
    $str = str_replace(' ', "\xE2\x81\xA0", $str); // Unicode Character 'WORD JOINER' (U+2060) 0xE2 0x81 0xA0
    $str = str_replace('0', "\xE2\x80\x8B", $str); // Unicode Character 'ZERO WIDTH SPACE' (U+200B) 0xE2 0x80 0x8B
    $str = str_replace('1', "\xE2\x80\x8C", $str); // Unicode Character 'ZERO WIDTH NON-JOINER' (U+200C) 0xE2 0x80 0x8C
    return $str;
}

// Convert zero-width characters to hidden binary data
function hidden2bin($str) {
    $str = str_replace("\xE2\x81\xA0", ' ', $str); // Unicode Character 'WORD JOINER' (U+2060) 0xE2 0x81 0xA0
    $str = str_replace("\xE2\x80\x8B", '0', $str); // Unicode Character 'ZERO WIDTH SPACE' (U+200B) 0xE2 0x80 0x8B
    $str = str_replace("\xE2\x80\x8C", '1', $str); // Unicode Character 'ZERO WIDTH NON-JOINER' (U+200C) 0xE2 0x80 0x8C
    return $str;
}

以下是有用的零宽度字符及其十六进制代码的列表。

例如,要从零宽度不连接符更改为蒙古语元音分隔符,就像这样替换:

str_replace('1', "\xE1\xA0\x8E", $str)

确保在两边都以相同的方式更改字符的十六进制编码。这样它就可以适当地编码和解码了。

选项2:从命令行创建零宽度消息

每次要发送和解码消息时都需要打开网页这可能会很烦人,特别是如果您经常这样做的话。

幸运的是,有人已经在GitHub上创建了一个名为 ZWFP 的工具,用于对零宽度消息进行编码,并且该工具可从命令行运行,很便捷。

但是要注意的一件事是,您将无法轻松更改用于零宽度二进制文件的字符。只要事先加密您的消息,实际上就没有什么可担心的。

尤其要注意,在发送和接收消息的双方,不可能一个人用网站编码,另一个人用命令行解码,反之亦然。您必须确保双方使用的是同一种方式来编码和解码。

开始之前请确保您的计算机上安装了Go编程语言。如果还没有,可以访问Go的下载页面,该网站还有详细的安装说明,如果您是第一次使用Go,不要跳过说明,因为您需要改变PATH环境变量。

安装Go之后,您可以从工作目录中获取 ZWFP 的 GitHub 存储库。

~/go$ go get -u github.com/vedhavyas/zwfp/cmd/zwfp/...

这些文件非常小,几乎可以在您按完Enter之前就下载完毕。除了新的命令提示符外这里没有任何迹象表明下载成功,但它应该就在那里了。现在,移至 “zwfp”文件夹,然后构建该工具。

~/go$ cd /go/src/github.com/vedhavyas/zwfp/cmd/zwfp
~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ go build

再一次,除了一个新的命令提示符外没有任何提示。从这里开始,运行测试工具。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ go test ./...

?       github.com/vedhavyas/zwfp/cmd/zwfp      [no test files]

现在来看看如何使用ZWFP。不幸的是,它的使用说明非常模糊,因此更深入地研究下使用该工具的正确方法。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ ./zwfp

Usage:
         ./zwfp CoverText Payload
                 Embeds Payload into CoverText

         ./zwfp SteganoText
                 Extracts Payload from SteganoText

首先,使用两个参数利用ZWFP对消息进行编码。一个是看起来很普通的表面消息,每个人都会看到的公开信息,然后是隐藏的消息。

如果我们希望 “ CoverText” 作为表面文本,而 “Payload” 作为隐藏消息,那么它看起来像这样:

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ ./zwfp CoverText Payload

CoverText

但是您肯定需要将其保存在一个文件中,无论如何。因此,来尝试一下使用不同的表面文字和隐藏文字。

继续:将 “You see this right?” 作为表面消息,将 “But this is a hidden message in that text.” 作为隐藏文字(如果每个参数使用多个单词,那么必须用引号将它们包起来)

然后,将其保存到 / Desktop 目录中的新文件中。对于此示例它将是一个新的 “secret.txt” 文件。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ ./zwfp "You see this right?" "But this is a hidden message in that text." > /home/kali/Desktop/secret.txt

使用 nano 查看这个文本文件。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ nano /home/kali/Desktop/secret.txt

  GNU nano 4.9.2                /home/kali/Desktop/secret.txt
You see this right?

                                    [ Read 1 line ]
^G Get Help   ^O Write Out  ^W Where Is   ^K Cut Text   ^J Justify    ^C Cur Pos
^X Exit       ^R Read File  ^\ Replace    ^U Paste Text ^T To Spell   ^_ Go To Line

很好,表面文字清晰可见。现在尝试看一下里面隐藏着什么。

为此,可以使用 vim 查看隐藏的字符。正如您在下面看到的,它与nano的显示有很大不同。输入 :qa 并按 Enter 退出vim。

ZWFP的用法并没有告诉您如何解码消息。为此 cat 这个文件,然后使用 xargs -0 查看隐藏的内容。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ cat /home/kali/Desktop/secret.txt | xargs -0 ./zwfp

Cover Text: You see this right?

Payload: But this is a hidden message in that text.

要知道 xargs -0 做了什么,查看 xargs手册页的部分。

~/go/src/github.com/vedhavyas/zwfp/cmd/zwfp$ man xargs

XARGS(1)                     General Commands Manual                    XARGS(1)

NAME
       xargs - build and execute command lines from standard input

SYNOPSIS
       xargs [options] [command [initial-arguments]]

DESCRIPTION
       This  manual  page documents the GNU version of xargs.  xargs reads items
       from the standard input, delimited by blanks (which can be protected with
       double  or  single  quotes  or a backslash) or newlines, and executes the
       command (default is /bin/echo) one or more times with  any  initial-argu‐
       ments  followed  by  items  read from standard input.  Blank lines on the
       standard input are ignored.

       The command line for command is built up until it  reaches  a  system-de‐
       fined  limit (unless the -n and -L options are used).  The specified com‐
       mand will be invoked as many times as necessary to use up the list of in‐
       put  items.   In general, there will be many fewer invocations of command
       than there were items in the input.  This will normally have  significant
       performance benefits.  Some commands can usefully be executed in parallel
       too; see the -P option.

       Because Unix filenames can contain blanks and newlines, this default  be‐
       haviour is often problematic; filenames containing blanks and/or newlines
       are incorrectly processed by xargs.  In these situations it is better  to
       use the -0 option, which prevents such problems.   When using this option
       you will need to ensure that the program which  produces  the  input  for
       xargs  also uses a null character as a separator.  If that program is GNU
       find for example, the -print0 option does this for you.

       If any invocation of the command exits with a status of 255,  xargs  will
       stop  immediately without reading any further input.  An error message is
       issued on stderr when this happens.

OPTIONS
       -0, --null
              Input items are terminated by  a  null  character  instead  of  by
              whitespace,  and  the  quotes and backslash are not special (every
              character is taken literally).  Disables the end of  file  string,
              which is treated like any other argument.  Useful when input items
              might contain white space, quote marks, or backslashes.   The  GNU
              find -print0 option produces input suitable for this mode.

使用 Chrome 扩展程序显示零宽度字符

如果您想保护自己不受零宽度字符的侵害,最好的方法是使用一个简单的Chrome浏览器扩展程序。该扩展会将零宽度字符替换为各种表情符号。

转到 Chrome 网上应用商店,然后在浏览器中添加 “Replace zero-width characters with emojis”。之后重新启动 Chrome。

不幸的是,该扩展程序不会自动运行,因此当您怀疑或好奇的时候需要手动检查每个页面。

要运行该扩展程序,请单击其在浏览器栏右侧的按钮(灰色正方形内的 “ R”),然后单击 “Show me the $!”。

当 Chrome 中的文档或网页使用零宽度字符隐藏信息时,该工具将使其非常明显。

有趣的是,由于它会将零宽度字符一对一替换为各种表情符号,因此您可以看到表情符号形式的二进制。如果您想探索或修改该工具,可以在GitHub上找到源代码。

尽管该扩展有用,但不要让它给您带来错误的安全感。它仅检测网页或文档中的零宽度字符,而不能检测隐藏在URL中的东西

复制不包含零宽度字符的文本

如果您无法使用 Chrome 扩展程序,或者您想要一个功能更强大的工具来删除文档中的零宽度字符,那么需要使用一个名为 Diffchecker 的网站。

Diffchecker 是一种工具,用于突出显示两个相似文档之间的差异,这使其成为检测经典金丝雀陷阱的有力工具

由于并非所有人都知道零宽度字符,因此人们有时会尝试使用多余的空格和故意的拼写错误来达到相同的效果。

如果您有两个版本的文档,Diffchecker 会突出显示这些差异,如果只有一个版本,则 Diffchecker 会将零宽度字符显示为点。

只需打开该网站,然后将文本复制粘贴到 “原始文本” 字段中即可。如果文本中包含零宽​​度字符,它们将开始显示为点。

如果您有第二个版本,请粘贴 “更改的文本” 字段,然后单击页面底部的 “查找差异”。

Diffchecker 也是查找URL中零宽度字符的理想选择,并且在调查可疑域时应该是首选。

如果找到零宽度字符,则删除它们很简单,只需突出显示点的部分并按 Backspace 或 Delete 键即可。

现在,您可以安全地复制文本了。如下所示,它将不再能够找到隐藏的消息。

如果您确实碰巧在试图使用金丝雀陷阱的同一文档中找到了两个版本,那么就可以将另一个版本用作替罪羊,将矛头指向其所有者,以便无法再追溯到您。

如果您希望在本地计算机上使用,那么有一个名为 Notepad ++的程序,该程序可以安装在 Kali 和其他 Linux 发行版上。在 Notepad ++中,复制并粘贴文本,然后在顶部栏上单击 “Encoding”,然后单击 “Encode in ANSI”。

Confidential Announcement: ‌​‌​‌​​​‍‌​​‌​‌‌‌‍‌​​‌​​​​‍‌​​‌‌‌‌​‍‌‌​‌​​‌‌‍‌‌​‌‌‌‌‌‍‌​​​‌​​​‍‌​​‌​‌‌‌‍‌​​‌‌‌‌​‍‌​​​‌​‌‌‍‌‌​‌‌‌‌‌‍‌​​‌​‌​​‍‌​​‌​‌‌​‍‌​​‌​​​‌‍‌​​‌‌​‌‌‍‌​​‌‌‌‌​‍‌‌​‌‌‌‌‌‍‌​​‌​​​‌‍‌​​‌​‌‌​‍‌​​‌​​​‌‍‌​​‌​‌​‌‍‌​​‌‌‌‌​‍‌‌​‌‌‌‌‌‍‌​​​‌‌​​‍‌​​‌​‌‌‌‍‌​​‌​‌‌​‍‌​​​‌​‌‌‍‌‌​‌‌‌‌‌‍‌​​‌​‌‌​‍‌​​​‌‌​​‍‌‌​‌‌‌‌‌‍‌​​​‌​‌‌‍‌​​‌​‌‌‌‍‌​​‌​‌‌​‍‌​​​‌‌​​‍‌‌​​​​​​‍‌‌​‌‌‌‌​‍‌‌​​​​​​‍‌‌​‌‌‌‌​This is some confidential text that you really shouldn't be sharing anywhere else.

通过更改文档的编码实际上可以暴露零宽度字符,这些字符依靠Unicode和UTF-8。现在零宽度字符看起来像是乱七八糟的东西,在阅读文档时很容易找到。

零宽度字符非常适合隐藏消息

零宽度字符是一个有用的工具。但是,绝对不要忘记它们的局限性。如果将它们用作秘密通信方式,您应始终记住对其进行加密。否则就是相当于下了一个巨大的赌注 “没有人会去寻找隐藏的消息”。⚪️

Use Zero-Width Characters to Hide Secret Messages in Text (& Even Reveal Leaks)

2 thoughts on “如何在文本中隐藏秘密消息 – 不是在图片和音频中,是在文本中:隐写术(3)

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据