Files
PSFree/js/remote-logger.js
T
2025-05-19 07:33:31 -06:00

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;