CSS 混淆对抗:利用 `unicode-bidi` 与不可见字符隐藏恶意文本

CSS 混淆对抗:利用 unicode-bidi 与不可见字符隐藏恶意文本

大家好,今天我们来探讨一个相对隐蔽但潜在危险的技术话题:利用 CSS 的 unicode-bidi 属性与不可见字符来隐藏恶意文本,并探讨相应的对抗策略。

1. 引言:CSS 混淆的必要性与风险

在Web安全领域,混淆技术扮演着重要的角色。它旨在通过各种方法,使得攻击者难以理解或分析代码的真实意图,从而增加攻击的难度。然而,混淆技术本身也可能被恶意利用,例如隐藏恶意链接、敏感信息,或者绕过安全检测机制。

CSS 作为前端开发的重要组成部分,其混淆技术相对较少被关注,但它同样存在潜在的风险。利用 CSS 混淆,攻击者可以将恶意文本隐藏在看似无害的页面中,诱导用户进行钓鱼、传播恶意软件,或者进行其他形式的攻击。

2. unicode-bidi 属性:控制文本双向显示

unicode-bidi 属性用于指定文本方向的嵌入级别,它可以影响文本的显示顺序,尤其是在包含从左到右(LTR)和从右到左(RTL)的文本时。这个属性是隐藏恶意文本的关键工具。

unicode-bidi 属性的常用值包括:

  • normal:不进行特殊处理,文本按照正常的双向算法显示。
  • embed:创建一个嵌入级别,文本方向由 direction 属性决定。
  • bidi-override:创建一个覆盖级别,强制文本按照 direction 属性指定的方向显示,忽略文本本身的双向性。
  • isolate:将周围的内容与嵌入的内容隔离,防止双向算法的意外影响。
  • isolate-override:类似于 bidi-override,但同时隔离周围的内容。
  • plaintext:用于处理纯文本,强制文本按照块级元素的 direction 属性显示。

示例:利用 bidi-override 隐藏文本

<!DOCTYPE html>
<html>
<head>
<style>
  .bidi-override {
    unicode-bidi: bidi-override;
    direction: rtl;
  }
</style>
</head>
<body>

<p>正常文本 <span class="bidi-override">这是一个反向显示的恶意链接:moc.elgoog.www</span></p>

</body>
</html>

在这个例子中,moc.elgoog.www 实际上是 www.google.com 的反向写法。由于 unicode-bidi: bidi-overridedirection: rtl 的作用,浏览器会将这段文本强制从右向左显示,使得用户看到的是 moc.elgoog.www。如果用户不仔细检查,很容易误以为这是一个合法的域名。

更进一步:结合 direction: ltrdirection: rtl

可以进一步结合 direction: ltrdirection: rtl 来构造更复杂的混淆。 例如:

<!DOCTYPE html>
<html>
<head>
<style>
  .bidi-override-rtl {
    unicode-bidi: bidi-override;
    direction: rtl;
  }

  .bidi-override-ltr {
    unicode-bidi: bidi-override;
    direction: ltr;
  }
</style>
</head>
<body>

<p>正常文本 <span class="bidi-override-rtl">!dlrow olleh</span><span class="bidi-override-ltr"> olleh dlrow!</span></p>

</body>
</html>

在这个例子中,最终显示的文本是 "hello world! hello world!",但其HTML代码却使用了反向的字符串。这种方式使得攻击者可以轻易地隐藏文本信息。

3. 不可见字符:更深层次的隐藏

不可见字符是指那些在文本中不显示任何视觉符号的字符。它们可以用于在文本中插入空格、换行、控制字符等。在 CSS 混淆中,不可见字符可以用于分割字符串、改变文本的长度,或者干扰安全检测。

常见的不可见字符包括:

  • 零宽度空格 (Zero-Width Space, ZWSP, U+200B)
  • 零宽度非连接符 (Zero-Width Non-Joiner, ZWNJ, U+200C)
  • 零宽度连接符 (Zero-Width Joiner, ZWJ, U+200D)
  • 左至右标记 (Left-To-Right Mark, LTR, U+200E)
  • 右至左标记 (Right-To-Left Mark, RTL, U+200F)

示例:利用零宽度空格隐藏文本

<!DOCTYPE html>
<html>
<head>
<style>
  .hidden-text {
    /* 假设这里有一个非常长的字符串,其中包含大量的零宽度空格 */
  }
</style>
</head>
<body>

<p>正常文本 <span class="hidden-text">这是一个隐​​藏的文本</span></p>

</body>
</html>

