☰
Python 写 POC 入门,批量验证漏洞脚本
2026/10/8 0:44:48 网站建设 项目流程

Python 写 POC 入门,批量验证漏洞脚本实战

前言

在漏洞挖掘、SRC 提交、红蓝对抗、安全巡检工作中,POC(Proof of Concept,概念验证脚本)是安全从业者的必备工具。POC 的核心作用:验证目标是否存在某一个漏洞,输出是否可利用,不会像 EXP 那样直接造成破坏。很多新手一开始分不清 POC 和 EXP,上来就写可以拿服务器权限的 EXP 脚本,很容易踩法律红线。

一句话区分:POC = 检测漏洞是否存在;EXP = 利用漏洞实现攻击、执行命令、获取权限。学习漏洞验证,优先写 POC,严禁在未授权目标执行 EXP。

网上很多零散的 POC 代码,要么缺少注释,要么没有批量功能,异常处理简陋,遇到超时、连接失败、编码错误直接程序崩溃。本文面向零基础 Python 安全学习者,手把手讲解 POC 编写思路、基础语法、单个目标 POC 开发,再扩展批量多目标验证、结果导出、异常捕获、命令行传参,同时讲解代码规范、踩坑点、法律边界。
读完本篇,你能够独立写出结构完整、支持批量检测、结果保存的漏洞 POC 模板,后续遇到各类 Web 漏洞都可以基于这个模板快速改造。

⚠️免责声明:本文所有代码仅用于本地靶场、自己授权环境学习测试。未经目标系统所有者书面授权,禁止使用脚本扫描、探测互联网上任何网站、服务器。私自对未授权资产进行漏洞探测、扫描,违反《网络安全法》,一切违规行为由使用者自行承担法律责任。

一、POC 开发前置知识准备

1.1 需要掌握的 Python 基础

写 Web 类漏洞 POC,不需要精通 Python 全栈,掌握下面基础就足够:

  1. requests 库:发送 HTTP 请求(GET、POST,设置请求头、Cookie、POST 数据),是 Web POC 最核心库;
  2. 字符串判断:if "特征字符串" in response.text,通过页面返回内容判断漏洞是否存在;
  3. 异常捕获try except:处理网络超时、连接拒绝、DNS 解析失败;
  4. 文件读写:读取目标列表、输出检测结果到 txt/csv;
  5. 命令行参数argparse:运行脚本时从外部传入参数,不用每次修改源码。

1.2 环境安装

Python3 是必备,推荐 3.8 及以上版本。
安装 requests 库:

pip install requests

重要提示:尽量不要使用 Python2,Python2 早已停止维护,现在 SRC、安全工具全部基于 Python3。

1.3 POC 编写的设计原则(写代码前一定要记住)

  1. 最小影响原则:POC 只做检测,不要执行删除文件、读取敏感数据、写入 Webshell 等破坏性动作;
  2. 低误报:不能只靠状态码判断,尽量使用页面返回的唯一特征字符串做判断;
  3. 健壮性:网络不稳定、目标端口关闭、HTTPS 证书报错、超时,脚本不能直接崩溃;
  4. 可扩展:单个目标函数和批量逻辑分离,方便修改适配不同漏洞;
  5. 输出清晰:区分【存在漏洞】【不存在漏洞】【访问异常】三种结果。

1.4 POC 与 EXP、扫描器的区别

  • POC:验证漏洞是否存在,轻量,无破坏性;
  • EXP:漏洞利用,执行命令、获取权限,风险极高;
  • 漏洞扫描器:大量规则,并发请求,适合资产批量巡检,底层原理就是大量 POC 集合。

二、第一个简单 POC:单个目标漏洞验证(示例:简单 SQL 注入检测演示)

仅作为教学演示逻辑,不是通用 SQL 注入工具。真实场景不能只靠简单字符判断。

漏洞场景假设:网站参数id存在 SQL 注入,当传入id=1'页面返回MySQL数据库报错信息,以此作为判断特征。
我们写一个函数poc_check(url),接收目标 URL,返回检测结果。

