beef-npm
Version:
Node.js package to install and interact with BeEF (Browser Exploitation Framework)
185 lines (162 loc) • 7.61 kB
JavaScript
const { exec } = require('child_process');
const axios = require('axios');
const path = require('path');
const fs = require('fs');
const readline = require('readline');
const BEEF_DIR = path.join(__dirname, 'beef');
const BEEF_REPO = 'https://github.com/beefproject/beef.git';
const BEEF_PORT = 3000; // Default BeEF port
// Function to install BeEF
exports.installBeEF = function() {
return new Promise((resolve, reject) => {
if (fs.existsSync(BEEF_DIR)) {
return reject(`BeEF directory already exists: ${BEEF_DIR}`);
}
console.log('Cloning BeEF repository...');
exec(`git clone ${BEEF_REPO} ${BEEF_DIR}`, (error) => {
if (error) {
return reject(`Error cloning BeEF: ${error.message}`);
}
console.log('BeEF cloned successfully.');
resolve();
});
});
};
function updateCredentials(username, password) {
const configPath = path.join(BEEF_DIR, 'config.yaml');
let config = fs.readFileSync(configPath, 'utf8');
// Replace the default username and password in the config file
config = config.replace(/username: '.*?'/, `username: '${username}'`);
config = config.replace(/passwd: '.*?'/, `passwd: '${password}'`);
fs.writeFileSync(configPath, config, 'utf8');
}
// Function to prompt for new credentials
function promptForCredentials() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
return new Promise((resolve) => {
rl.question('Enter new BeEF username: ', (username) => {
rl.question('Enter new BeEF password: ', (password) => {
rl.close();
resolve({ username, password });
});
});
});
}
// Function to start BeEF
exports.startBeEF = function() {
return new Promise((resolve, reject) => {
// Check Ruby version before starting BeEF
exec('ruby -v', (error, stdout, stderr) => {
if (error) {
return reject(`Error checking Ruby version: ${error.message}`);
}
const rubyVersionMatch = stdout.match(/ruby (\d+\.\d+\.\d+)/);
const currentRubyVersion = rubyVersionMatch ? parseFloat(rubyVersionMatch[1]) : null;
// If Ruby version is less than 3.0, install/update RVM and Ruby
if (currentRubyVersion && currentRubyVersion < 3.0) {
console.log(`Current Ruby version is ${currentRubyVersion}. Upgrading to Ruby 3.1.0...`);
// Install RVM
exec('curl -sSL https://get.rvm.io | bash', { shell: '/bin/bash' }, (error) => {
if (error) {
return reject(`Error installing RVM: ${error.message}`);
}
// Load RVM and install Ruby 3.1.0
exec('source ~/.rvm/scripts/rvm && rvm install 3.1.0', { shell: '/bin/bash' }, (error) => {
if (error) {
return reject(`Error installing Ruby 3.1.0: ${error.message}`);
}
// Ruby 3.1.0 installed, now start BeEF
runBeEF();
});
});
} else {
// Ruby version is good, start BeEF
runBeEF();
}
});
// Helper function to start BeEF
function runBeEF() {
console.log('Starting BeEF...');
exec(`cd ${BEEF_DIR} && ./beef`, { shell: '/bin/bash' }, (error, stdout, stderr) => {
if (error) {
if (stderr.includes("Could not find") && stderr.includes("in any of the sources")) {
console.log("BeEF needs requirements that aren't installed. Installing...");
// Run bundle install to install missing gems
exec(`cd ${BEEF_DIR} && ./beef`, { shell: shell }, (error, stdout, stderr) => {
if (error) {
return reject(`Error running bundle install: ${error.message}`);
}
// Attempt to run BeEF again
console.log('Retrying to start BeEF...');
exec(`cd ${BEEF_DIR} && ./beef`, { shell: '/bin/bash' }, (error, stdout, stderr) => {
handleBeEFOutput(error, stdout, stderr);
});
});
} else {
handleBeEFOutput(error, stdout, stderr);
}
} else {
console.log('BeEF started successfully. You can access it at http://localhost:3000');
resolve();
}
});
}
// Helper function to handle BeEF output
function handleBeEFOutput(error, stdout, stderr) {
// Log standard output and standard error for debugging
console.log('STDOUT:', stdout);
console.log('STDERR:', stderr);
if (stderr.includes("Warning: System language") || stderr.includes("ERROR: Default username and password in use!")) {
if (stderr.includes("ERROR: Default username and password in use!")) {
console.log('BeEF needs a different username and password. Updating config.yaml...');
promptForCredentials().then(({ username, password }) => {
updateCredentials(username, password);
console.log('Credentials updated. Starting BeEF again...');
exec(`cd ${BEEF_DIR} && ./beef`, { shell: '/bin/bash' }, (error) => {
if (error) {
return reject(`Error starting BeEF with new credentials: ${error.message}`);
}
console.log('BeEF started successfully. You can access it at http://localhost:3000');
resolve();
});
});
} else {
console.log("Warning: System language $LANG '' does not appear to be UTF-8 compatible.");
resolve(); // Resolve without restarting BeEF if it's just a warning
}
} else {
return reject(`Error starting BeEF: ${error.message}`);
}
}
});
};
// Function to interact with BeEF API
exports.interactWithBeEF = async function(endpoint) {
try {
const response = await axios.get(`http://localhost:${BEEF_PORT}/${endpoint}`);
console.log('Response from BeEF:', response.data);
} catch (error) {
console.error('Error interacting with BeEF:', error.message);
}
};
// Function to print a message
exports.printMsg = function() {
console.log("This is a message from the BeEN package.");
};
// Main function to install and start BeEF (optional)
async function main() {
try {
await exports.installBeEF();
await exports.startBeEF();
console.log('BeEF is running. You can interact with it now.');
// Example interaction with BeEF (replace with actual endpoint if necessary)
await exports.interactWithBeEF('api/your-endpoint'); // Replace with valid endpoint
} catch (error) {
console.error(error);
}
}
// Uncomment the line below to run the main function when executing the script directly
// main();