在这个例子中,隐​​藏 之间的 ​​ 是两个零宽度空格。 这些字符在浏览器中是不可见的,但它们确实存在于文本中。 如果安全检测系统没有考虑到这些不可见字符,就可能无法检测到隐藏的文本。

更隐蔽的技巧:结合 unicode-bidi 和不可见字符

unicode-bidi 和不可见字符结合起来,可以实现更深层次的隐藏。例如,可以将恶意链接拆分成多个部分,用不可见字符连接起来,并使用 unicode-bidi 属性来控制显示顺序。

<!DOCTYPE html>
<html>
<head>
<style>
  .bidi-override {
    unicode-bidi: bidi-override;
    direction: rtl;
  }
</style>
</head>
<body>

<p>正常文本 <span class="bidi-override">moc.elgoog.www&#x200B;.</span></p>

</body>
</html>

在这个例子中,&#x200B; 是零宽度空格的 HTML 实体编码。 它被插入到 moc.elgoog.www 之后,使得安全检测系统更难识别这个恶意链接。虽然显示效果和之前的例子一样,但背后的实现原理更复杂,更难以检测。

4. 实战案例:构造一个隐蔽的钓鱼链接

假设攻击者想要构造一个隐蔽的钓鱼链接,诱导用户访问恶意网站。 他可以利用 unicode-bidi 和不可见字符来实现这个目标。

<!DOCTYPE html>
<html>
<head>
<style>
  .bidi-override-rtl {
    unicode-bidi: bidi-override;
    direction: rtl;
  }

  .bidi-override-ltr {
    unicode-bidi: bidi-override;
    direction: ltr;
  }

  .fake-link {
    color: blue;
    text-decoration: underline;
    cursor: pointer;
  }
</style>
</head>
<body>

<p>请点击以下链接: <span class="fake-link"><span class="bidi-override-rtl">moc.liamg</span>&#x200B;<span class="bidi-override-ltr">.www</span></span></p>

<script>
  const fakeLink = document.querySelector('.fake-link');
  fakeLink.addEventListener('click', () => {
    window.location.href = 'http://www.evil.com'; // 替换为真实的恶意网站
  });
</script>

</body>
</html>

在这个例子中:

  • moc.liamggmail.com 的反向写法。
  • &#x200B; 是零宽度空格,用于分隔两个部分。
  • .www.www 的正向写法。
  • unicode-bidi 属性用于控制文本的显示顺序。
  • JavaScript 代码用于将点击事件重定向到恶意网站 http://www.evil.com

用户看到的链接可能是 www.gmail.com,但实际上点击后会跳转到恶意网站。

5. 对抗策略:如何检测和防御 CSS 混淆

检测和防御 CSS 混淆是一个复杂的问题,需要综合考虑多种因素。以下是一些可能的对抗策略:

  • 内容安全策略 (CSP): CSP 是一种安全机制,可以限制浏览器加载资源的来源,从而减少恶意代码的执行。 可以通过设置 CSP 策略,限制内联 CSS 的使用,或者只允许加载来自特定域名的 CSS 文件。
  • 代码审查: 对代码进行人工审查,可以发现隐藏在 CSS 中的恶意代码。 审查人员需要特别注意 unicode-bidi 属性和不可见字符的使用。
  • 安全扫描工具: 使用安全扫描工具可以自动检测网页中的潜在安全风险。 这些工具通常会检查 CSS 代码中是否存在混淆、恶意链接或其他可疑内容。
  • 输入验证和输出编码: 对用户输入进行验证,防止恶意代码注入。 对输出进行编码,确保特殊字符被正确转义,避免被解释为 HTML 代码。
  • 浏览器安全特性: 现代浏览器通常会提供一些安全特性,例如 XSS 过滤器,可以检测和阻止跨站脚本攻击。 确保浏览器启用了这些安全特性。
  • 正则表达式检测:编写正则表达式来检测恶意模式。例如,可以查找包含 unicode-bidi: bidi-overridedirection: rtldirection: ltr 的代码,以及不可见字符。

示例:使用正则表达式检测 unicode-bidi 混淆

function detectBidiOverride(cssText) {
  const regex = /unicode-bidi:s*bidi-override/i;
  return regex.test(cssText);
}

// 示例用法
const cssCode = `
  .bidi-override {
    unicode-bidi: bidi-override;
    direction: rtl;
  }
`;

if (detectBidiOverride(cssCode)) {
  console.log("检测到 unicode-bidi 混淆!");
} else {
  console.log("未检测到 unicode-bidi 混淆。");
}

示例:使用正则表达式检测不可见字符

