#!/usr/bin/env python

import requests
import re
import urlparse
from bs4 import BeautifulSoup


class Scanner:
    def __init__(self, url, ignore_links):
        self.session = requests.Session()
        self.target_url = url
        self.target_links = []
        self.ignore_links = ignore_links

    def link_extraction(self, url):
        response = self.session.get(url)
        return re.findall('(?:href=")(.*?)"', response.content)

    def crawl(self, url=None):
        if url is None:
            url = self.target_url
        links = self.link_extraction(url)
        for link in links:
            link = urlparse.urljoin(url, link)

            if '#' in link:
                link = link.split('#')[0]

            if self.target_url in link and link not in self.target_links and link not in self.ignore_links:
                self.target_links.append(link)
                print(link)
                self.crawl(link)

    def extract_forms(self, url):
        response = self.session.get(url)
        parsed_html = BeautifulSoup(response.content, 'html.parser')
        return parsed_html.findAll('form')

    def submit_form(self, form, value, url):
        action = form.get('action')       # .get is used for attributes not for tags
        post_url = urlparse.urljoin(url, action)
        method = form.get('method')

        input_list = form.find_all('input')  # find_all == findAll

        dict = {}
        for input in input_list:
            input_name = input.get('name')
            input_type = input.get('type')
            input_value = input.get('value')
            if input_type == 'text':
                input_value = value
            dict[input_name] = input_value
        if method == 'post':
            return self.session.post(post_url, data=dict)
        return self.session.get(post_url, params=dict)

    def run_scanner(self):
        for link in self.target_links:
            forms = self.extract_forms(link)
            for form in forms:
                print('---> Testing form in' + link)
                vulnerable_to_xss = self.test_xss_in_form(form, link)
                if vulnerable_to_xss:
                    print('\n\n *** XSS Discoverd in ' + link + 'in the following form')
                    print(form)

            if '=' in link:
                print('\n\n--->Testing ' + link)
                vulnerable_to_xss = self.test_xss_in_link(link)
                if vulnerable_to_xss:
                    print('***Discovere XSS in ' + link)

    def test_xss_in_link(self, url):
        xss_test_script = "<sCript>alert('test')</scriPt>"
        url = url.replace('=', '=' + xss_test_script)
        response = self.session.get(url)
        return xss_test_script in response.content

    def test_xss_in_form(self, form, url):
        xss_test_script = "<sCript>alert('test')</scriPt>"
        response = self.submit_form(form, xss_test_script, url)
        return xss_test_script in response.content




target_url = 'http://10.0.2.22/dvwa/'
ignore_links = ['http://10.0.2.22/dvwa/logout.php']

dict = {'username': 'admin', 'password': 'password', 'Login': 'submit'}

vul_scanner = Scanner(target_url, ignore_links)
vul_scanner.session.post('http://10.0.2.22/dvwa/login.php', data=dict)

vul_scanner.crawl()
vul_scanner.run_scanner()