From ff06c914fc2ddcab78efe36517966a348d288e4c Mon Sep 17 00:00:00 2001 From: carlospolop Date: Thu, 23 Oct 2025 12:21:23 +0200 Subject: [PATCH] f --- .github/workflows/build_master.yml | 27 +++++++++++++++++++++++-- .github/workflows/translate_all.yml | 31 +++++++++++++++++++++++++---- theme/ht_searcher.js | 24 +++++++++++++++++----- 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build_master.yml b/.github/workflows/build_master.yml index a8e3cfb84..0dc3f3650 100644 --- a/.github/workflows/build_master.yml +++ b/.github/workflows/build_master.yml @@ -88,9 +88,32 @@ jobs: RATIO=$(awk "BEGIN {printf \"%.1f\", ($COMPRESSED_SIZE / $ORIGINAL_SIZE) * 100}") echo "Compression: ${ORIGINAL_SIZE} bytes -> ${COMPRESSED_SIZE} bytes (${RATIO}%)" - # Copy ONLY the .gz version to the searchindex repo (no uncompressed .js) + # XOR encrypt the compressed file + KEY='Prevent_Online_AVs_From_Flagging_HackTricks_Search_Gzip_As_Malicious_394h7gt8rf9u3rf9g' + python3 - << 'PYTHON_SCRIPT' +import sys +key = sys.argv[1] +input_file = sys.argv[2] +output_file = sys.argv[3] + +with open(input_file, 'rb') as f: + data = f.read() + +key_bytes = key.encode('utf-8') +encrypted = bytearray(len(data)) +for i in range(len(data)): + encrypted[i] = data[i] ^ key_bytes[i % len(key_bytes)] + +with open(output_file, 'wb') as f: + f.write(encrypted) + +print(f"Encrypted: {len(data)} bytes") +PYTHON_SCRIPT + python3 - "$KEY" "${ASSET}.gz" "${ASSET}.gz.enc" + + # Copy ONLY the encrypted .gz version to the searchindex repo (no uncompressed .js) cd /tmp/searchindex-repo - cp "${GITHUB_WORKSPACE}/${ASSET}.gz" "${FILENAME}.gz" + cp "${GITHUB_WORKSPACE}/${ASSET}.gz.enc" "${FILENAME}.gz" # Stage all files git add -A diff --git a/.github/workflows/translate_all.yml b/.github/workflows/translate_all.yml index 4239e8708..3914d3499 100644 --- a/.github/workflows/translate_all.yml +++ b/.github/workflows/translate_all.yml @@ -184,8 +184,31 @@ jobs: RATIO=$(awk "BEGIN {printf \"%.1f\", ($COMPRESSED_SIZE / $ORIGINAL_SIZE) * 100}") echo "Compression: ${ORIGINAL_SIZE} bytes -> ${COMPRESSED_SIZE} bytes (${RATIO}%)" - # Copy ONLY the .gz version to the searchindex repo (no uncompressed .js) - cp "${ASSET}.gz" "/tmp/searchindex-repo/${FILENAME}.gz" + # XOR encrypt the compressed file + KEY="Prevent_Online_AVs_From_Flagging_HackTricks_Search_Gzip_As_Malicious_394h7gt8rf9u3rf9g" + python3 - << 'PYTHON_SCRIPT' +import sys +key = sys.argv[1] +input_file = sys.argv[2] +output_file = sys.argv[3] + +with open(input_file, 'rb') as f: + data = f.read() + +key_bytes = key.encode('utf-8') +encrypted = bytearray(len(data)) +for i in range(len(data)): + encrypted[i] = data[i] ^ key_bytes[i % len(key_bytes)] + +with open(output_file, 'wb') as f: + f.write(encrypted) + +print(f"Encrypted: {len(data)} bytes") +PYTHON_SCRIPT + python3 - "$KEY" "${ASSET}.gz" "${ASSET}.gz.enc" + + # Copy ONLY the encrypted .gz version to the searchindex repo (no uncompressed .js) + cp "${ASSET}.gz.enc" "/tmp/searchindex-repo/${FILENAME}.gz" # Commit and push with retry logic cd /tmp/searchindex-repo @@ -224,8 +247,8 @@ jobs: git config user.name "GitHub Actions" git config user.email "github-actions@github.com" - # Re-copy ONLY the .gz version (no uncompressed .js) - cp "${ASSET}.gz" "${FILENAME}.gz" + # Re-copy ONLY the encrypted .gz version (no uncompressed .js) + cp "${ASSET}.gz.enc" "${FILENAME}.gz" git add "${FILENAME}.gz" git commit -m "Update ${FILENAME}.gz from hacktricks-cloud build" diff --git a/theme/ht_searcher.js b/theme/ht_searcher.js index 9548e9173..77cfb87da 100644 --- a/theme/ht_searcher.js +++ b/theme/ht_searcher.js @@ -21,7 +21,17 @@ try { importScripts('https://cdn.jsdelivr.net/npm/elasticlunr@0.9.5/elasticlunr.min.js'); } catch { importScripts(abs('/elasticlunr.min.js')); } - /* 2 — decompress gzip data */ + /* 2 — XOR decryption function */ + function xorDecrypt(encryptedData, key){ + const keyBytes = new TextEncoder().encode(key); + const decrypted = new Uint8Array(encryptedData.length); + for(let i = 0; i < encryptedData.length; i++){ + decrypted[i] = encryptedData[i] ^ keyBytes[i % keyBytes.length]; + } + return decrypted.buffer; + } + + /* 3 — decompress gzip data */ async function decompressGzip(arrayBuffer){ if(typeof DecompressionStream !== 'undefined'){ /* Modern browsers: use native DecompressionStream */ @@ -40,21 +50,25 @@ } } - /* 3 — load a single index (remote → local) */ + /* 4 — load a single index (remote → local) */ async function loadIndex(remote, local, isCloud=false){ + const XOR_KEY = "Prevent_Online_AVs_From_Flagging_HackTricks_Search_Gzip_As_Malicious_394h7gt8rf9u3rf9g"; let rawLoaded = false; if(remote){ /* Try ONLY compressed version from GitHub (remote already includes .js.gz) */ try { const r = await fetch(remote,{mode:'cors'}); if (r.ok) { - const compressed = await r.arrayBuffer(); + const encryptedCompressed = await r.arrayBuffer(); + /* Decrypt first */ + const compressed = xorDecrypt(new Uint8Array(encryptedCompressed), XOR_KEY); + /* Then decompress */ const text = await decompressGzip(compressed); importScripts(URL.createObjectURL(new Blob([text],{type:'application/javascript'}))); rawLoaded = true; - console.log('Loaded compressed from GitHub:',remote); + console.log('Loaded encrypted+compressed from GitHub:',remote); } - } catch(e){ console.warn('compressed GitHub',remote,'failed →',e); } + } catch(e){ console.warn('encrypted+compressed GitHub',remote,'failed →',e); } } /* If remote (GitHub) failed, fall back to local uncompressed file */ if(!rawLoaded && local){