Advertisement
Guest User

Untitled

a guest
Sep 14th, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.62 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. # fortilogin.py
  4. # Copyright (C) 2015 Stephane Lepin
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License along
  17. # with this program. If not, see <https://www.gnu.org/licenses/>
  18.  
  19. import sys
  20. import http.client
  21. import urllib.request, urllib.error, urllib.parse
  22. import ssl
  23. import re
  24. from urllib.parse import urlencode
  25. from urllib.parse import urlparse
  26. from getpass import getpass
  27.  
  28. # Show usage info and exit if not arguments are given
  29. if len(sys.argv) < 2:
  30. print(("Usage : " + __file__+ " username [password]"))
  31. exit()
  32.  
  33. username = sys.argv[1]
  34.  
  35. # Get the password from the arguments if specified, prompt for it otherwise
  36. if len(sys.argv) >= 3:
  37. password = sys.argv[2]
  38. else:
  39. password = getpass('Password for ' + username + ' :')
  40.  
  41. # The script will try to match testRegex against the data returned by testHost
  42. testHost = "ipv4.icanhazip.com"
  43. testRegex = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\n" # ICHI has a line return after the IP address
  44.  
  45. # Initial request to know if I'm behind a Fortinet captive portal
  46. # I'm using httplib to detect and avoid the automatic redirection performed by urllib
  47. conn = http.client.HTTPConnection(testHost)
  48. conn.request('GET', '/')
  49. rep = conn.getresponse()
  50.  
  51. # The captive portal responds with HTTP rep code 303
  52. if rep.status == 303:
  53. # So I can extract the magic token embedded in the value of the Location header.
  54. # This value is something like this : http://10.151.0.1:1000/fgtauth?0004610d63757532
  55. locationUrl = rep.getheader('Location')
  56. portalUrl = urlparse(locationUrl)
  57. magic = portalUrl.query
  58.  
  59. postUrl = portalUrl.scheme + "://" + portalUrl.netloc + "/"
  60.  
  61. ssl_ctx = ssl.create_default_context()
  62. ssl_ctx.check_hostname = False
  63. ssl_ctx.verify_mode = ssl.CERT_NONE
  64.  
  65. print("Not authenticated !")
  66. print(("Redirected to " + locationUrl))
  67. print("------")
  68. print(("Captive portal url : " + postUrl))
  69. print(("Magic token : " + magic))
  70. print("------")
  71.  
  72. print(("Authenticating as " + username))
  73.  
  74. # Step 1 - call the full URL returned by the captive portal
  75. rep = urllib.request.urlopen(locationUrl, context=ssl_ctx)
  76. print(("Step 1 : " + str(rep.getcode())))
  77.  
  78. # Step 2 - send a POST request to the "Yes, I agree" form
  79. rep = urllib.request.urlopen(postUrl, urlencode({'4Tredir': 'http://' + testHost, 'magic': magic, 'answer': 1}), context=ssl_ctx)
  80. print(("Step 2 : " + str(rep.getcode())))
  81.  
  82. # Step 3 - send a POST request with your credentials to the Authentication form
  83. rep = urllib.request.urlopen(postUrl, urlencode({'4Tredir': 'http://' + testHost, 'magic': magic, 'username': username, 'password': password}), context=ssl_ctx)
  84. print(("Step 3 : " + str(rep.getcode())))
  85.  
  86. testResponse = rep.read()
  87. rep = urllib.request.urlopen('http://' + testHost)
  88. testResponse = rep.read()
  89.  
  90. if re.compile(testRegex).match(testResponse) != None:
  91. print("Authenticated !")
  92. else:
  93. print(testResponse)
  94. print("Seems like something went wrong. Here's what I received :\n")
  95. print(testResponse)
  96. else:
  97. print("Already authenticated")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement