<commit_before>import optparse
import sys
import requests
import re
from bs4 import BeautifulSoup

def detect_version(header_composed_by):
    regex_version_spip = re.search(r"SPIP (\d+).(\d+).(\d+)", header_composed_by)
    try:
        major_version = regex_version_spip.group(1)
        intermediary_version = regex_version_spip.group(2)
        minor_version = regex_version_spip.group(3)
        print "[!] version is : " + str(major_version) + "." + str(intermediary_version) + "." + str(minor_version)
    except:
        print "[-] unable to find the version"
        pass

def detect_plugins(url, bruteforce_file):
    global opts

    plugins_folder_uri = "plugins/"
    url = url + plugins_folder_uri
    print "Accessing " + url
    req = requests.get(url, timeout=5)

    if (req.status_code == 200):
        # folder might be viewable
        # gonna iterate on the different plugins
        print "[!] folder plugins/ is accessible"
        soup = BeautifulSoup(req.content)
        links_to_plugins = soup('a')
        for link in links_to_plugins:
            # grabbing the folder of the plugin
            try:
                regex_plugin = re.search(r"href=\"(\w+/)\"> (\w+)/<", str(link))
                folder_plugin = regex_plugin.group(1)
                name_plugin = regex_plugin.group(2)
                detect_version_by_plugin_name(url, folder_plugin)
            except:
                pass
            
    elif (req.status_code == 403):
        # folder might exist but not accessible
        # gonna try to detect plugins with brute force attack
        print "[-] folder plugins/ is forbidden"
        if (bruteforce_file is not None):
            # bruteforce the plugins folder
            bruteforce_folder_plugins(url, bruteforce_file)
    elif (req.status_code == 404):
        # folder seems to not exist
        print "[-] folder plugins/ does not exist"
    else:
        print "While accessing " + url + ", the status code is : " + str(req.status_code)


def remove_new_line_from_name(name):
    return name[:-1] + '/'

def bruteforce_folder_plugins(url, name_file):
    # uri for the plugins folder
    plugins_folder_uri = "plugins/"
    url = url + plugins_folder_uri

    folders = []
    with open(name_file) as f:
        folders = f.readlines()

    # removing new line 
    folders = [remove_new_line_from_name(name) for name in folders]
    for folder in folders:
        print "[-] Trying : " + url + folder
        detect_version_by_plugin_name(url, folder)

def detect_version_by_plugin_name(url, folder):
    try:
        url_plugin = url + folder + "plugin.xml"
        # HTTP GET to get the version of the plugin
        req_plugin_xml = requests.get(url_plugin, timeout=5)
        if (req_plugin_xml.status_code == 200):
            regex_version_plugin = re.search(r"<version>(\d+(.\d+)?(.\d+)?)</version>", req_plugin_xml.content)
            print "[!] Plugin " + folder[:-1] + " detected. Version : " + str(regex_version_plugin.group(1))
            print "URL : " + url_plugin
        else:
            pass
    except:
        try:
            url_plugin = url + folder + "paquet.xml"
            # HTTP GET to get the version of the plugin
            req_plugin_xml = requests.get(url_plugin, timeout=5)
            if (req_plugin_xml.status_code == 200):
                regex_version_plugin = re.search(r"version=\"(\d+(.\d+)?(.\d+)?)\"", req_plugin_xml.content)
                print "[!] Plugin " + folder[:-1] + " detected. Version : " + str(regex_version_plugin.group(1))
                print "URL : " + url_plugin
            else:
                pass
        except:
            pass    

# option parser
parser = optparse.OptionParser()
parser.add_option('--website', help='Website to pentest', dest='website')
parser.add_option('--path', help='Path for webapp (default : "/")', dest='path', default='/')
parser.add_option('--plugins', help='Detect plugins installed', dest='detect_plugins', default=False, action='store_true')
parser.add_option('--version', help='Detect version', dest='detect_version', default=False, action='store_true')
parser.add_option('--bruteforce_plugins_file', help='Bruteforce plugin file (eg. plugins_name.txt)', dest='bruteforce_plugins_file', default=None)
# parser.add_option('--v', help='Verbose', dest='verbose', default=False)

if (len(sys.argv) <= 2):
    parser.print_help()
else:
    (opts, args) = parser.parse_args()

    url = opts.website + opts.path

    if (opts.detect_version):
        print "Accessing " + url
        req = requests.get(url, timeout=5)
        detect_version(req.headers['composed-by']) 

    if (opts.detect_plugins):
        detect_plugins(url, opts.bruteforce_plugins_file)

    # detect plugin will do brute force attack if it finds a HTTP 403 (Restricted)
    if (opts.detect_plugins is False and opts.bruteforce_plugins_file is not None):
        bruteforce_folder_plugins(url, opts.bruteforce_plugins_file)<commit_msg>Added the vuln identification (quick & dirty) will be refactored<commit_after>import optparse
import sys
import requests
import re
from bs4 import BeautifulSoup

major_version = 0
intermediary_version = 0
minor_version = 0

def detect_version(header_composed_by):
    global major_version
    global intermediary_version
    global minor_version

    regex_version_spip = re.search(r"SPIP (\d+).(\d+).(\d+)", header_composed_by)
    try:
        major_version = regex_version_spip.group(1)
        intermediary_version = regex_version_spip.group(2)
        minor_version = regex_version_spip.group(3)

        print "[!] version is : " + str(major_version) + "." + str(intermediary_version) + "." + str(minor_version)
    except:
        print "[-] unable to find the version"
        pass

