main.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-"
  3. """
  4. [pArAnoIA_Browser] by /psy (https://browser.03c8.net/)/ - 2020/2024
  5. You should have received a copy of the GNU General Public License along
  6. with pArAnoIA-Browser; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. import os, sys, re, random, socket, requests, time, urllib.parse, urllib.request, urllib.error
  10. try:
  11. import gi
  12. except:
  13. print("\nError importing: gi lib. \n\n To install it on Debian based systems:\n\n $ 'sudo apt-get install python3-gi' or 'pip3 install PyGObject'\n")
  14. sys.exit(2)
  15. try:
  16. import pygeoip
  17. except:
  18. print("\n[Error] [AI] Cannot import lib: pygeoip. \n\n To install it try:\n\n $ 'sudo apt-get install python3-geoip' or 'pip3 install pygeoip'\n")
  19. sys.exit(2)
  20. from uuid import getnode
  21. gi.require_version('Gtk', '3.0')
  22. gi.require_version('WebKit', '3.0')
  23. from gi.repository import Gtk, WebKit
  24. from gi.repository import Gdk
  25. Gdk.threads_init()
  26. class Browser(object):
  27. def __init__(self):
  28. self.check_ip_service1 = 'https://ip.42.pl/ra' # set external check ip service-backup 1 [OK! 23/06/2019]
  29. self.home_website = "https://check.torproject.org" # Home website
  30. self.https_strict = "ON" # HTTPS(strict)
  31. self.navigation_mode = "EXPLORER" # Navigation mode
  32. self.logs_mode = "OFF" # logging mode
  33. self.tor_mode = "OFF" # TOR mode
  34. self.dns_prefetching = "ON" # DNS Prefetching
  35. self.javascript = "ON" # Javascript(flag) = No-Javascript [*]
  36. self.java = "ON" # Java*
  37. self.flash = "ON" # Flash*
  38. self.webaudio = "ON" # WebAudio*
  39. self.webgl = "ON" # WebGL/WebVideo*
  40. self.xss = "ON" # XSS audit
  41. self.cache = "ON" # Cache*
  42. self.styles = "ON" # Styles/Fonts*
  43. self.logs = [] # logged urls
  44. self.logo = "core/images/paranoia.jpeg" # set source path for logo img
  45. self.agents_file = "core/user-agents.txt" # set source path to retrieve user-agents
  46. self.geodb = "core/geo/GeoLiteCity.dat" # set source for geoip-DB
  47. self.agents = [] # generating available user-agents
  48. f = open(self.agents_file)
  49. agents = f.readlines()
  50. f.close()
  51. for agent in agents:
  52. self.agents.append(agent)
  53. self.builder = Gtk.Builder()
  54. self.builder.add_from_file("core/browser.glade")
  55. self.builder.connect_signals(self)
  56. self.toolbar1 = self.builder.get_object("toolbar1")
  57. self.back = self.builder.get_object("back")
  58. self.forward = self.builder.get_object("forward")
  59. self.refresh = self.builder.get_object("refresh")
  60. self.stop = self.builder.get_object("stop")
  61. self.url = self.builder.get_object("url")
  62. self.spinner = self.builder.get_object("spinner")
  63. self.progressbar = self. builder.get_object("progressbar")
  64. self.scrolledwindow = self.builder.get_object("scrolledwindow")
  65. self.scrolledwindowinspector = self.builder.get_object("scrolledwindowinspector")
  66. self.scrolledwindowlogs = self.builder.get_object("scrolledwindowlogs")
  67. self.navigation_mode_img = self.builder.get_object("navigation_mode_img")
  68. self.navigation_mode_button = self.builder.get_object("navigation_mode_button")
  69. self.source_code_img = self.builder.get_object("source_code_img")
  70. self.source_code_button = self.builder.get_object("source_code_button")
  71. self.logs_img = self.builder.get_object("logs_img")
  72. self.logs_button = self.builder.get_object("logs_button")
  73. self.logs_view_buffer = self.builder.get_object("logs_view_buffer")
  74. self.top_panel = self.builder.get_object("top_panel")
  75. self.top_domain = self.builder.get_object("top_domain")
  76. self.hide_top_panel_img = self.builder.get_object("hide_top_panel_img")
  77. self.hide_top_panel_button = self.builder.get_object("hide_top_panel_button")
  78. self.toolbar = self.builder.get_object("toolbar")
  79. self.fullscreen_img = self.builder.get_object("fullscreen_img")
  80. self.fullscreen_button = self.builder.get_object("fullscreen_button")
  81. self.max_screen_img = self.builder.get_object("max_screen_img")
  82. self.max_screen_button = self.builder.get_object("max_screen_button")
  83. self.source_code_view_buffer = self.builder.get_object("source_code_view_buffer")
  84. self.source_code_text_view = self.builder.get_object("source_code_text_view")
  85. self.main_view_box_top = self.builder.get_object("main_view_box_top")
  86. self.main_view_box_foot = self.builder.get_object("main_view_box_foot")
  87. self.main_view_box_left = self.builder.get_object("main_view_box_left")
  88. self.https_mode_img = self.builder.get_object("https_mode_img")
  89. self.https_mode_button = self.builder.get_object("https_mode_button")
  90. self.tor_mode_img = self.builder.get_object("tor_mode_img")
  91. self.dns_img = self.builder.get_object("dns_img")
  92. self.dns_button = self.builder.get_object("dns_button")
  93. self.javascript_img = self.builder.get_object("javascript_img")
  94. self.javascript_button = self.builder.get_object("javascript_button")
  95. self.java_img = self.builder.get_object("java_img")
  96. self.java_button = self.builder.get_object("java_button")
  97. self.webaudio_img = self.builder.get_object("webaudio_img")
  98. self.webaudio_button = self.builder.get_object("webaudio_button")
  99. self.webgl_img = self.builder.get_object("webgl_img")
  100. self.webgl_button = self.builder.get_object("webgl_button")
  101. self.xss_img = self.builder.get_object("xss_img")
  102. self.xss_button = self.builder.get_object("xss_button")
  103. self.cache_img = self.builder.get_object("cache_img")
  104. self.cache_button = self.builder.get_object("cache_button")
  105. self.styles_img = self.builder.get_object("styles_img")
  106. self.styles_button = self.builder.get_object("styles_button")
  107. self.mac = self.builder.get_object("mac")
  108. self.ip_internal = self.builder.get_object("ip_internal")
  109. self.ip_external = self.builder.get_object("ip_external")
  110. self.ip_location = self.builder.get_object("ip_location")
  111. self.domain_name = self.builder.get_object("domain_name")
  112. self.domain_location = self.builder.get_object("domain_location")
  113. self.domain_lat = self.builder.get_object("domain_lat")
  114. self.domain_long = self.builder.get_object("domain_long")
  115. self.domain_code = self.builder.get_object("domain_code")
  116. self.useragent = self.builder.get_object("useragent")
  117. self.referer = self.builder.get_object("referer")
  118. self.windowsize = self.builder.get_object("windowsize")
  119. self.window = self.builder.get_object("window1")
  120. self.window.connect('destroy', lambda w: Gtk.main_quit())
  121. self.window.show_all()
  122. self.webview = WebKit.WebView()
  123. self.set_useragent()
  124. self.set_referer()
  125. self.set_navigation_settings()
  126. self.set_browser_settings()
  127. self.scrolledwindow.add(self.webview)
  128. self.webview.connect('title-changed', self.change_title)
  129. self.webview.connect('load-committed', self.change_url)
  130. self.webview.connect('load-committed', self.spinner_on)
  131. self.webview.connect('load_finished',self.spinner_off)
  132. self.webview.show() # start the whole show! ;-)
  133. self.get_mac() # get/set our MAC
  134. self.get_ip_internal() # get/set our IP(internal)
  135. self.get_ip_external() # get/set our IP(external)
  136. self.get_windowsize() # get/set our Window(size)
  137. self.main_view_box_top.show() # Websites (main view)
  138. self.main_view_box_foot.hide() # Shell
  139. self.main_view_box_left.hide() # Logs
  140. self.check_requests_tor() # at init and via urllib2
  141. def run(self, opts=None):
  142. Gtk.main()
  143. def set_navigation_settings(self):
  144. settings = WebKit.WebSettings()
  145. settings.set_property('user-agent', self.useragent.get_text()) # set User-agent
  146. self.webview.set_settings(settings)
  147. self.refresh_website()
  148. def set_browser_settings(self):
  149. settings = WebKit.WebSettings()
  150. settings.set_property('enable-frame-flattening', 'False')
  151. settings.set_property('enable-fullscreen', 'False')
  152. settings.set_property('enable-html5-database', 'False')
  153. settings.set_property('enable-html5-local-storage', 'False')
  154. settings.set_property('enable-hyperlink-auditing', 'False')
  155. settings.set_property('media-playback-allows-inline', 'False')
  156. settings.set_property('media-playback-requires-user-gesture', 'False')
  157. settings.set_property('auto-load-images', 'False')
  158. settings.set_property('enable-caret-browsing', 'False')
  159. settings.set_property('enable-site-specific-quirks', 'False')
  160. settings.set_property('enable-smooth-scrolling', 'False')
  161. settings.set_property('print-backgrounds', 'False')
  162. settings.set_property('enable-dns-prefetching', 'True')
  163. settings.set_property('enable-scripts', 'False') # javascript
  164. settings.set_property('javascript-can-access-clipboard', 'False')
  165. settings.set_property('javascript-can-open-windows-automatically', 'False')
  166. settings.set_property("enable-java-applet", 'False')
  167. settings.set_property('enable-offline-web-application-cache', 'False')
  168. settings.set_property('enable-page-cache', 'False')
  169. settings.set_property('enable-private-browsing', 'True')
  170. settings.set_property('enable-webaudio', 'False')
  171. settings.set_property('enable-webgl', 'False')
  172. settings.set_property('enable-xss-auditor', 'True')
  173. settings.set_property('enable-page-cache', 'False')
  174. settings.set_property('enable-offline-web-application-cache', 'False')
  175. settings.set_property("enable-file-access-from-file-uris", "False") # hack.it! >;-)
  176. #settings.set_property('allow-modal-dialogs', 'False')
  177. #settings.set_property('enable-write-console-messages-to-stdout', 'False')
  178. #settings.set_property('draw-compositing-indicators', 'False')
  179. #settings.set_property('enable-accelerated-2d-canvas', 'False')
  180. #settings.set_property('enable-resizable-text-areas', 'False')
  181. #settings.set_property('enable-tabs-to-links', 'False')
  182. #settings.set_property('load-icons-ignoring-image-load-setting', 'False')
  183. self.webview.set_settings(settings)
  184. self.ipData = pygeoip.GeoIP(self.geodb) # load geodb
  185. def on_url_backspace(self, widget):
  186. url = widget.get_text()
  187. self.url.set_text("") # remove text from url-bar when focus-in-event
  188. def on_url_activate(self, widget):
  189. url = widget.get_text()
  190. url = self.check_url_spelling(url) # check for 'hints' when spelling at url bar
  191. self.url.set_text(url) # set url to bar
  192. self.set_domain_name(url) # set url to domain_name
  193. self.set_useragent() # set user-agent
  194. self.set_navigation_settings() # set navigation settings
  195. self.webview.open(url) # visit website
  196. self.check_geoip_visited_website(url) # set geoip (visited link)
  197. if self.home_website in url: # Home website
  198. self.on_visit_home_website()
  199. if self.logs_mode == "ON": # when logging mode in ON
  200. self.main_view_box_left.show() # be sure that logs view is also ON
  201. if url not in self.logs:
  202. self.logs.append(url) # add to logs list
  203. self.refresh_log() # refresh logs
  204. self.get_mac() # get/set our MAC
  205. self.get_ip_internal() # get/set our IP(internal)
  206. self.get_ip_external() # get/set our IP(external)
  207. self.set_useragent() # we want to change our HTTP User-Agent used to visit a site, on each request... and randomnly!
  208. self.get_windowsize() # get/set our window size
  209. html = self.get_html(url) # get source code from visited website
  210. def set_domain_name(self, url):
  211. domain_url = '.'.join(urllib.parse.urlparse(url).netloc.split('.')[-2:])
  212. self.domain_name.set_text("["+domain_url+"]")
  213. def check_url_spelling(self, url): # [rev: 26/06/2019]
  214. if self.home_website in url: # Home website
  215. url = self.home_website
  216. elif "!0" in url: # !0 = 03c8.net(author) / just link!
  217. url = 'https://03c8.net' # ;-)
  218. elif "!deep" in url: # !deep = Torch(content) / just link!
  219. url = 'http://xmh57jrzrnw6insl.onion/'
  220. elif "!start" in url: # !start = StartPage(tems)
  221. url = str(url.split(' ',1)[1])
  222. url = 'https://www.startpage.com/do/search?limit=10&lang=english&format=html&query=' + url
  223. elif "!s" in url: # !s = DuckDuckGo(terms)
  224. if self.tor_mode == "OFF":
  225. url = str(url.split(' ',1)[1])
  226. url = "https://duckduckgo.com/?q=" + url
  227. else:
  228. url = "https://3g2upl4pq6kufc4m.onion/" # duckduckGO (via TOR)
  229. elif "!dict" in url: # !dict = Cambridge Dictionary(words)
  230. url = str(url.split(' ',1)[1])
  231. url = 'https://dictionary.cambridge.org/dictionary/english/' + url
  232. elif "!map" in url: # !map = OpenStreetMaps(locations)
  233. url = str(url.split(' ',1)[1])
  234. url = 'https://www.openstreetmap.org/search?query=' + url
  235. elif "!w" in url: # !w = Wikipedia(terms)
  236. url = str(url.split(' ',1)[1])
  237. url = 'https://en.wikipedia.org/wiki/' + url
  238. elif "!video" in url: # !video = PeerTube(videos)
  239. url = str(url.split(' ',1)[1])
  240. url = 'https://peertube.cpy.re/search?search=' + url
  241. elif "!image" in url: # !image = DevianARt(images)
  242. url = str(url.split(' ',1)[1])
  243. url = 'https://www.deviantart.com/search?q=' + url
  244. elif "!nasa" in url: # !nasa = NASA(images)
  245. url = str(url.split(' ',1)[1])
  246. url = 'https://images.nasa.gov/search-results?q=' + url
  247. elif "!porn" in url: # !porn = PornHub(adult content)
  248. url = str(url.split(' ',1)[1])
  249. url = 'https://www.pornhub.com/video/search?search=' + url
  250. else:
  251. if url.startswith('https://'):
  252. url = url
  253. else:
  254. if url.startswith('http://'):
  255. if self.https_strict == "ON":
  256. url = url.replace('http://', "")
  257. url = 'https://' + url
  258. self.url.set_icon_from_stock(0, "gtk-dialog-authentication")
  259. else:
  260. url = url
  261. self.url.set_icon_from_stock(0, "gtk-dialog-warning")
  262. else:
  263. if self.https_strict == "ON":
  264. url = 'https://' + url
  265. self.url.set_icon_from_stock(0, "gtk-dialog-authentication")
  266. else:
  267. url = self.home_website # when non-supported go to Home
  268. return url
  269. def on_hide_top_panel_button_clicked(self, widget):
  270. hide_top_panel_img = self.hide_top_panel_img.get_stock()
  271. if hide_top_panel_img.stock_id == "gtk-remove":
  272. self.hide_top_panel_img.set_from_stock("gtk-add", 4)
  273. self.top_panel.hide()
  274. self.top_domain.hide()
  275. else:
  276. self.hide_top_panel_img.set_from_stock("gtk-remove", 4)
  277. self.top_panel.show()
  278. self.top_domain.show()
  279. def on_fullscreen_button_clicked(self, widget):
  280. fullscreen_img = self.fullscreen_img.get_stock()
  281. if fullscreen_img.stock_id == "gtk-zoom-fit":
  282. self.fullscreen_img.set_from_stock("gtk-leave-fullscreen", 4)
  283. self.top_panel.hide()
  284. self.top_domain.hide()
  285. self.toolbar.hide()
  286. else:
  287. self.fullscreen_img.set_from_stock("gtk-zoom-fit", 4)
  288. self.top_panel.show()
  289. self.top_domain.show()
  290. self.toolbar.show()
  291. self.get_windowsize() # get/set our window size
  292. def on_max_screen_button_toggled(self, widget):
  293. max_screen_img = self.max_screen_img.get_stock()
  294. if max_screen_img.stock_id == "gtk-fullscreen":
  295. self.max_screen_img.set_from_stock("gtk-leave-fullscreen", 4)
  296. self.window.fullscreen()
  297. self.get_warning_fixed_window() # get warning when maximized(fixed) size for Window
  298. else:
  299. self.max_screen_img.set_from_stock("gtk-fullscreen", 4)
  300. self.window.unfullscreen()
  301. self.get_windowsize() # get/set our window size
  302. def get_warning_fixed_window(self):
  303. msg = ("\n\nWait... ;-)\n\npArAnoIA is trying to evade screen/monitor tracking techniques.\n\nFullscreen mode will disable related contrameasures...\n\nAre you sure about keeping a fixed size?")
  304. dlg_img = Gtk.Image()
  305. dlg_img.set_from_file(os.path.join(self.logo))
  306. dlg_img.show()
  307. dlg = Gtk.MessageDialog(message_format=msg, image=dlg_img, parent=self.window)
  308. dlg.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
  309. dlg.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK)
  310. dlg.set_default_response(Gtk.ResponseType.OK)
  311. dlg.set_title('Warning: Setting a fixed size for Window...')
  312. dlg.run()
  313. dlg.destroy()
  314. def get_html(self, website):
  315. self.webview.execute_script('oldtitle=document.title;document.title=document.documentElement.innerHTML;')
  316. html = self.webview.get_main_frame().get_title()
  317. self.webview.execute_script('document.title=oldtitle;')
  318. return html
  319. def get_mac(self):
  320. current_mac = self.mac.get_text() # we want to be sure about our MAC at init
  321. if current_mac == "255.255.255.255": # set by default at GUI level
  322. self.set_mac()
  323. def set_mac(self):
  324. mac = getnode() # to get physical address
  325. hex_mac = str(":".join(re.findall('..', '%012x' % mac)))
  326. self.mac.set_text(hex_mac)
  327. def get_ip_internal(self):
  328. current_ip_internal = self.ip_internal.get_text() # we want to be sure about our private IP (for internal LAN)
  329. if current_ip_internal == "127.0.0.1": # set by default at GUI level
  330. self.set_ip_internal()
  331. def set_ip_internal(self):
  332. s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  333. try:
  334. s.connect(("1.1.1.1", 1)) # black magic! /23-06-2019/ [UFONet+LoVe] ;-)
  335. except:
  336. print("\n[Info] Network is unaccesible: Aborting!\n")
  337. sys.exit(2)
  338. private_ip = s.getsockname()[0]
  339. s.close()
  340. self.ip_internal.set_text(private_ip)
  341. def get_ip_external(self):
  342. current_ip_external = self.ip_external.get_text() # we want to be sure about our public IP (for the Internet)
  343. if current_ip_external == "127.0.0.1": # set by default at GUI level
  344. self.set_ip_external()
  345. def set_ip_external(self):
  346. try:
  347. public_ip = self.external_ip # method 1: extracted from Home website
  348. except:
  349. try:
  350. public_ip = requests.get(self.check_ip_service1).text # method 2: direct request to third-party services
  351. except:
  352. public_ip = "127.0.0.1"
  353. if public_ip != "127.0.0.1": # check for geolocation
  354. self.check_geoip_ip_external(public_ip)
  355. self.ip_external.set_text(public_ip)
  356. def check_geoip_ip_external(self, ip):
  357. try:
  358. record = self.ipData.record_by_addr(ip)
  359. self.ip_location.set_text("["+str(record['country_name'])+"]")
  360. except:
  361. self.ip_location.set_text('[Unknown]')
  362. def check_geoip_visited_website(self, ip):
  363. domain_url = '.'.join(urllib.parse.urlparse(ip).netloc.split('.')[-2:])
  364. try:
  365. record = self.ipData.record_by_name(domain_url)
  366. self.domain_location.set_text("["+str(record['country_name'])+"]")
  367. self.domain_lat.set_text("(Lat: "+str(record['latitude'])+")")
  368. self.domain_long.set_text("(Long: "+str(record['longitude'])+")")
  369. self.domain_code.set_text("["+str(record['country_code'])+"]")
  370. except:
  371. self.domain_location.set_text('[Unknown]')
  372. self.domain_lat.set_text("(Lat: ?)")
  373. self.domain_long.set_text("(Long: ?)")
  374. self.domain_code.set_text("[?]")
  375. def set_useragent(self):
  376. user_agent = random.choice(self.agents).strip()
  377. self.useragent.set_text(user_agent)
  378. def get_windowsize(self):
  379. windowsize = self.window.get_size()
  380. w, h = windowsize
  381. windowsize = str(w)+"x"+str(h)
  382. self.windowsize.set_text(windowsize) # set to 1024x768 by default
  383. def on_refresh_clicked(self, widget):
  384. self.webview.reload()
  385. def on_back_clicked(self, widget):
  386. self.webview.go_back()
  387. def on_forward_clicked(self, widget):
  388. self.webview.go_forward()
  389. def on_stop_clicked(self, widget):
  390. self.webview.stop_loading()
  391. def change_title(self, widget, frame, title):
  392. self.window.set_title('/pArAnoIA Browser/ | ' + title)
  393. def change_url(self, widget, frame):
  394. uri = frame.get_uri()
  395. self.url.set_text(uri)
  396. self.back.set_sensitive(self.webview.can_go_back() )
  397. self.forward.set_sensitive(self.webview.can_go_forward() )
  398. def on_navigation_mode_button_toggled(self, widget):
  399. self.on_navigation_mode_img_button_press_event(self)
  400. def on_navigation_mode_img_button_press_event(self, widget):
  401. navigation_img = self.navigation_mode_img.get_stock()
  402. if navigation_img.stock_id == "gtk-orientation-landscape":
  403. self.navigation_mode_img.set_from_stock("gtk-find-and-replace", 4)
  404. self.navigation_mode = "INSPECTOR" # set navigation mode to: INSPECTOR
  405. self.start_inspector()
  406. else:
  407. self.navigation_mode_img.set_from_stock("gtk-orientation-landscape", 4)
  408. self.navigation_mode = "EXPLORER" # set navigation mode to: EXPLORER
  409. settings = WebKit.WebSettings()
  410. settings.set_property('enable-developer-extras', False)
  411. self.webview.set_settings(settings)
  412. self.main_view_box_foot.hide()
  413. self.set_referer() # set referer according to Navigation mode
  414. def start_inspector(self):
  415. view = self.webview
  416. self.webview = WebKit.WebView()
  417. settings = WebKit.WebSettings()
  418. settings.set_property('enable-developer-extras', True)
  419. view.set_settings(settings)
  420. self.inspector = view.get_inspector()
  421. self.inspector.connect("inspect-web-view", self.inspect)
  422. self.webview = WebKit.WebView()
  423. self.scrolledwindowinspector.add(self.webview)
  424. self.scrolledwindowinspector.show()
  425. self.source_code_text_view.hide()
  426. self.main_view_box_foot.show()
  427. def inspect(self, inspector, view):
  428. self.scrolledwindowinspector.show_all()
  429. self.webview.show()
  430. return self.webview
  431. def on_logs_button_toggled(self, widget):
  432. self.on_logs_img_button_press_event(self)
  433. def on_logs_img_button_press_event(self, widget):
  434. settings = WebKit.WebSettings()
  435. logs_img = self.logs_img.get_stock()
  436. if logs_img.stock_id == "gtk-no":
  437. self.logs_img.set_from_stock("gtk-yes", 4)
  438. self.logs_mode = "OFF" # set logging mode to: OFF
  439. settings.set_property('enable-private-browsing', 'True')
  440. self.main_view_box_left.hide()
  441. else:
  442. self.logs_img.set_from_stock("gtk-no", 4)
  443. self.logs_mode = "ON" # set logging mode to: ON
  444. settings.set_property('enable-private-browsing', 'False')
  445. self.main_view_box_left.show()
  446. self.webview.set_settings(settings)
  447. def refresh_log(self):
  448. self.logs_view_buffer.set_text("")
  449. for log in self.logs:
  450. iter = self.logs_view_buffer.get_end_iter()
  451. self.logs_view_buffer.insert(iter, log + "\n")
  452. def show_source_code(self, url):
  453. self.webviewsource = WebKit.WebView()
  454. self.webviewsource.open(url)
  455. def get_source(webobj, frame):
  456. source = self.webviewsource.get_main_frame().get_data_source().get_data()
  457. code_buffer = str(self.source_code_view_buffer.set_text(source.str))
  458. self.webviewsource.connect("load-finished", get_source)
  459. browser_settings = self.webviewsource.get_settings()
  460. browser_settings.set_property('enable-default-context-menu', True)
  461. browser_settings.set_property('enable-accelerated-compositing', True)
  462. browser_settings.set_property('enable-file-access-from-file-uris', True)
  463. self.webviewsource.set_settings(browser_settings)
  464. self.set_source_code_on_url_icon() # set source_code at url bar
  465. self.scrolledwindowinspector.hide()
  466. self.source_code_text_view.show()
  467. self.main_view_box_foot.show()
  468. def set_referer(self):
  469. referer = self.referer.get_text()
  470. if self.navigation_mode == "INSPECTOR":
  471. self.referer.set_text("127.0.0.1") # turn referer into INSPECTOR mode
  472. else:
  473. self.referer.set_text("-") # turn referer into EXPLORER mode
  474. def refresh_website(self):
  475. url = self.url.get_text()
  476. self.webview.open(url)
  477. def on_styles_button_toggled(self, widget):
  478. self.on_styles_button_press_event(self)
  479. def on_styles_button_press_event(self, widget):
  480. settings = WebKit.WebSettings()
  481. styles_img = self.styles_img.get_stock()
  482. if styles_img.stock_id == "gtk-yes":
  483. self.styles_img.set_from_stock("gtk-no", 4)
  484. self.styles = "OFF"
  485. settings.set_property('enable-frame-flattening', 'True')
  486. settings.set_property('enable-fullscreen', 'True')
  487. settings.set_property('enable-html5-database', 'True')
  488. settings.set_property('enable-html5-local-storage', 'True')
  489. settings.set_property('enable-hyperlink-auditing', 'True')
  490. settings.set_property('media-playback-allows-inline', 'True')
  491. settings.set_property('media-playback-requires-user-gesture', 'True')
  492. settings.set_property('auto-load-images', 'True')
  493. settings.set_property('enable-caret-browsing', 'True')
  494. settings.set_property('enable-site-specific-quirks', 'True')
  495. settings.set_property('enable-smooth-scrolling', 'True')
  496. else:
  497. self.styles_img.set_from_stock("gtk-yes", 4)
  498. self.styles = "ON"
  499. settings.set_property('enable-frame-flattening', 'False')
  500. settings.set_property('enable-fullscreen', 'False')
  501. settings.set_property('enable-html5-database', 'False')
  502. settings.set_property('enable-html5-local-storage', 'False')
  503. settings.set_property('enable-hyperlink-auditing', 'False')
  504. settings.set_property('media-playback-allows-inline', 'False')
  505. settings.set_property('media-playback-requires-user-gesture', 'False')
  506. settings.set_property('auto-load-images', 'False')
  507. settings.set_property('enable-caret-browsing', 'False')
  508. settings.set_property('enable-site-specific-quirks', 'False')
  509. settings.set_property('enable-smooth-scrolling', 'False')
  510. self.webview.set_settings(settings)
  511. self.refresh_website()
  512. def on_cache_button_toggled(self, widget):
  513. self.on_cache_button_press_event(self)
  514. def on_cache_button_press_event(self, widget):
  515. settings = WebKit.WebSettings()
  516. cache_img = self.cache_img.get_stock()
  517. if cache_img.stock_id == "gtk-yes":
  518. self.cache_img.set_from_stock("gtk-no", 4)
  519. self.cache = "OFF"
  520. settings.set_property('enable-page-cache', 'True')
  521. settings.set_property('enable-offline-web-application-cache', 'True')
  522. else:
  523. self.cache_img.set_from_stock("gtk-yes", 4)
  524. self.cache = "ON"
  525. settings.set_property('enable-page-cache', 'False')
  526. settings.set_property('enable-offline-web-application-cache', 'False')
  527. self.webview.set_settings(settings)
  528. self.refresh_website()
  529. def on_xss_button_toggled(self, widget):
  530. self.on_xss_button_press_event(self)
  531. def on_xss_button_press_event(self, widget):
  532. settings = WebKit.WebSettings()
  533. xss_img = self.xss_img.get_stock()
  534. if xss_img.stock_id == "gtk-yes":
  535. self.xss_img.set_from_stock("gtk-no", 4)
  536. self.xss = "OFF"
  537. settings.set_property('enable-xss-auditor', 'False')
  538. else:
  539. self.xss_img.set_from_stock("gtk-yes", 4)
  540. self.xss = "ON"
  541. settings.set_property('enable-xss-auditor', 'True')
  542. self.webview.set_settings(settings)
  543. self.refresh_website()
  544. def on_webgl_button_toggled(self, widget):
  545. self.on_webgl_button_press_event(self)
  546. def on_webgl_button_press_event(self, widget):
  547. settings = WebKit.WebSettings()
  548. webgl_img = self.webgl_img.get_stock()
  549. if webgl_img.stock_id == "gtk-yes":
  550. self.webgl_img.set_from_stock("gtk-no", 4)
  551. self.webgl = "OFF"
  552. settings.set_property("enable-webgl", 'False')
  553. else:
  554. self.webgl_img.set_from_stock("gtk-yes", 4)
  555. self.webgl = "ON"
  556. settings.set_property("enable-webgl", 'True')
  557. self.webview.set_settings(settings)
  558. self.refresh_website()
  559. def on_webaudio_button_toggled(self, widget):
  560. self.on_webaudio_button_press_event(self)
  561. def on_webaudio_button_press_event(self, widget):
  562. settings = WebKit.WebSettings()
  563. webaudio_img = self.webaudio_img.get_stock()
  564. if webaudio_img.stock_id == "gtk-yes":
  565. self.webaudio_img.set_from_stock("gtk-no", 4)
  566. self.webaudio = "OFF"
  567. settings.set_property("enable-webaudio", 'False')
  568. else:
  569. self.webaudio_img.set_from_stock("gtk-yes", 4)
  570. self.webaudio = "ON"
  571. settings.set_property("enable-webaudio", 'True')
  572. self.webview.set_settings(settings)
  573. self.refresh_website()
  574. def on_java_button_toggled(self, widget):
  575. self.on_java_button_press_event(self)
  576. def on_java_button_press_event(self, widget):
  577. settings = WebKit.WebSettings()
  578. java_img = self.java_img.get_stock()
  579. if java_img.stock_id == "gtk-yes":
  580. self.java_img.set_from_stock("gtk-no", 4)
  581. self.java = "OFF"
  582. self.flash = "OFF"
  583. settings.set_property("enable-java-applet", 'False')
  584. else:
  585. self.java_img.set_from_stock("gtk-yes", 4)
  586. self.java = "ON"
  587. self.flash = "ON"
  588. settings.set_property("enable-java-applet", 'True')
  589. self.webview.set_settings(settings)
  590. self.refresh_website()
  591. def on_javascript_button_toggled(self, widget):
  592. self.on_javascript_button_press_event(self)
  593. def on_javascript_button_press_event(self, widget):
  594. settings = WebKit.WebSettings()
  595. javascript_img = self.javascript_img.get_stock()
  596. if javascript_img.stock_id == "gtk-yes":
  597. self.javascript_img.set_from_stock("gtk-no", 4)
  598. self.javascript = "OFF"
  599. settings.set_property('enable-scripts', 'False')
  600. settings.set_property('javascript-can-access-clipboard', 'False')
  601. settings.set_property('javascript-can-open-windows-automatically', 'False')
  602. else:
  603. self.javascript_img.set_from_stock("gtk-yes", 4)
  604. self.javascript = "ON"
  605. settings.set_property('enable-scripts', 'True')
  606. settings.set_property('javascript-can-access-clipboard', 'False')
  607. settings.set_property('javascript-can-open-windows-automatically', 'True')
  608. self.webview.set_settings(settings)
  609. self.refresh_website()
  610. def on_dns_button_toggled(self, widget):
  611. self.on_dns_button_press_event(self)
  612. def on_dns_button_press_event(self, widget):
  613. settings = WebKit.WebSettings()
  614. dns_img = self.dns_img.get_stock()
  615. if dns_img.stock_id == "gtk-yes":
  616. self.dns_img.set_from_stock("gtk-no", 4)
  617. self.dns_prefetching = "OFF"
  618. settings.set_property('enable-dns-prefetching', 'False')
  619. else:
  620. self.dns_img.set_from_stock("gtk-yes", 4)
  621. self.dns_prefetching = "ON"
  622. settings.set_property('enable-dns-prefetching', 'True')
  623. self.webview.set_settings(settings)
  624. def on_https_mode_button_toggled(self, widget):
  625. self.on_https_mode_img_button_press_event(self)
  626. def on_https_mode_img_button_press_event(self, widget):
  627. https_img = self.https_mode_img.get_stock()
  628. if https_img.stock_id == "gtk-yes":
  629. self.https_mode_img.set_from_stock("gtk-no", 4)
  630. self.https_strict = "OFF"
  631. else:
  632. self.https_mode_img.set_from_stock("gtk-yes", 4)
  633. self.https_strict = "ON"
  634. self.set_warning_on_url_icon() # set warning at url bar
  635. self.refresh_website()
  636. def on_source_code_button_toggled(self, widget):
  637. self.on_source_code_img_button_press_event(self)
  638. def on_source_code_img_button_press_event(self, widget):
  639. url = self.url.get_text()
  640. if url.startswith("http") or url.startswith("source-code"):
  641. self.show_source_code(url)
  642. def set_source_code_on_url_icon(self):
  643. uri = self.url.get_text()
  644. url_primary_icon_name = self.url.get_icon_stock(0)
  645. if url_primary_icon_name == "gtk-dialog-authentication" or url_primary_icon_name == "gtk-home" or url_primary_icon_name == "gtk-warning":
  646. self.url.set_icon_from_stock(0, "gtk-properties")
  647. if uri.startswith("http://"):
  648. uri = uri.replace("http://", "")
  649. elif uri.startswith("https://"):
  650. uri = uri.replace("https://", "")
  651. url = "source-code: " + uri
  652. if "/" in url:
  653. url = url.replace("/", "")
  654. self.url.set_text(url)
  655. self.main_view_box_top.hide()
  656. self.main_view_box_foot.show()
  657. else:
  658. if "source-code" in uri:
  659. uri = uri.replace("source-code: ", "")
  660. check_default = "https://" + uri
  661. if check_default == self.home_website: # Home site detected! ;-)
  662. self.url.set_icon_from_stock(0, "gtk-home")
  663. uri = 'https://' + uri
  664. else:
  665. if self.https_strict == "ON":
  666. self.url.set_icon_from_stock(0, "gtk-dialog-authentication")
  667. uri = 'https://' + uri
  668. else:
  669. self.url.set_icon_from_stock(0, "gtk-dialog-warning")
  670. uri = 'http://' + uri
  671. self.url.set_text(uri)
  672. self.main_view_box_top.show()
  673. self.main_view_box_foot.hide()
  674. self.set_useragent()
  675. self.set_navigation_settings()
  676. self.webview.open(uri) # re-visit website after review source code
  677. def set_warning_on_url_icon(self):
  678. url_primary_icon_name = self.url.get_icon_stock(0)
  679. if url_primary_icon_name == "gtk-dialog-authentication" or url_primary_icon_name == "gtk-home" or url_primary_icon_name == "gtk-properties":
  680. self.url.set_icon_from_stock(0, "gtk-dialog-warning")
  681. else:
  682. self.url.set_icon_from_stock(0, "gtk-dialog-authentication")
  683. def on_visit_home_website(self):
  684. url_primary_icon_name = self.url.get_icon_stock(0)
  685. self.url.set_icon_from_stock(0, "gtk-home") # sweet home-lab ;-)
  686. html = self.get_html(self.home_website)
  687. self.check_html_tor(html) # check TOR via html
  688. self.extract_ip_external_from_home_website(html) # extract public IP from Home website
  689. self.check_geoip_visited_website(self.home_website) # set geoip (Home)
  690. def check_requests_tor(self): # check for TOR via direct request
  691. tor_reply = urllib.request.urlopen(self.home_website).read() # check if TOR is enabled
  692. if not tor_reply or 'Congratulations'.encode('utf-8') not in tor_reply:
  693. self.tor_mode = "OFF"
  694. self.tor_mode_img.set_from_stock("gtk-no", 4)
  695. else:
  696. self.tor_mode = "ON"
  697. self.tor_mode_img.set_from_stock("gtk-yes", 4)
  698. self.set_useragent()
  699. self.set_navigation_settings()
  700. self.set_domain_name(self.home_website) # set url to domain_name
  701. self.webview.open(self.home_website) # open Home website by default
  702. self.check_geoip_visited_website(self.home_website) # set geoip (Home)
  703. url_primary_icon_name = self.url.get_icon_stock(0)
  704. self.url.set_icon_from_stock(0, "gtk-home") # sweet home-lab ;-)
  705. def check_html_tor(self, html):
  706. tor_mode_img = self.tor_mode_img.get_stock() # check for TOR 'network circuit'
  707. if 'Congratulations' not in html:
  708. self.tor_mode = "OFF"
  709. self.tor_mode_img.set_from_stock("gtk-no", 4)
  710. else:
  711. self.tor_mode = "ON"
  712. self.tor_mode_img.set_from_stock("gtk-yes", 4)
  713. def extract_ip_external_from_home_website(self, html):
  714. try:
  715. self.external_ip = html.split('<strong>')[1].split('</strong>')[0].strip()
  716. except:
  717. pass # other methods supported... ;-)
  718. def spinner_on(self,widget,frame):
  719. self.spinner.start()
  720. def spinner_off(self, widget,frame):
  721. self.spinner.stop()
  722. if __name__ == "__main__":
  723. app = Browser()
  724. app.run()