#!/usr/bin/python3 
#
# BHParse : Parse BurpSuite Generated XML (intercept history) files into html.  
# author : https://github.com/ajaytekam 
# usage : ./bhparse -f BurpFile.xml 
# 

import sys
import os
import base64 
import random
import argparse
import xml.etree.ElementTree as ET
from hashlib import md5
from shutil import rmtree  
import zipfile
import wget 
import os

def GenerateFileName():
    randomNum = "{}".format(random.randint(1200,2000)/1000.0)
    name = md5(randomNum.encode('utf-8')).hexdigest()
    return f"{name}.html" 

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("file", help="XML file generated by BurpSuite")
    args = parser.parse_args()
    tree = ET.parse(args.file)
    root = tree.getroot()
    dirName = root[0][2].text
    # checking if ./dirName directory exists or not 
    PATH = os.getcwd()+"/"+dirName
    if os.path.isdir(PATH):
        print("[!] './{}' directory exists...".format(dirName))
        print("[?] Choose Y|y to delete './{}' and continue or  N|n to exit".format(dirName))
        ch = input("[?] Choose [y|n]: ")
        if ch == 'N' or ch == 'n':
            sys.exit()
        else:
            rmtree(dirName)
    # create OP dir
    os.mkdir(dirName)
    os.chdir(dirName)
    # directory for request-response files 
    os.mkdir("files")
    print("[+] Writing files in " + os.getcwd())
    # number of items 
    item_len = len(root)
    # open file handler
    IndexFile = open("index.html", "w")
    # hostname 
    hostname = root[0][2].text 
    IndexHeaderBody = """
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Burp Proxy Report</title>
        <link rel="stylesheet" type="text/css" href="StaticFiles/datatables.min.css">
        <script type="text/javascript" charset="utf8" src="StaticFiles/jquery-3.3.1.min.js"></script>
        <script type="text/javascript" charset="utf8" src="StaticFiles/datatables.min.js"></script>
    </head>
    <body>
    <center><h1>{host}</h1></center>
    <table id="MyTable" class="display">
    <thead>
      <tr>
         <th>URL</th>
         <th>Status</th>
         <th>Method</th>
         <th>MIME</th>
         <th>LENGTH</th>
         <th>Details</th>
      </tr>
    </thead>
    <tbody>
    """.format(host=hostname)
    IndexFile.write(IndexHeaderBody)
    counter = 0
    # index to access items
    # time           0
    # url            1
    # host           2
    # port           3
    # protocol       4
    # method         5
    # path           6
    # extension      7
    # request        8
    # status         9
    # responselength 10
    # mimetype       11
    # response       12
    # comment        13
    #
    while item_len: 
        # iterate for each item and create file and 
        # write the data in it
        # create an entry for item in index.md
        url = root[counter][1].text
        status = root[counter][9].text
        method = root[counter][5].text
        mimetype = root[counter][11].text
        fileName = GenerateFileName()
        responselength = root[counter][10].text
        TableRow =  """
        <tr>
          <td>{URL}</td>
          <td>{STATUS}</td>
          <td>{METHOD}</td>
          <td>{MIME}</td>
          <td>{LENGTH}</td>
          <td><a href="files/{FILENAME}"><button>Click!</button></a></td>
        </tr>
        """.format(URL=url, STATUS=status, METHOD=method, MIME=mimetype, LENGTH=responselength, FILENAME=fileName)
        IndexFile.write(TableRow) 
        # creating elemnt file 
        FilePath = "files/{}".format(fileName)
        elemFile = open(FilePath, "w")
        path = root[counter][6].text
        extension = root[counter][7].text
        request = (base64.b64decode(root[counter][8].text)).decode('utf-8', 'ignore').replace('<', '&lt;').replace('>', '&gt;')
        responselength = root[counter][10].text
        if root[counter][12].text == None:
            response = "NULL"
        else:
            response = (base64.b64decode(root[counter][12].text)).decode('utf-8', 'ignore').replace('<', '&lt;').replace('>', '&gt;')
        # Writing data to the files 
        ReportBody = """
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Report file</title>
            <style>
        
                table {{
                    border-collapse: collapse;
                    width: 100%;
                }}
        
                th, td {{
                    padding: 8px;
                    text-align: left;
                    border-bottom: 1px solid #ddd;
                }}

                tr:hover {{background-color:#f5f5f5;}}
                td:hover {{font-weight: bold;}}
        
                pre {{
                    background-color: #eee;
                    border: 1px solid #999;
                    display: block;
                    padding: 20px;
                    overflow-x: auto;
                }}
        
            </style>
        </head>
        <body>
            <table>
                <tr><th>URL</th><td>{url}</td></tr>
                <tr><th>Status</th><td>{status}</td</tr>
                <tr><th>Method</th><td>{method}</td</tr>        
                <tr><th>Path</th><td>{path}</td></tr>
                <tr><th>Extension</th><td>{extension}</td></tr>
                <tr><th>MimeType</th><td>{mimetype}</td></tr>
                <tr><th>ResponseLength</th><td>{responselength}</td></tr>
            </table>
            <h3>Reqeust Body :</h3>
            <pre>{request}</pre></td>
            <h3>Response Body :</h3>
            <pre>{response}</pre>

        </body>
        </html>
        """.format(url=url,status=status,method=method,path=path,extension=extension,mimetype=mimetype,responselength=responselength,request=request,response=response) 
        elemFile.write(ReportBody)
        # closing the file
        elemFile.close()
        # increment counter
        counter+=1
        # decrementing item len
        item_len-=1
    IndexFooterBody = """
    </tbody>
    </table>   
    <script>
        $(document).ready( function () {
            $('#MyTable').DataTable({
                "pageLength": 50,
                columnDefs: [
                    {
                        targets: [1,2,3,4,5],
                        className: 'dt-head-left'
                    }
                ]
             });
        } );
    </script>
    </body>
    </html>
    """
    IndexFile.write(IndexFooterBody)
    IndexFile.close()
    print("[+] Downloading Static Files")
    url="https://github.com/Ajaytekam/MyLibraryFiles/raw/main/StaticFiles.zip"
    wget.download(url, ".")
    # extracting files
    with zipfile.ZipFile("StaticFiles.zip", "r") as zip_ref:
        zip_ref.extractall(".")
    os.remove("StaticFiles.zip")
    print("\n[+] Process completed")

if __name__ == "__main__":
    main()