def detect_plugins(url, bruteforce_file):
    global opts

    plugins_folder_uri = "plugins/"
    url = url + plugins_folder_uri
    print "Accessing " + url
    req = requests.get(url, timeout=5)

    if (req.status_code == 200):
        # folder might be viewable
        # gonna iterate on the different plugins
        print "[!] folder plugins/ is accessible"
        soup = BeautifulSoup(req.content)
        links_to_plugins = soup('a')
        for link in links_to_plugins:
            # grabbing the folder of the plugin
            try:
                regex_plugin = re.search(r"href=\"(\w+/)\"> (\w+)/<", str(link))
                folder_plugin = regex_plugin.group(1)
                name_plugin = regex_plugin.group(2)
                detect_version_by_plugin_name(url, folder_plugin)
            except:
                pass
            
    elif (req.status_code == 403):
        # folder might exist but not accessible
        # gonna try to detect plugins with brute force attack
        print "[-] folder plugins/ is forbidden"
        if (bruteforce_file is not None):
            # bruteforce the plugins folder
            bruteforce_folder_plugins(url, bruteforce_file)
    elif (req.status_code == 404):
        # folder seems to not exist
        print "[-] folder plugins/ does not exist"
    else:
        print "While accessing " + url + ", the status code is : " + str(req.status_code)


def remove_new_line_from_name(name, char=''):
    return name[:-1] + char

def detect_vulnerabilities():
    global major_version
    global intermediary_version
    global minor_version

    vulns = []
    with open('spip_vulns.db') as f:
        vulns = f.readlines()

    # removing new line 
    vulns = [remove_new_line_from_name(vuln) for vuln in vulns]

    # parsing the db to check if there's any vuln
    for vuln in vulns:
        vals = vuln.split(';;')
        versions_vuln = vals[0]
        description_vuln = vals[1]
        url_vuln = vals[2]
        version_vuln = versions_vuln.split('/')
        for version in version_vuln:
            tmp = version.split('.')
            i = 0
            while i < len(tmp):
                if (i == 0 and tmp[i] != major_version):
                    break
                if (i == 1 and tmp[i] != intermediary_version):
                    break

                if (i == 1 and tmp[i] == intermediary_version and (i + 1) > len(tmp)):
                    print "[!] Potential Vulnerability : (versions : " + versions_vuln + "), " + description_vuln + ", details : " + url_vuln
                    break

                if ((i == 2) and (int(tmp[i]) >= int(minor_version))):
                    print "[!] Potential Vulnerability : (versions : " + versions_vuln + "), " + description_vuln + ", details : " + url_vuln
                    break
                i = i + 1

def bruteforce_folder_plugins(url, name_file):
    # uri for the plugins folder
    plugins_folder_uri = "plugins/"
    url = url + plugins_folder_uri

    folders = []
    with open(name_file) as f:
        folders = f.readlines()

    # removing new line 
    folders = [remove_new_line_from_name(name, '/') for name in folders]
    for folder in folders:
        print "[-] Trying : " + url + folder
        detect_version_by_plugin_name(url, folder)

def detect_version_by_plugin_name(url, folder):
    try:
        url_plugin = url + folder + "plugin.xml"
        # HTTP GET to get the version of the plugin
        req_plugin_xml = requests.get(url_plugin, timeout=5)
        if (req_plugin_xml.status_code == 200):
            regex_version_plugin = re.search(r"<version>(\d+(.\d+)?(.\d+)?)</version>", req_plugin_xml.content)
            print "[!] Plugin " + folder[:-1] + " detected. Version : " + str(regex_version_plugin.group(1))
            print "URL : " + url_plugin
        else:
            pass
    except:
        try:
            url_plugin = url + folder + "paquet.xml"
            # HTTP GET to get the version of the plugin
            req_plugin_xml = requests.get(url_plugin, timeout=5)
            if (req_plugin_xml.status_code == 200):
                regex_version_plugin = re.search(r"version=\"(\d+(.\d+)?(.\d+)?)\"", req_plugin_xml.content)
                print "[!] Plugin " + folder[:-1] + " detected. Version : " + str(regex_version_plugin.group(1))
                print "URL : " + url_plugin
            else:
                pass
        except:
            pass    

# option parser
parser = optparse.OptionParser()
parser.add_option('--website', help='Website to pentest', dest='website')
parser.add_option('--path', help='Path for webapp (default : "/")', dest='path', default='/')
parser.add_option('--plugins', help='Detect plugins installed', dest='detect_plugins', default=False, action='store_true')
parser.add_option('--version', help='Detect version', dest='detect_version', default=False, action='store_true')
parser.add_option('--vulns', help='Detect possible vulns', dest='detect_vulns', default=False, action='store_true')
parser.add_option('--bruteforce_plugins_file', help='Bruteforce plugin file (eg. plugins_name.txt)', dest='bruteforce_plugins_file', default=None)
# parser.add_option('--v', help='Verbose', dest='verbose', default=False)

if (len(sys.argv) <= 2):
    parser.print_help()
else:
    (opts, args) = parser.parse_args()

    url = opts.website + opts.path

    if (opts.detect_version or opts.detect_vulns):
        print "Accessing " + url
        req = requests.get(url, timeout=5)
        detect_version(req.headers['composed-by']) 

    if (opts.detect_plugins):
        detect_plugins(url, opts.bruteforce_plugins_file)

    # detect plugin will do brute force attack if it finds a HTTP 403 (Restricted)
    if (opts.detect_plugins is False and opts.bruteforce_plugins_file is not None):
        bruteforce_folder_plugins(url, opts.bruteforce_plugins_file)

    if (opts.detect_vulns):
        detect_vulnerabilities()
{'fraction_non_alphanumeric': 0.1185064935064935, 'fraction_numerical': 0.006920710868079289, 'mean_word_length': 2.6160024714241583, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4385325', 'n_tokens_mistral': 3702, 'n_tokens_neox': 3516, 'n_words': 876}