利用视觉模糊测试技术探索Z͌̈́̾a͊̈́l͊̿g̏̉͆o̾̚̚S̝̬ͅc̬r̯̼͇ͅi̼͖̜̭͔p̲̘̘̹͖t̠͖̟̹͓͇ͅ
字数 853 2025-08-18 11:37:07

ZalgoScript与视觉模糊测试技术详解

1. ZalgoScript概述

ZalgoScript是一种利用Unicode组合字符创造视觉混乱效果的JavaScript代码技术。这些特殊字符会导致文本在浏览器中呈现异常,产生"溢出"或"破坏"正常布局的效果。

1.1 技术背景

  • 起源于Twitter将字符限制从140提升到280后对Unicode字符的探索
  • 某些Unicode组合字符会导致浏览器渲染异常
  • 无法通过DOM树结构直接识别,必须通过视觉呈现检测

2. Unicode组合字符基础

2.1 关键Unicode码点

以下码点通过自我重复可产生Zalgo效果(多为Unicode合并字符):

834, 1425, 1427, 1430, 1434, 1435, 1442, 1443, 1444, 
1445, 1446, 1447, 1450, 1453, 1557, 1623, 1626, 3633, 
3636, 3637, 3638, 3639, 3640, 3641, 3642, 3655, 3656, 
3657, 3658, 3659, 3660, 3661, 3662

2.2 字符生成方法

// 单个字符重复
document.write(String.fromCharCode(834).repeat(20))

// 多个字符组合
document.write(String.fromCharCode(311)+String.fromCharCode(844).repeat(20))

3. 视觉模糊测试器构建

3.1 测试页面设计

<style>
.parent {
  position: absolute;
  height: 50%;
  width: 50%;
  top: 50%;
  transform: translateY(-50%);
}
.fuzz {
  height: 300px;
  width:5000px;
  position: relative;
  left:50%;
  top: 50%;
  transform: translateY(-50%);
}
</style>
<body>
<div class="parent">
  <div class="fuzz" id="test"></div>
</div>
<script>
var chars = location.search.slice(1).split(',');
if(chars.length > 1) {
  document.getElementById('test').innerHTML = 
    String.fromCharCode(chars[0]) + 
    String.fromCharCode(chars[1]).repeat(100);
} else {
  document.getElementById('test').innerHTML = 
    String.fromCharCode(chars[0]).repeat(100);
}
</script>

3.2 测试流程

  1. 从查询字符串读取1-2个字符编码
  2. 使用innerHTML和String.fromCharCode输出字符
  3. 通过CSS将内容平移以便检测边缘溢出

4. 自动化测试实现

4.1 依赖工具

  • Headless Chrome
  • Puppeteer (NodeJS模块)
  • PNG库

4.2 核心代码实现

const PNGReader = require('png.js');
const puppeteer = require('puppeteer');

// 判断像素是否为白色
function isWhite(pixel) {
  return pixel[0] === 255 && pixel[1] === 255 && pixel[2] === 255;
}

// 判断像素是否在目标区域(顶部、左侧、右侧或底部)
function isInRange(x,y) {
  return y <= 120 || y >= 220 || x <= 180;
}

// 模糊测试主函数
async function fuzzBrowser(writeStream, page, chr1, chr2) {
  const url = typeof chr2 !== 'undefined' 
    ? `http://localhost/visualfuzzer/index.php?${chr1},${chr2}`
    : `http://localhost/visualfuzzer/index.php?${chr1}`;
  
  await page.goto(url);
  const buf = await page.screenshot({
    clip: {x:0, y:0, width:400, height: 300}
  });
  
  const reader = new PNGReader(buf);
  reader.parse((err, png) => {
    if(err) throw err;
    
    outerLoop:
    for(let x=0; x<400; x++) {
      for(let y=0; y<300; y++) {
        if(!isWhite(png.getPixel(x,y)) && isInRange(x,y)) {
          const output = typeof chr2 !== 'undefined'
            ? `${chr1},${chr2}\n`
            : `${chr1}\n`;
          
          writeStream.write(output);
          console.log(`Interesting char(s): ${output.trim()}`);
          break outerLoop;
        }
      }
    }
  });
}