function detectInvisibleCharacters(text) {
  const regex = /[u200B-u200FuFEFF]/g; // 匹配常见的不可见字符
  return regex.test(text);
}

// 示例用法
const text = "这是一个隐​​藏的文本";
if (detectInvisibleCharacters(text)) {
  console.log("检测到不可见字符!");
} else {
  console.log("未检测到不可见字符。");
}

更全面的检测策略

为了更全面地检测 CSS 混淆,可以将以上策略结合起来使用。 例如,可以先使用安全扫描工具进行初步检测,然后对可疑代码进行人工审查,并使用正则表达式来查找潜在的恶意模式。

对抗策略的局限性

需要注意的是,任何对抗策略都存在局限性。 攻击者可能会不断尝试新的混淆技术来绕过安全检测。 因此,需要不断更新和改进对抗策略,才能有效地保护 Web 应用的安全。

6. 其他混淆技术:不仅仅是 unicode-bidi 和不可见字符

虽然 unicode-bidi 和不可见字符是常见的 CSS 混淆手段,但攻击者还可以使用其他技术来隐藏恶意代码。

  • CSS 缩写和简写: 攻击者可以使用 CSS 缩写和简写来隐藏代码的真实意图。 例如,background: red url(evil.com) 可以被缩写为 background:red url(evil.com),这使得代码更难阅读。
  • CSS 变量 (Custom Properties): 攻击者可以使用 CSS 变量来存储恶意代码,并在需要时动态地将其插入到页面中。
  • CSS 滤镜 (Filters): 攻击者可以使用 CSS 滤镜来隐藏文本或图像,使其难以被人类或安全检测工具识别。
  • CSS 选择器: 复杂的 CSS 选择器可以用于定位特定的 HTML 元素,并在这些元素上应用恶意样式。
  • 利用 CSS 注入漏洞:如果应用程序存在 CSS 注入漏洞,攻击者可以将恶意 CSS 代码注入到页面中,从而控制页面的外观和行为。

7. 案例研究:真实世界的 CSS 混淆攻击

虽然 CSS 混淆攻击相对较少被报道,但它们确实存在。 一些研究人员已经发现了利用 CSS 混淆来隐藏恶意链接、窃取用户凭据,或者传播恶意软件的案例。

例如,在一些钓鱼攻击中,攻击者会使用 CSS 混淆来隐藏真实的登录表单,并用虚假的表单来欺骗用户。 当用户在虚假表单中输入用户名和密码时,这些信息会被发送到攻击者的服务器。

此外,一些恶意广告活动也使用了 CSS 混淆来绕过广告平台的安全检测。 这些广告可能会将用户重定向到恶意网站,或者在用户的设备上安装恶意软件。

8. 未来趋势:CSS 混淆的演变

随着 Web 安全技术的不断发展,CSS 混淆技术也在不断演变。 未来的 CSS 混淆可能会更加复杂和隐蔽,更难被检测和防御。

  • 更高级的混淆算法: 攻击者可能会使用更高级的混淆算法来加密 CSS 代码,使其难以被阅读和分析。
  • 利用 WebAssembly: 攻击者可以使用 WebAssembly 来编写复杂的混淆逻辑,并在浏览器中执行。
  • 机器学习: 攻击者可以使用机器学习技术来生成更有效的混淆代码,或者自动识别和利用安全漏洞。

9. 最佳实践:开发安全的 CSS 代码

为了开发安全的 CSS 代码,应该遵循以下最佳实践:

  • 保持 CSS 代码简洁易懂: 避免使用过于复杂的 CSS 选择器和样式规则。
  • 使用 CSS Lint 工具: 使用 CSS Lint 工具可以自动检测 CSS 代码中的潜在问题。
  • 限制内联 CSS 的使用: 尽量将 CSS 代码放在外部文件中,并使用 CSP 策略来限制内联 CSS 的使用。
  • 定期审查 CSS 代码: 定期审查 CSS 代码,查找潜在的安全风险。
  • 及时更新浏览器和安全工具: 及时更新浏览器和安全工具,以获取最新的安全补丁和防御机制。

10. 应对CSS混淆,安全常在心中

CSS 混淆是一种潜在的安全风险,需要引起足够的重视。 通过了解 CSS 混淆的原理、检测方法和对抗策略,可以有效地保护 Web 应用的安全。 开发者应该遵循最佳实践,开发安全的 CSS 代码,并定期审查代码,查找潜在的安全风险。 安全是一个持续的过程,需要不断学习和改进。

最后,记住,安全无小事,防范于未然。

更多IT精英技术系列讲座,到智猿学院

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注