123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- #!/usr/bin/env python3
- import subprocess
- import re
- import lxml
- from lxml import html
- import urllib
- import urllib.request
- import urllib3
- import base64
- class Foo:
- def __init__(self):
- self.headers = {}
- self.headers['User-Agent'] = 'Mozilla/5.0'
- self.pool = urllib3.PoolManager()
- self.cookies = {}
- def perform_xhr_post(self, url, extra_headers=[], fields={}):
- pool = self.pool
- headers = self.headers.copy()
- headers['X-Requested-With'] = 'XMLHttpRequest'
- for (k,v) in extra_headers:
- headers[k] = v
- xs = list(self.cookies.items())
- headers['Cookie'] = "; ".join(["%s=%s" % (k,v) \
- for (k,v) in xs \
- if k != 'PHPSESSID'])
- print("request POST %s" % url)
- print("request headers: %s" % headers)
- print("request fields: %s" % fields)
- f = pool.request_encode_body(method='POST',
- url=url,
- fields=fields,
- encode_multipart=False,
- headers=headers,
- redirect=False)
- return self.postprocess(f)
- # called by perform_get and perform_xhr_post after executing the request
- # f = the request object
- def postprocess(self, f):
- print("response headers: %s" % f.headers)
- if f.get_redirect_location():
- print("redirect: %s" % f.get_redirect_location())
- for cookie1 in f.headers.get_all('Set-Cookie'):
- cookies1 = re.findall('([^= ]*)=([^; ]*); ', cookie1)
- for (k,v) in cookies1:
- # what's the exact syntax? we don't really care. just remove the accidentally captured strings
- if not (re.match('[Mm]ax-[Aa]ge', k) or re.match('path', k)):
- if self.cookies.get(k):
- print("replacing cookie %s with %s" % (k, v) )
- else:
- print("setting cookie %s to %s" % (k, v) )
- if 'himalaya-site-ident' == k:
- print("himalaya-site-ident: ",base64.b64decode(v.replace('%3D', '=')))
- self.cookies[k] = v
- print(f.data)
- print()
- return f
- def perform_get(self, url, redirect=False):
- pool = self.pool
- headers = self.headers.copy()
- headers['Cookie'] = "; ".join(["%s=%s" % (k,v) for (k,v) in self.cookies.items()])
- print("request GET %s" % url)
- print("request headers: %s" % headers)
- f = pool.request(method='GET', url=url, headers=headers, redirect=redirect)
- return self.postprocess(f)
- print("let's go")
- foo = Foo()
- dummy='http://detectportal.firefox.com/success.txt'
- f1 = foo.perform_get(dummy)
- print(f1)
- base = re.findall(b'https://.*\\.conn4\\.com', f1.data)[0]
- base_host = re.findall(b'(?<=https://).*\\.conn4\\.com', f1.data)[0]
- url = f1.get_redirect_location()
- f2 = foo.perform_get(url)
- url = f2.get_redirect_location()
- f2 = foo.perform_get(url)
- f2_headers = {k.lower(): v for k, v in f2.headers.items()}
- print(f2_headers)
- url3 = f2_headers.get('location')
- if url3 is None:
- f3 = foo.perform_get(url)
- f3data = f2.data
- else:
- f3data = f3.data
- url = url3
- tokenstring = re.findall(b'"token":"([^"]+)"', f3data)[0]
- scenestring = re.findall(b'"id":"([^"]+)"', f3data)[0]
- sceneurl = b"%s/scenes/%s/" % (base, scenestring)
- # WTF, shouldn't urllib3 be using "bytes" everywhere????
- url = sceneurl.decode()
- f4aa = foo.perform_get(url)
- headers4 = {}
- # headers['Referer'] = 'https://accor.conn4.com/'
- headers4['Referer'] = sceneurl.decode()
- headers4['Cookie'] = "; ".join(["%s=%s" % (k,v) for (k,v) in foo.cookies.items()])
- headers4['X-Requested-With'] = 'XMLHttpRequest'
- headers4['Origin'] = base.decode()
- # if we made a mistake before arriving here, the server uses this value for Allow-Origin instead:
- # headers4['Origin'] = 'https://portal-eu-ffm01.conn4.com'
- headers4['Accept'] = '*/*'
- # unnecessary:
- # headers4['Cache-Control'] = 'no-cache'
- # headers4['Accept-Language'] = 'en-US,en;q=0.5'
- # headers4['Connection'] = 'keep-alive'
- headers4['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
- headers4['Host'] = base_host.decode()
- # 'accor.conn4.com'
- url = '%s/wbs/api/v1/create-session/' % base.decode()
- form = {}
- form['session_id'] = ''
- form['with-tariffs'] = '1'
- form['locale'] = 'en_US'
- form['authorization'] = "token=%s" % tokenstring.decode()
- f4a = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)
- sessions = re.findall(b'"session":"([^"]+)"', f4a.data)[0].decode()
- print(sessions)
- # oh, it's the same as the PHPSESSIONID.
- print(f4a.data)
- # wbsTokenstring = re.findall(b'wbsToken.*"token":"([^"]+)"', f4a.data)[0]
- print("-----------")
- url = '%s/_time?t=1577515801949' % base.decode()
- foo.perform_xhr_post(url)
- # "get" in original trace, but "post" works fine
- # firefox did this, but it's unnecessary (maybe this is the case where mac address hasn't changed)
- # url = 'https://accor.conn4.com/wbs/api/v1/login/free/'
- # form = {}
- # form['authorization'] = 'session=%s' % sessions
- # f4 = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)
- url = '%s/wbs/api/v1/register/free/' % base.decode()
- form = {}
- form['authorization'] = 'session=%s' % sessions
- form['registration_type'] = 'terms-only'
- form['authorization'] = "token=%s" % tokenstring.decode()
- form['registration[terms]'] = '1'
- f5 = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)
- # b'{"error":{"message":"Internal system exception","code":652,"backend-code":"1613"},"
|