import requests def poc_check(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } payload = "?id=1'" vuln_url = target_url + payload try: # 关闭证书校验,设置超时5秒,防止卡死 resp = requests.get(vuln_url, headers=headers, verify=False, timeout=5) resp_text = resp.text # 判断页面是否包含数据库报错特征 if "MySQL" in resp_text or "You have an error in your SQL syntax" in resp_text: return True, f"【存在漏洞】 {vuln_url}" else: return False, f"【无漏洞】 {vuln_url}" except requests.exceptions.Timeout: return False, f"【访问超时】 {vuln_url}" except requests.exceptions.ConnectionError: return False, f"【连接失败,无法访问】 {vuln_url}" except Exception as e: return False, f"【未知异常】{vuln_url} 错误信息:{str(e)}" if __name__ == "__main__": # 填写自己靶场地址 target = "http://127.0.0.1/sqli" result, msg = poc_check(target) print(msg)

代码逐段解析

  1. headers:模拟浏览器 UA,很多网站会拦截默认 requests 的 UA;
  2. verify=False:忽略 HTTPS 证书警告,自测常用;生产正规 POC 可以去掉;
  3. timeout=5:5 秒没有响应直接抛出超时,防止脚本卡死;
  4. try except 捕获网络异常:超时、连接拒绝、DNS 解析失败,单独分类返回信息;
  5. 返回两个值:布尔值(是否存在漏洞) + 消息文本,方便后续批量脚本调用。

运行脚本,就可以对单个靶场地址进行检测。

重点:漏洞判定的特征字符串,一定要找漏洞触发之后才会出现的独有特征,通用页面文字不能作为判断依据,否则产生大量误报。

三、升级:批量 POC 脚本,读取目标列表批量检测

实际安全巡检场景,不可能一个一个手动输入目标,一般会把所有目标放到target.txt,一行一个 URL,循环读取并调用 poc_check 函数。

target.txt 示例内容:

http://127.0.0.1/sqli http://127.0.0.1/test http://192.168.1.100

完整批量代码:

import requests # 关闭requests的HTTPS证书告警 requests.packages.urllib3.disable_warnings() def poc_check(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } payload = "?id=1'" vuln_url = target_url + payload try: resp = requests.get(vuln_url, headers=headers, verify=False, timeout=5) resp_text = resp.text if "MySQL" in resp_text or "You have an error in your SQL syntax" in resp_text: return True, f"【存在漏洞】 {vuln_url}" else: return False, f"【无漏洞】 {vuln_url}" except requests.exceptions.Timeout: return False, f"【访问超时】 {vuln_url}" except requests.exceptions.ConnectionError: return False, f"【连接失败】 {vuln_url}" except Exception as e: return False, f"【未知异常】{vuln_url} 错误:{str(e)}" def batch_scan(file_path): # 保存存在漏洞的结果 vuln_result = [] try: with open(file_path, "r", encoding="utf-8") as f: lines = f.readlines() for line in lines: target = line.strip() # 跳过空行 if not target: continue print(f"正在检测:{target}") is_vuln, msg = poc_check(target) print(msg) if is_vuln: vuln_result.append(msg) # 将存在漏洞的目标写入vuln.txt with open("vuln.txt", "w", encoding="utf-8") as out_f: for item in vuln_result: out_f.write(item + "\n") print("\n=====扫描完成,存在漏洞的结果已保存至 vuln.txt=====") except FileNotFoundError: print(f"错误:文件 {file_path} 不存在!") if __name__ == "__main__": batch_scan("target.txt")

批量脚本逻辑讲解

  1. 读取 target.txt,循环每一行,strip 去除换行、空格;
  2. 调用 poc_check,打印实时检测信息;
  3. 如果判断存在漏洞,存入列表;
  4. 全部扫描结束,将所有漏洞目标写入vuln.txt,方便后续 SRC 提交、复盘;
  5. 捕获文件不存在异常,防止脚本直接崩溃。

运行命令:

python poc_batch.py

当前版本是串行单线程,逐个请求。目标数量大的时候速度很慢。后面会讲解多线程优化方案。

四、进阶优化:命令行传参,灵活指定目标文件

使用 argparse 实现命令行传参,不用每次打开源码修改文件名,更加专业,符合开源 POC 的习惯。

