UNPKG

akamai-v3-sensor-data-helper

Version:

A Node.js module for decrypting Akamai v3 sensor data. Check out our web app at https://akamai-v3-tools.vercel.app and read the detailed guide at https://medium.com/@glizzykingdreko/akamai-v3-sensor-data-deep-dive-into-encryption-decryption-and-bypass-too

296 lines (254 loc) 11.3 kB
const parser = require('@babel/parser'); const traverse = require('@babel/traverse').default; const t = require('@babel/types'); const generate = require('@babel/generator').default; function identifyIndex(ast) { // Array to store the found patterns const foundPatterns = []; var result = {}; // Store the function name we need to find let targetFunctionName = null; // Store the important value name we need to find its declaration let importantValueName = null; // First pass: Find the variable declaration pattern traverse(ast, { VariableDeclarator(path) { const node = path.node; // Check if the initialization is a logical OR expression if (t.isLogicalExpression(node.init) && node.init.operator === '||') { const left = node.init.left; const right = node.init.right; // Check if the right side is a call expression if (t.isCallExpression(right)) { // Check if the left side is a simple identifier (not a complex expression) if (t.isIdentifier(left)) { // This matches our exact pattern: var variableName = anotherVariable || functionCall() foundPatterns.push({ variableName: node.id.name, leftOperand: generate(left).code, rightOperand: generate(right).code, location: { start: node.loc ? node.loc.start : 'unknown', end: node.loc ? node.loc.end : 'unknown' } }); // Store the function name we need to find if (t.isIdentifier(right.callee)) { targetFunctionName = right.callee.name; } } } } } }); if (!targetFunctionName) { return null; } let functionDeclaration = null; // Second pass: Find the function declaration traverse(ast, { FunctionDeclaration(path) { const node = path.node; if (node.id && node.id.name === targetFunctionName) { functionDeclaration = node; path.stop(); // Stop traversing once we find the function } }, VariableDeclarator(path) { const node = path.node; if (t.isIdentifier(node.id) && node.id.name === targetFunctionName && t.isFunctionExpression(node.init)) { functionDeclaration = node; path.stop(); // Stop traversing once we find the function } } }); if (!functionDeclaration) { return null; } // Generate the code for the function const functionCode = generate(functionDeclaration).code; // Now parse the function.js file to find the array declaration const functionAst = parser.parse(functionCode, { sourceType: 'module', plugins: ['jsx'] }); let importantValue = null; // Find the array declaration within the function traverse(functionAst, { VariableDeclarator(nodePath) { const node = nodePath.node; // Check if the initialization is an array expression with at least 2 elements if (t.isArrayExpression(node.init) && node.init.elements.length >= 2) { // Get the second element of the array const secondElement = node.init.elements[1]; if (t.isIdentifier(secondElement)) { importantValue = secondElement.name; importantValueName = secondElement.name; // Store for later use } } } }); if (!importantValue) { return null; } // Third pass: Find the declaration of the important value traverse(ast, { VariableDeclarator(nodePath) { const node = nodePath.node; // Check if this is the declaration we're looking for if (t.isIdentifier(node.id) && node.id.name === importantValueName) { console.log(`Found declaration of ${importantValueName}`); // Function to recursively find the last member expression in the arguments function findLastMemberExpression(node) { if (!node) return null; // If this is a call expression, check its arguments if (t.isCallExpression(node)) { const args = node.arguments; if (args.length > 0) { // Check the last argument const lastArg = args[args.length - 1]; if (t.isMemberExpression(lastArg)) { return lastArg; } // Recursively check the last argument return findLastMemberExpression(lastArg); } } // If this is a member expression, check its object and property if (t.isMemberExpression(node)) { return node; } // For other types of nodes, check their properties for (const key of Object.keys(node)) { if (node[key] && typeof node[key] === 'object') { const result = findLastMemberExpression(node[key]); if (result) return result; } } return null; } // Find the last member expression in the initialization const lastMemberExpr = findLastMemberExpression(node.init); if (lastMemberExpr) { let element = node.init.arguments[0].arguments[0]; result = { list: element.object.name, index: element.property.name } } } } }); return result.index; } function findObjectsWithHexKeys(ast) { let result = null; traverse(ast, { VariableDeclarator(path) { try { if (path.node.init && path.node.init.type === 'ObjectExpression') { const obj = path.node.init; let hexKeys = 0; let functionCalls = 0; obj.properties.forEach(prop => { try { if (prop.key && prop.key.type === 'StringLiteral') { const key = prop.key.value; if (key && key.length === 1 && /[\x20-\x7F]/.test(key)) { hexKeys++; } } if (prop.value) { const value = prop.value; if (value.type === 'CallExpression' || (value.type === 'ConditionalExpression' && (value.consequent && value.consequent.type === 'CallExpression' || value.alternate && value.alternate.type === 'CallExpression')) || (value.type === 'LogicalExpression' && (value.left && value.left.type === 'CallExpression' || value.right && value.right.type === 'CallExpression'))) { functionCalls++; } } } catch (error) { console.error('Error processing property:', error); } }); if (hexKeys === 11 && functionCalls >= 11) { const objectJson = {}; obj.properties.forEach(prop => { try { const key = prop.key && prop.key.type === 'StringLiteral' ? prop.key.value : prop.key && prop.key.type === 'Identifier' ? prop.key.name : 'unknown'; const hexKey = key.length === 1 ? `\\x${key.charCodeAt(0).toString(16).padStart(2, '0')}` : key; objectJson[hexKey] = prop.value ? generate(prop.value).code : 'unknown'; } catch (error) { console.error('Error processing property for JSON:', error); } }); result = { node: path.node, legenda: { name: path.node.id.name, code: generate(path.node).code } }; path.stop(); } } } catch (error) { console.error('Error processing variable declarator:', error); } } }); return result; } function findListArray(ast) { let result = null; traverse(ast, { AssignmentExpression(path) { const node = path.node; if (node.right && node.right.type === 'CallExpression' && node.right.arguments && node.right.arguments[1] && node.right.arguments[1].type === 'ArrayExpression') { const arrayArg = node.right.arguments[1]; if (arrayArg.elements && arrayArg.elements.length > 0 && arrayArg.elements[0].type === 'ArrayExpression') { const innerArray = arrayArg.elements[0]; if ( innerArray.elements && innerArray.elements.every(el => el.type === 'StringLiteral') && innerArray.elements.length >= 10 ) { result = { index: node.left.name, list: innerArray.elements.map(el => el.value) }; path.stop(); } } } } }); return result; } function main(code) { try { const ast = typeof code === 'string' ? parser.parse(code) : code; const hexObject = findObjectsWithHexKeys(ast); const listData = findListArray(ast); if (!hexObject || !listData) { throw new Error('Could not find all required elements'); } return { index: identifyIndex(ast), list: listData.list, legenda: hexObject.legenda }; } catch (error) { throw error; } } module.exports = main;