4.3 测试执行

(async() => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  const fs = require('fs');
  
  // 已知有效的单个字符
  const singleChars = {
    834:1,1425:1,1427:1,1430:1,1434:1,1435:1,1442:1,
    1443:1,1444:1,1445:1,1446:1,1447:1,1450:1,1453:1,
    1557:1,1623:1,1626:1,3633:1,3636:1,3637:1,3638:1,
    3639:1,3640:1,3641:1,3642:1,3655:1,3656:1,3657:1,
    3658:1,3659:1,3660:1,3661:1,3662:1
  };
  
  const writeStream = fs.createWriteStream('logs.txt', {flags: 'a'});
  
  // 测试768-879范围内的字符组合
  for(let i=768; i<=879; i++) {
    for(let j=768; j<=879; j++) {
      if(singleChars[i] || singleChars[j]) continue;
      
      process.stdout.write(`Fuzzing chars ${i},${j}\r`);
      await fuzzBrowser(writeStream, page, i, j)
        .catch(err => {
          console.log("Failed fuzzing browser:"+err);
          browser.close();
          writeStream.end();
        });
    }
  }
  
  await browser.close();
  await writeStream.end();
})();

5. ZalgoScript实际应用

5.1 Edge浏览器漏洞利用

在Edge浏览器中,某些特殊字符组合会被错误地识别为空白字符,从而可以构造有效的ZalgoScript。

5.2 示例代码

a=[];
for(i=768;i<=858;i++){
  a.push(String.fromCharCode(837)+String.fromCharCode(i).repeat(5));
}
a[10]+='alert('
a[15]+='1';
a[20]+=')';
input.value=a.join('')
eval(a.join(''));

5.3 典型ZalgoScript

̀ͅͅalert(1ͅͅ

6. 防御措施

  1. 输入过滤:严格限制允许的Unicode字符范围
  2. 输出编码:对动态内容进行适当的HTML编码
  3. 内容安全策略(CSP):限制内联脚本执行
  4. 浏览器更新:保持浏览器最新版本以修复已知渲染问题

7. 资源

通过以上技术,安全研究人员可以系统地发现和测试浏览器对Unicode组合字符的渲染异常,从而识别潜在的ZalgoScript攻击向量。

ZalgoScript与视觉模糊测试技术详解 1. ZalgoScript概述 ZalgoScript是一种利用Unicode组合字符创造视觉混乱效果的JavaScript代码技术。这些特殊字符会导致文本在浏览器中呈现异常,产生"溢出"或"破坏"正常布局的效果。 1.1 技术背景 起源于Twitter将字符限制从140提升到280后对Unicode字符的探索 某些Unicode组合字符会导致浏览器渲染异常 无法通过DOM树结构直接识别,必须通过视觉呈现检测 2. Unicode组合字符基础 2.1 关键Unicode码点 以下码点通过自我重复可产生Zalgo效果(多为Unicode合并字符): 2.2 字符生成方法 3. 视觉模糊测试器构建 3.1 测试页面设计 3.2 测试流程 从查询字符串读取1-2个字符编码 使用innerHTML和String.fromCharCode输出字符 通过CSS将内容平移以便检测边缘溢出 4. 自动化测试实现 4.1 依赖工具 Headless Chrome Puppeteer (NodeJS模块) PNG库 4.2 核心代码实现 4.3 测试执行 5. ZalgoScript实际应用 5.1 Edge浏览器漏洞利用 在Edge浏览器中,某些特殊字符组合会被错误地识别为空白字符,从而可以构造有效的ZalgoScript。 5.2 示例代码 5.3 典型ZalgoScript 6. 防御措施 输入过滤 :严格限制允许的Unicode字符范围 输出编码 :对动态内容进行适当的HTML编码 内容安全策略(CSP) :限制内联脚本执行 浏览器更新 :保持浏览器最新版本以修复已知渲染问题 7. 资源 Zalgo文本生成器: 传送门 Unicode组合字符规范: Unicode标准 Puppeteer文档: GitHub 通过以上技术,安全研究人员可以系统地发现和测试浏览器对Unicode组合字符的渲染异常,从而识别潜在的ZalgoScript攻击向量。