337 lines
9.8 KiB
JavaScript
337 lines
9.8 KiB
JavaScript
/**
|
|
* PSFree Remote Logger
|
|
*
|
|
* Remote logging system for PSFree that sends logs to a local server
|
|
* to monitor exploit progress in real-time.
|
|
*
|
|
* TODO: Add automatic reconnect feature if the connection is lost
|
|
*/
|
|
|
|
// Logger configuration
|
|
const RemoteLogger = {
|
|
// Server configuration
|
|
config: {
|
|
// Logging server URL (replace with your computer's IP)
|
|
serverUrl: 'http://192.168.1.100:3000',
|
|
// Whether logging is enabled
|
|
enabled: true,
|
|
// Whether to also print logs to the local console
|
|
localConsole: true,
|
|
// Minimum log level to be sent (0=DEBUG, 1=INFO, 2=WARN, 3=ERROR)
|
|
minLevel: 0,
|
|
// Unique ID for this logging session
|
|
sessionId: generateSessionId(),
|
|
// Device information
|
|
deviceInfo: {
|
|
userAgent: navigator.userAgent,
|
|
firmware: detectFirmware(),
|
|
timestamp: new Date().toISOString()
|
|
},
|
|
// Buffer to store logs if connection is lost
|
|
logBuffer: [],
|
|
// Maximum buffer size
|
|
maxBufferSize: 100,
|
|
// Connection status
|
|
connected: false
|
|
},
|
|
|
|
// Log levels
|
|
LEVEL: {
|
|
DEBUG: 0,
|
|
INFO: 1,
|
|
WARN: 2,
|
|
ERROR: 3
|
|
},
|
|
|
|
// Initialize the logger
|
|
init: function(customConfig = {}) {
|
|
// Merge default config with custom config
|
|
this.config = { ...this.config, ...customConfig };
|
|
|
|
// Try to auto-detect server IP if not configured
|
|
if (this.config.serverUrl === 'http://192.168.1.100:3000') {
|
|
this.autoDetectServerIp();
|
|
}
|
|
|
|
// Send session info to the server
|
|
this.sendSessionInfo();
|
|
|
|
// Override the original console.log function
|
|
this.overrideConsoleLog();
|
|
|
|
// Initialization log
|
|
this.info('Remote Logger initialized', {
|
|
config: {
|
|
serverUrl: this.config.serverUrl,
|
|
sessionId: this.config.sessionId,
|
|
deviceInfo: this.config.deviceInfo
|
|
}
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
// Try to auto-detect server IP
|
|
autoDetectServerIp: function() {
|
|
// List of commonly used IPs in local networks
|
|
const commonIps = [
|
|
'http://192.168.1.100:3000',
|
|
'http://192.168.1.101:3000',
|
|
'http://192.168.1.102:3000',
|
|
'http://192.168.1.103:3000',
|
|
'http://192.168.1.104:3000',
|
|
'http://192.168.1.105:3000',
|
|
'http://192.168.0.100:3000',
|
|
'http://192.168.0.101:3000',
|
|
'http://192.168.0.102:3000',
|
|
'http://192.168.0.103:3000',
|
|
'http://192.168.0.104:3000',
|
|
'http://192.168.0.105:3000',
|
|
'http://10.0.0.100:3000',
|
|
'http://10.0.0.101:3000',
|
|
'http://10.0.0.102:3000'
|
|
];
|
|
|
|
// Try pinging each IP to find an active server
|
|
for (const ip of commonIps) {
|
|
fetch(`${ip}/ping`, {
|
|
method: 'GET',
|
|
mode: 'no-cors',
|
|
cache: 'no-cache',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
timeout: 500
|
|
})
|
|
.then(() => {
|
|
// If successful, use this IP
|
|
this.config.serverUrl = ip;
|
|
this.info(`Server found at ${ip}`);
|
|
})
|
|
.catch(() => {
|
|
// If failed, try the next IP
|
|
});
|
|
}
|
|
},
|
|
|
|
// Send session info to the server
|
|
sendSessionInfo: function() {
|
|
if (!this.config.enabled) return;
|
|
|
|
// Create URL with query parameters to avoid CORS issues with body
|
|
const sessionData = {
|
|
sessionId: this.config.sessionId,
|
|
deviceInfo: JSON.stringify(this.config.deviceInfo),
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Create query string from data
|
|
const queryString = Object.keys(sessionData)
|
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(sessionData[key])}`)
|
|
.join('&');
|
|
|
|
// Send request using GET method and query parameters
|
|
fetch(`${this.config.serverUrl}/session?${queryString}`, {
|
|
method: 'GET',
|
|
mode: 'no-cors',
|
|
cache: 'no-cache'
|
|
})
|
|
.then(() => {
|
|
this.config.connected = true;
|
|
|
|
// Success log
|
|
if (this.config.localConsole) {
|
|
console.log(`Connected to logging server at ${this.config.serverUrl}`);
|
|
console.log(`Session ID: ${this.config.sessionId}`);
|
|
}
|
|
|
|
// Send logs stored in buffer
|
|
this.flushBuffer();
|
|
})
|
|
.catch(error => {
|
|
this.config.connected = false;
|
|
if (this.config.localConsole) {
|
|
console.error('Failed to connect to logging server:', error);
|
|
}
|
|
});
|
|
},
|
|
|
|
// Override the original console.log functions
|
|
overrideConsoleLog: function() {
|
|
const originalLog = console.log;
|
|
const originalWarn = console.warn;
|
|
const originalError = console.error;
|
|
const self = this;
|
|
|
|
console.log = function(...args) {
|
|
if (self.config.localConsole) {
|
|
originalLog.apply(console, args);
|
|
}
|
|
|
|
self.debug(args.map(arg => {
|
|
if (typeof arg === 'object') {
|
|
return JSON.stringify(arg);
|
|
}
|
|
return arg;
|
|
}).join(' '));
|
|
};
|
|
|
|
console.warn = function(...args) {
|
|
if (self.config.localConsole) {
|
|
originalWarn.apply(console, args);
|
|
}
|
|
|
|
self.warn(args.map(arg => {
|
|
if (typeof arg === 'object') {
|
|
return JSON.stringify(arg);
|
|
}
|
|
return arg;
|
|
}).join(' '));
|
|
};
|
|
|
|
console.error = function(...args) {
|
|
if (self.config.localConsole) {
|
|
originalError.apply(console, args);
|
|
}
|
|
|
|
self.error(args.map(arg => {
|
|
if (typeof arg === 'object') {
|
|
return JSON.stringify(arg);
|
|
}
|
|
return arg;
|
|
}).join(' '));
|
|
};
|
|
},
|
|
|
|
// Send log to server
|
|
sendLog: function(level, message, data = {}) {
|
|
if (!this.config.enabled || level < this.config.minLevel) return;
|
|
|
|
const logEntry = {
|
|
sessionId: this.config.sessionId,
|
|
timestamp: new Date().toISOString(),
|
|
level: level,
|
|
levelName: Object.keys(this.LEVEL).find(key => this.LEVEL[key] === level),
|
|
message: message,
|
|
data: JSON.stringify(data)
|
|
};
|
|
|
|
// If not connected, save to buffer
|
|
if (!this.config.connected) {
|
|
this.bufferLog(logEntry);
|
|
return;
|
|
}
|
|
|
|
// Create query string from log data
|
|
const queryString = Object.keys(logEntry)
|
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(logEntry[key])}`)
|
|
.join('&');
|
|
|
|
// Send log to server using GET method
|
|
fetch(`${this.config.serverUrl}/log?${queryString}`, {
|
|
method: 'GET',
|
|
mode: 'no-cors',
|
|
cache: 'no-cache'
|
|
})
|
|
.catch(error => {
|
|
this.config.connected = false;
|
|
this.bufferLog(logEntry);
|
|
if (this.config.localConsole) {
|
|
console.error('Failed to send log to server:', error);
|
|
}
|
|
});
|
|
},
|
|
|
|
// Save log in buffer if connection is lost
|
|
bufferLog: function(logEntry) {
|
|
this.config.logBuffer.push(logEntry);
|
|
|
|
// If buffer is too large, remove oldest logs
|
|
if (this.config.logBuffer.length > this.config.maxBufferSize) {
|
|
this.config.logBuffer.shift();
|
|
}
|
|
},
|
|
|
|
// Send all buffered logs
|
|
flushBuffer: function() {
|
|
if (!this.config.connected || this.config.logBuffer.length === 0) return;
|
|
|
|
for (const log of this.config.logBuffer) {
|
|
this.sendLog(log.level, log.message, log.data ? JSON.parse(log.data) : {});
|
|
}
|
|
|
|
this.config.logBuffer = [];
|
|
},
|
|
|
|
// Logging functions
|
|
debug: function(message, data = {}) {
|
|
this.sendLog(this.LEVEL.DEBUG, message, data);
|
|
},
|
|
|
|
info: function(message, data = {}) {
|
|
this.sendLog(this.LEVEL.INFO, message, data);
|
|
},
|
|
|
|
warn: function(message, data = {}) {
|
|
this.sendLog(this.LEVEL.WARN, message, data);
|
|
},
|
|
|
|
error: function(message, data = {}) {
|
|
this.sendLog(this.LEVEL.ERROR, message, data);
|
|
},
|
|
|
|
// Log exploit stage
|
|
logStage: function(stage, percent, details = {}) {
|
|
this.info(`STAGE: ${stage}`, {
|
|
stage: stage,
|
|
percent: percent,
|
|
details: details
|
|
});
|
|
|
|
// Dispatch event for UI
|
|
document.dispatchEvent(new CustomEvent('exploitProgress', {
|
|
detail: {
|
|
stage: stage,
|
|
percent: percent
|
|
}
|
|
}));
|
|
}
|
|
};
|
|
|
|
// Function to generate unique session ID
|
|
function generateSessionId() {
|
|
return 'xxxx-xxxx-xxxx-xxxx'.replace(/[x]/g, () => {
|
|
const r = Math.random() * 16 | 0;
|
|
return r.toString(16);
|
|
});
|
|
}
|
|
|
|
// Function to detect firmware
|
|
function detectFirmware() {
|
|
const userAgent = navigator.userAgent;
|
|
let firmware = null;
|
|
|
|
// Detect PS4 firmware
|
|
const ps4Match = userAgent.match(/PlayStation 4\/([0-9.]+)/);
|
|
if (ps4Match && ps4Match[1]) {
|
|
firmware = {
|
|
console: 'PS4',
|
|
version: ps4Match[1]
|
|
};
|
|
}
|
|
|
|
// Detect PS5 firmware
|
|
const ps5Match = userAgent.match(/PlayStation 5\/([0-9.]+)/);
|
|
if (ps5Match && ps5Match[1]) {
|
|
firmware = {
|
|
console: 'PS5',
|
|
version: ps5Match[1]
|
|
};
|
|
}
|
|
|
|
return firmware;
|
|
}
|
|
|
|
// Export RemoteLogger to window
|
|
window.RemoteLogger = RemoteLogger;
|