1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
'use strict'
const net = require('net')
const fs = require('fs/promises')
const path = require('path')
const serverFuzzFnMap = require('./server')
const clientFuzzFnMap = require('./client')
const port = process.env.PORT || 0
const timeout = parseInt(process.env.TIMEOUT, 10) || 300_000 // 5 minutes by default
const netServer = net.createServer((socket) => {
socket.on('data', (data) => {
// Select server fuzz fn
const serverFuzzFns = Object.values(serverFuzzFnMap)
const serverFuzzFn = serverFuzzFns[Math.floor(Math.random() * serverFuzzFns.length)]
serverFuzzFn(socket, data)
})
})
const waitForNetServer = netServer.listen(port)
// Set script to exit gracefully after a set period of time.
const timer = setTimeout(() => {
process.kill(process.pid, 'SIGINT')
}, timeout)
async function writeResults (resultsPath, data) {
try {
await fs.writeFile(resultsPath, JSON.stringify(data, null, 2))
console.log(`=== Written results to ${resultsPath} ===`)
} catch (err) {
console.log(`=== Unable to write results to ${resultsPath}`, err, '===')
}
}
async function fuzz (buf) {
// Wait for net server to be ready
await waitForNetServer
// Select client fuzz fn based on the buf input
await Promise.all(
Object.entries(clientFuzzFnMap).map(async ([clientFuzzFnName, clientFuzzFn]) => {
const results = {}
try {
await clientFuzzFn(netServer, results, buf)
} catch (err) {
clearTimeout(timer)
const output = { clientFuzzFnName, buf: { raw: buf, string: buf.toString() }, raw: JSON.stringify({ clientFuzzFnName, buf: { raw: buf, string: buf.toString() }, err, ...results }), err, ...results }
console.log(`=== Failed fuzz ${clientFuzzFnName} with input '${buf}' ===`)
console.log('=== Fuzz results start ===')
console.log(output)
console.log('=== Fuzz results end ===')
await writeResults(path.resolve(`fuzz-results-${Date.now()}.json`), output)
throw err
}
})
)
}
module.exports = {
fuzz
}
|