import requests import argparse requests.packages.urllib3.disable_warnings() def poc_check(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } payload = "?id=1'" vuln_url = target_url + payload try: resp = requests.get(vuln_url, headers=headers, verify=False, timeout=5) resp_text = resp.text if "MySQL" in resp_text or "You have an error in your SQL syntax" in resp_text: return True, f"【存在漏洞】 {vuln_url}" else: return False, f"【无漏洞】 {vuln_url}" except requests.exceptions.Timeout: return False, f"【访问超时】 {vuln_url}" except requests.exceptions.ConnectionError: return False, f"【连接失败】 {vuln_url}" except Exception as e: return False, f"【未知异常】{vuln_url} 错误:{str(e)}" def batch_scan(file_path): vuln_result = [] try: with open(file_path, "r", encoding="utf-8") as f: lines = f.readlines() for line in lines: target = line.strip() if not target: continue print(f"正在检测:{target}") is_vuln, msg = poc_check(target) print(msg) if is_vuln: vuln_result.append(msg) with open("vuln.txt", "w", encoding="utf-8") as out_f: for item in vuln_result: out_f.write(item + "\n") print("\n=====扫描完成,结果保存 vuln.txt=====") except FileNotFoundError: print(f"文件 {file_path} 不存在!") if __name__ == "__main__": parser = argparse.ArgumentParser(description="漏洞POC批量检测脚本") parser.add_argument("-f", "--file", help="目标URL列表文件,例如 target.txt", required=True) args = parser.parse_args() batch_scan(args.file)

使用方式:

python poc_batch.py -f target.txt

五、多线程加速批量扫描(重点实战)

串行扫描几百个目标速度非常慢,使用concurrent.futures.ThreadPoolExecutor实现多线程并发请求。

注意:线程数不要设置太大,推荐 10~30,线程过多容易触发目标 WAF 封禁 IP,也容易产生大量网络异常。

import requests import argparse from concurrent.futures import ThreadPoolExecutor, as_completed requests.packages.urllib3.disable_warnings() def poc_check(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } payload = "?id=1'" vuln_url = target_url + payload try: resp = requests.get(vuln_url, headers=headers, verify=False, timeout=5) resp_text = resp.text if "MySQL" in resp_text or "You have an error in your SQL syntax" in resp_text: return True, f"【存在漏洞】 {vuln_url}" else: return False, f"【无漏洞】 {vuln_url}" except requests.exceptions.Timeout: return False, f"【访问超时】 {vuln_url}" except requests.exceptions.ConnectionError: return False, f"【连接失败】 {vuln_url}" except Exception as e: return False, f"【未知异常】{vuln_url} 错误:{str(e)}" def task(target): is_vuln, msg = poc_check(target) print(msg) return is_vuln, msg def batch_thread_scan(file_path, thread_num=15): targets = [] vuln_result = [] try: with open(file_path, "r", encoding="utf-8") as f: for line in f.readlines(): line = line.strip() if line: targets.append(line) print(f"共加载目标数量:{len(targets)},开始多线程扫描,线程数:{thread_num}") with ThreadPoolExecutor(max_workers=thread_num) as executor: future_list = [executor.submit(task, t) for t in targets] for future in as_completed(future_list): is_vuln, msg = future.result() if is_vuln: vuln_result.append(msg) with open("vuln.txt", "w", encoding="utf-8") as f: for item in vuln_result: f.write(item + "\n") print("\n=====全部任务执行完毕,漏洞目标保存 vuln.txt=====") except FileNotFoundError: print(f"文件 {file_path} 不存在!") if __name__ == "__main__": parser = argparse.ArgumentParser(description="多线程POC批量漏洞验证脚本") parser.add_argument("-f", "--file", help="目标列表文件", required=True) parser.add_argument("-t", "--thread", help="线程数量,默认15", type=int, default=15) args = parser.parse_args() batch_thread_scan(args.file, args.thread)

运行示例,指定 20 线程:

python poc_batch.py -f target.txt -t 20

多线程使用注意事项

  1. 线程不是越大越快,太高容易被 WAF 拉黑本机 IP;
  2. 网络请求属于 IO 密集型任务,多线程非常适合 POC 场景;
  3. 不建议加代理池、超高并发用于互联网无差别扫描。

六、POC 编写通用模板,适配各种 Web 漏洞

上面的代码可以作为通用模板,更换下面两处即可快速改成其他漏洞 POC:

  1. 修改请求方式:GET 改为 POST,添加 POST 的 data/json;
  2. 修改 payload 和判断特征字符串。

示例:POST 请求漏洞修改示例片段

