那些CTF中的神操作之零宽度字符隐写

883 阅读3分钟

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!

简介

首先我们要得知,什么是零宽度字符。

零宽度字符是一些不可见的,不可打印的字符。它们存在于页面中主要用于调整字符的显示格式。

常见的零宽度字符及它们的unicode码和原本用途

零宽度空格符 (zero-width space) U+200B : 用于较长单词的换行分隔

零宽度非断空格符 (zero-width no-break space) U+FEFF : 用于阻止特定位置的换行分隔

零宽度连字符 (zero-width joiner) U+200D : 用于阿拉伯文与印度语系等文字中,使不会发生连字的字符间产生连字效果

零宽度断字符 (zero-width non-joiner) U+200C : 用于阿拉伯文,德文,印度语系等文字中,阻止会发生连字的字符间的连字效果

左至右符 (left-to-right mark) U+200E : 用于在混合文字方向的多种语言文本中(例:混合左至右书写的英语与右至左书写的希伯来语),规定排版文字书写方向为左至右

右至左符 (right-to-left mark) U+200F : 用于在混合文字方向的多种语言文本中,规定排版文字书写方向为右至左

注:加密和解密是一个可逆的过程,但是一定要用相同的方式(相同的工具/网址)进行加解密

效果

比如说

‌‌‌‌‍‎‍‎Hello,misc‌‌‌‌‍‎‌‌‌‌‌‍‎‌‍!‌‌‌‌‍‎‍

这样看,就是简简单单的一串字符,但其实里面运用了零宽度字符隐写。

我们可以将它作为txt在010editor里打开,或者对其进行编码如unicode

\u200C\u200C\u200C\u200C\u200D\u200E\u200D\u200EHello,misc\u200C\u200C\u200C\u200C\u200D\u200E\uFEFF\u200C\u200C\u200C\u200C\u200C\u200D\u200E\u200C\u200D!\u200C\u200C\u200C\u200C\u200D\u200E\u200D\uFEFF

大家会发现,其实里面是多了许多东西的。

如何判断

这里就简单说明几个方法

1.使用010editor查看文本,如果有一些不能显示的字符便可以判断是否是零宽度字符隐写

2.使用命令vim查看

3.编码查看,在一些编码过程中隐写内容也会编码,我们便可以用这种方法查看。

4.放入txt文本,逐个查看,因为表面只有这么多字符,其实有隐藏的东西,若存在零宽隐写,那么当我们逐个查看时就会出现向下还会保持当前的位置。

具体加密方式

先将内容转化为二进制

const zeroPad = num => ‘00000000’.slice(String(num).length) + num; 
const textToBinary = username => (
   username.split('').map(char =>
     zeroPad(char.charCodeAt(0).toString(2))).join(' ') 
);

在将二进制进行加密,遍历二进制字符串,并将每个1转换为0宽度空间,将每个0转换为零宽非连接符。转换字母后,我们将插入0宽连接符,然后再下一个。

const binaryToZeroWidth = binary => (
   binary.split('').map((binaryNum) => {
     const num = parseInt(binaryNum, 10);
     if (num === 1) {
       return '​'; // zero-width space
     } else if (num === 0) {
       return '‌'; // zero-width non-joiner
     }
     return '‍'; // zero-width joiner
   }).join('') // zero-width no-break space
);

解密

有专门的解密网站,也是本人常用的网站。

330k.github.io/misc_tools/…

当然也有专门的github项目。

github.com/yuanfux/zer…

结尾

以上给大家带来的是零宽隐写的一些套路,是不是很有创意,大家学会了也可以自己尝试加密或破解一下,若大家还有知道其他的创意套路也可以在评论区留言互相学习,感谢阅读。