m34.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/env python3
  2. import subprocess
  3. import re
  4. import lxml
  5. from lxml import html
  6. import urllib
  7. import urllib.request
  8. import urllib3
  9. import base64
  10. class Foo:
  11. def __init__(self):
  12. self.headers = {}
  13. self.headers['User-Agent'] = 'Mozilla/5.0'
  14. self.pool = urllib3.PoolManager()
  15. self.cookies = {}
  16. def perform_xhr_post(self, url, extra_headers=[], fields={}):
  17. pool = self.pool
  18. headers = self.headers.copy()
  19. headers['X-Requested-With'] = 'XMLHttpRequest'
  20. for (k,v) in extra_headers:
  21. headers[k] = v
  22. xs = list(self.cookies.items())
  23. headers['Cookie'] = "; ".join(["%s=%s" % (k,v) \
  24. for (k,v) in xs \
  25. if k != 'PHPSESSID'])
  26. print("request POST %s" % url)
  27. print("request headers: %s" % headers)
  28. print("request fields: %s" % fields)
  29. f = pool.request_encode_body(method='POST',
  30. url=url,
  31. fields=fields,
  32. encode_multipart=False,
  33. headers=headers,
  34. redirect=False)
  35. return self.postprocess(f)
  36. # called by perform_get and perform_xhr_post after executing the request
  37. # f = the request object
  38. def postprocess(self, f):
  39. print("response headers: %s" % f.getheaders())
  40. if f.get_redirect_location():
  41. print("redirect: %s" % f.get_redirect_location())
  42. for cookie1 in f.getheaders().get_all('Set-Cookie'):
  43. cookies1 = re.findall('([^= ]*)=([^; ]*); ', cookie1)
  44. for (k,v) in cookies1:
  45. # what's the exact syntax? we don't really care. just remove the accidentally captured strings
  46. if not (re.match('[Mm]ax-[Aa]ge', k) or re.match('path', k)):
  47. if self.cookies.get(k):
  48. print("replacing cookie %s with %s" % (k, v) )
  49. else:
  50. print("setting cookie %s to %s" % (k, v) )
  51. if 'himalaya-site-ident' == k:
  52. print("himalaya-site-ident: ",base64.b64decode(v.replace('%3D', '=')))
  53. self.cookies[k] = v
  54. print(f.data)
  55. print()
  56. return f
  57. def perform_get(self, url, redirect=False):
  58. pool = self.pool
  59. headers = self.headers.copy()
  60. headers['Cookie'] = "; ".join(["%s=%s" % (k,v) for (k,v) in self.cookies.items()])
  61. print("request GET %s" % url)
  62. print("request headers: %s" % headers)
  63. f = pool.request(method='GET', url=url, headers=headers, redirect=redirect)
  64. return self.postprocess(f)
  65. print("let's go")
  66. foo = Foo()
  67. dummy='http://detectportal.firefox.com/success.txt'
  68. f1 = foo.perform_get(dummy)
  69. url = f1.get_redirect_location()
  70. f2 = foo.perform_get(url)
  71. url = f2.get_redirect_location()
  72. f2 = foo.perform_get(url)
  73. f2_headers = {k.lower(): v for k, v in f2.getheaders().items()}
  74. url = f2_headers.get('location')
  75. f3 = foo.perform_get(url)
  76. tokenstring = re.findall(b'"token":"([^"]+)"', f3.data)[0]
  77. scenestring = re.findall(b'"id":"([^"]+)"', f3.data)[0]
  78. sceneurl = b"https://accor.conn4.com/scenes/%s/" % scenestring
  79. # WTF, shouldn't urllib3 be using "bytes" everywhere????
  80. url = sceneurl.decode()
  81. f4aa = foo.perform_get(url)
  82. headers4 = {}
  83. # headers['Referer'] = 'https://accor.conn4.com/'
  84. headers4['Referer'] = sceneurl.decode()
  85. headers4['Cookie'] = "; ".join(["%s=%s" % (k,v) for (k,v) in foo.cookies.items()])
  86. headers4['X-Requested-With'] = 'XMLHttpRequest'
  87. headers4['Origin'] = 'https://accor.conn4.com'
  88. # if we made a mistake before arriving here, the server uses this value for Allow-Origin instead:
  89. # headers4['Origin'] = 'https://portal-eu-ffm01.conn4.com'
  90. headers4['Accept'] = '*/*'
  91. # unnecessary:
  92. # headers4['Cache-Control'] = 'no-cache'
  93. # headers4['Accept-Language'] = 'en-US,en;q=0.5'
  94. # headers4['Connection'] = 'keep-alive'
  95. headers4['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
  96. headers4['Host'] = 'accor.conn4.com'
  97. url = 'https://accor.conn4.com/wbs/api/v1/create-session/'
  98. form = {}
  99. form['session_id'] = ''
  100. form['with-tariffs'] = '1'
  101. form['locale'] = 'en_US'
  102. form['authorization'] = "token=%s" % tokenstring.decode()
  103. f4a = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)
  104. sessions = re.findall(b'"session":"([^"]+)"', f4a.data)[0].decode()
  105. print(sessions)
  106. # oh, it's the same as the PHPSESSIONID. go figure
  107. url = 'https://accor.conn4.com/_time?t=1577515801949'
  108. foo.perform_xhr_post(url)
  109. # "get" in original trace, but "post" works fine
  110. # firefox did this, but it's unnecessary (maybe this is the case where mac address hasn't changed)
  111. # url = 'https://accor.conn4.com/wbs/api/v1/login/free/'
  112. # form = {}
  113. # form['authorization'] = 'session=%s' % sessions
  114. # f4 = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)
  115. url = 'https://accor.conn4.com/wbs/api/v1/register/free/'
  116. form = {}
  117. form['authorization'] = 'session=%s' % sessions
  118. form['registration_type'] = 'terms-only'
  119. form['registration[terms]'] = '1'
  120. f5 = foo.perform_xhr_post(url, extra_headers=list(headers4.items()), fields=form)