def poc_check(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Content-Type": "application/x-www-form-urlencoded" } post_data = {"username":"admin","password":"123456"} try: resp = requests.post(target_url, data=post_data, headers=headers, verify=False, timeout=5) if "欢迎管理员" in resp.text: return True, "存在漏洞" except Exception as e: return False, str(e)

如果漏洞是 JSON 提交:使用json={}代替data。

七、POC 开发常见踩坑(新手高频问题)

坑 1:只依靠 HTTP 状态码判断漏洞

if resp.status_code == 200就判定存在漏洞,误报率极高。200 只是页面正常返回,不能证明漏洞存在。优先页面返回特征文本。

坑 2:不设置 timeout,脚本卡死

目标服务器无响应,requests 会永久阻塞,整个脚本停住,所有 POC 必须加上 timeout。

坑 3:忽略 URL 末尾斜杠问题

目标http://xxx.com和http://xxx.com/,拼接 payload 很容易变成http://xxx.com?id=1',缺少斜杠导致请求地址错误。可以在代码里做 URL 预处理,自动处理末尾/。

坑 4:UA 固定不变,短时间大量请求被 WAF 拦截

批量扫描大量目标时,WAF 识别高频相同 UA 直接拦截,可以准备 UA 列表随机选择。

坑 5:没有异常捕获,遇到一个异常目标整个程序崩溃

没有 try except,遇到一个无法访问网站,程序直接终止,前面扫描结果丢失。

坑 6:直接复制网上 POC 不审计代码

网上很多开源 POC 暗藏恶意代码,运行前逐行阅读代码,理解每一行作用。

坑 7:把 POC 拿来扫公网大量站点

就算只是漏洞验证,未授权批量扫描公网资产属于违规行为。POC 仅限自己搭建的 DVWA、WebGoat 等本地靶场。

八、POC 提交 SRC 的规范

当你挖到漏洞提交 SRC 时,配套 POC 有规范:

  1. 代码简洁,带详细注释;
  2. 只能验证漏洞,不能执行命令、下载文件;
  3. 提供复现步骤、请求包截图;
  4. 说明影响版本、漏洞特征;
  5. 附带 poc 运行输出结果。

SRC 平台审核人员会运行你的 POC 复现漏洞,如果 POC 破坏性强,会直接驳回,严重情况会上报。

九、拓展学习方向

  1. 学习 burp 导出请求包转 Python requests 代码,快速生成 POC 请求;
  2. 学习处理 JSON 响应,resp.json()解析接口返回数据;
  3. 学习代理配置,POC 流量走 Burp 抓包调试;
proxies = { "http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080" } resp = requests.get(url,proxies=proxies,verify=False)
  1. 学习导出 CSV 格式扫描结果,方便 Excel 查看;
  2. 学习异步 aiohttp,更高并发 IO 扫描;
  3. 学习框架:pocsuite3,是国内安全圈主流 POC 框架,标准化管理大量 POC。

总结

Python 写 POC 的核心逻辑:构造漏洞请求 payload,发送 HTTP 数据包,根据页面返回特征判断漏洞,增加异常处理,扩展批量、多线程能力。
POC 的本质是自动化复现漏洞检测流程,不是攻击工具。新手入门最关键的习惯:守住法律边界,只在自己搭建靶场测试,写代码坚持 POC 最小影响原则。

不要一上来就追求复杂 EXP,把基础 POC 模板练熟,学会修改 payload、判断特征、处理网络异常,后续遇到任意 Web 漏洞,都可以快速编写验证脚本。POC 编写能力,是漏洞挖掘、SRC、红蓝对抗岗位的基础技能。


最后

关于网络安全技术储备

网络安全是当今信息时代中非常重要的一环。无论是找工作还是感兴趣(黑客),都是未来职业选择中上上之选,为了保护自己的网络安全,学习网络安全知识是必不可少的。

如果你是准备学习网络安全(黑客)或者正在学习,下面这些你应该能用得上:

①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源
⑨历年CTF夺旗赛题解析

一、网络安全(黑客)学习路线

网络安全(黑客)学习路线,形成网络安全领域所有的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、网络安全教程视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

三、网络安全CTF实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这里带来的是CTF&SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

四、网络安全面试题

最后,我们所有的作为都是为就业服务的,所以关键的临门一脚就是咱们的面试题内容,所以面试题板块是咱们不可或缺的部分,这里我给大家准备的就是我在面试期间准备的资料。

网安其实不难,难的是坚持和相信自己,我的经验是既然已经选定网安你就要相信它,相信它能成为你日后进阶的高效渠道,这样自己才会更有信念去学习,才能在碰到困难的时候坚持下去。

机会属于有准备的人,这是一个实力的时代。人和人之间的差距不在于智商,而在于如何利用业余时间,只要你想学习,什么时候开始都不晚,不要担心这担心那,你只需努力,剩下的交给时间!

这份完整版的网络安全学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询