【邮件安全技术】通过Postfix邮箱服务伪造发件邮箱

在Linux系统安装Postfix,并启动Postfix服务,通过本脚本可伪造域名邮箱发送邮件

import smtplib
import base64
import re
import sys
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.header import Header

# 邮件内容
subject = "测试邮件标题"
body = """你好:
测试邮件
来自于我
2025年2月11日"""

# 发件人和收件人
from_email = "admin@aabbccddee.com"
to_emails = ["用户名@收件域名.org"]
cc_emails = ["用户名@收件域名.org"]  # 抄送地址

# 设置发件人和收件人
sender = "发件人昵称"
sendername = base64.b64encode(sender.encode('utf-8')).decode('utf-8')

# 附件路径
attachment_path = "/root/kun.jpg"

# 创建 MIMEMultipart 对象
msg = MIMEMultipart()
msg['From'] = f'=?utf-8?B?{sendername}?= <{from_email}>'
msg['To'] = ", ".join(to_emails)
msg['Cc'] = ", ".join(cc_emails)  # 添加抄送地址
msg['Subject'] = Header(subject, 'utf-8')

# 添加邮件正文
msg.attach(MIMEText(body, 'plain', 'utf-8'))

# 添加附件
with open(attachment_path, "rb") as attachment_file:
    part = MIMEApplication(attachment_file.read(), Name="kun.jpg")
    part['Content-Disposition'] = 'attachment; filename="kun.jpg"'
    msg.attach(part)

# ------------------- 配置区域 -------------------
POSTFIX_LOG_PATH = '/var/log/mail.log'  # Postfix日志路径(根据服务器调整)
CHECK_INTERVAL = 10  # 检查日志间隔(秒)
TIMEOUT = 300        # 超时时间(秒)

# ------------------- 工具函数 -------------------
def extract_queue_id_from_postfix_log():
    """从 Postfix 日志中提取最新的队列ID"""
    try:
        with open(POSTFIX_LOG_PATH, "r") as log_file:
            lines = log_file.readlines()
            for line in reversed(lines):  # 从后往前读取,找到最新的队列ID
                match = re.search(r"postfix/[^:]+: (\w+):", line)
                if match:
                    return match.group(1)
    except Exception as e:
        print(f"解析 Postfix 日志时发生错误:{e}")
    return None

def check_delivery_status(queue_id):
    """检查Postfix日志中的投递状态,并提取详细信息"""
    status = None
    details = []
    try:
        with open(POSTFIX_LOG_PATH, 'r') as log_file:
            for line in log_file:
                if queue_id in line:
                    if "status=sent" in line:
                        status = "sent"
                        details.append("邮件已成功投递。")
                    elif "status=bounced" in line:
                        status = "bounced"
                        details.append("邮件投递失败(退回):")
                    elif "status=deferred" in line:
                        status = "deferred"
                        details.append("邮件投递延迟:")
                    # 提取详细信息
                    if "status=" in line:
                        details.append(line.strip())
                    # 特别解析 DMARC 错误
                    if "DMARC check failed" in line:
                        details.append("\nDMARC 检查失败,可能的原因:")
                        details.append("- 发件域名的 DMARC 记录未正确配置。")
                        details.append("- SPF 或 DKIM 配置问题。")
                        details.append("- 发件服务器的 IP 地址被目标服务器限制。")
                        details.append("建议参考以下链接解决问题:")
                        details.append("https://open.work.weixin.qq.com/help2/pc/20049")
        return status, "\n".join(details)
    except FileNotFoundError:
        print(f"错误:日志文件 {POSTFIX_LOG_PATH} 不存在")
    return status, ""

# ------------------- 发送并监控 -------------------
try:
    server = smtplib.SMTP('localhost')
    # server.set_debuglevel(1)  # 开启调试模式(可选,用于调试)

    # 发送邮件
    server.sendmail(from_email, to_emails + cc_emails, msg.as_string())
    print("邮件已发送,正在尝试获取队列ID...")

    # 提取队列ID
    queue_id = extract_queue_id_from_postfix_log()
    if queue_id:
        print(f"邮件已入队,队列ID: {queue_id}")
        print("开始监控投递状态...")

        start_time = time.time()
        while time.time() - start_time < TIMEOUT:
            status, details = check_delivery_status(queue_id)
            if status:
                print(f"状态:{status}")
                print("详细信息:")
                print(details)
                break
            time.sleep(CHECK_INTERVAL)
        else:
            print("监控超时,最终状态未确认")
    else:
        print("警告:未能获取队列ID,无法跟踪状态")
except Exception as e:
    print(f"发送邮件时发生错误:{e}")
finally:
    server.quit()

如果不行,那可能需要配置下postfix: update_postfix_config.sh

#!/bin/bash

# 定义需要设置的参数和值
declare -A postfix_params=(
    ["smtpd_sender_restrictions"]="permit_sasl_authenticated, permit_mynetworks, reject_non_fqdn_sender, reject_unauth_destination"
    ["smtpd_recipient_restrictions"]="permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_non_fqdn_recipient"
    ["smtpd_relay_restrictions"]="permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
    ["smtpd_sender_login_maps"]="hash:/etc/postfix/virtual"
    ["mynetworks"]="127.0.0.0/8, 192.168.1.0/24"
)

# Postfix 配置文件路径
POSTFIX_CONFIG="/etc/postfix/main.cf"

# 检查配置文件是否存在
if [[ ! -f "$POSTFIX_CONFIG" ]]; then
    echo "Error: Postfix configuration file $POSTFIX_CONFIG does not exist."
    exit 1
fi

# 遍历参数并更新配置文件
for param in "${!postfix_params[@]}"; do
    value="${postfix_params[$param]}"
    echo "Checking parameter: $param"

    # 检查参数是否已存在
    if grep -q "^$param" "$POSTFIX_CONFIG"; then
        echo "Parameter $param exists. Updating value to: $value"
        # 替换现有参数的值
        sed -i "/^$param/c\\$param = $value" "$POSTFIX_CONFIG"
    else
        echo "Parameter $param does not exist. Adding it with value: $value"
        # 添加新的参数和值
        echo "$param = $value" >>"$POSTFIX_CONFIG"
    fi
done

echo "Postfix configuration updated successfully."

# 重启 Postfix 服务
echo "Restarting Postfix service..."
sudo systemctl restart postfix

# 检查 Postfix 服务状态
if sudo systemctl is-active --quiet postfix; then
    echo "Postfix service restarted successfully."
else
    echo "Error: Failed to restart Postfix service."
    exit 1
fi

chmod +x update_postfix_config.sh

sudo bash ./update_postfix_config.sh

注意,本文仅用于技术交流,所以功能均在“梦中”验证通过,作者不保证任何可用性、不承担任何责任。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值