简介burpFakeIP-master.zip 是一项源自 GitHub 的开源 Burp Suite 插件工程由作者 vanarrow 整理发布面向 Web 安全测试人员、渗透测试工程师、红队成员及高校安全专业学生。它通过 Burp 扩展 API 介入请求流程在报文发出前改写与来源相关的 IP 信息帮助测试者在授权渗透测试、CTF 或安全演练中隐藏真实身份、绕过基于 IP 的访问限制并可模拟多用户、多地域访问场景从而验证服务端 IP 风控策略、提升测试覆盖度。包体共 12 个文件压缩包大小约 1.09MB核心为 Python 扩展脚本另配 9 张界面/配置/效果截图、1 份说明文档和 1 份测试记录文件类型覆盖源码、图片、笔记与日志目录结构清晰便于对照学习和二次开发资源按功能拆分脚本与演示材料可先看截图、再读代码最后按需修改降低上手门槛。目前已有 412 人学习/下载。通过研读该插件读者可以掌握 Burp 扩展 API 调用方式、源 IP 改写逻辑也能基于现有模板继续扩展 IP 轮换、随机伪装、代理联动等功能是学习 Burp 插件开发与网络源地址伪造的实用样本。1. burpFakeIP 是做什么的一个让请求“换 IP 头”的 Burp 扩展做接口测试时经常遇到一个尴尬场景目标后台对某个接口做了 IP 白名单只允许内网段访问直接拿办公网 IP 打过去响应永远是 403。换个思路用代理池成本高、速度慢还经常被风控识别。其实很多系统的“客户端 IP 判断”并不看 TCP 层的真实出口地址而是直接读 HTTP 头里的X-Forwarded-For、X-Real-IP、Client-IP这些字段。burpFakeIP 就是这样一款 Burp Suite 插件它会在请求发出前自动改写或插入伪造 IP 头让后端以为请求来自你指定的地址。适合做越权测试、频率限制绕过、多账号风控策略验证的人不需要额外搭代理解压 zip、加载进 Extender 就能用。这个 github 项目包的思路很简单把“换 IP 头”这个重复动作自动化省掉在 Repeater 里手动改包的体力活。2. 从插件包到请求头burpFakeIP 的工作原理与加载全流程2.1 后端怎么读客户端 IP你的请求头比出口 IP 更值钱很多新手第一反应是“改 IP 头这么简单的事后端会认吗”实际测试里大量内网系统、日志分析平台、接口限流服务确实优先信任X-Forwarded-For。原因很直接业务系统部署在 Nginx/CDN 后面时TCP 层的remote_addr拿到的是反代 IP后端为了获取真实客户端 IP只能依赖反代写入的头部。常见反代写入的头有三个X-Forwarded-For表示一串代理链路X-Real-IP通常只存最左边一个客户端 IPTrue-Client-IP是部分 CDN 透传原始客户端 IP 用的。有的老系统还会读Client-IP和X-Client-IP。这意味着“后端到底取哪个头”是个黑匣子不能想当然。我拿到一个目标时会先做一个最小探针找目标上能回显 IP 的接口比如“获取本机来源 IP”的功能页先不加头打一次记录结果再手动加X-Forwarded-For: 8.8.8.8打一次。如果返回变成了8.8.8.8说明后端是取头的FakeIP 这条路走得通如果完全没反应说明后端看的是 TCP 层连接地址或反代强制覆盖了头部这种场景下换头策略无效得换真实代理或者找内网入口。这个探针步骤花不了两分钟但能避免在错误方向上空跑。2.2 解压与加载BApp 商店搜不到也可以手动装从 github 拿到burpFakeIP-master.zip后第一步是解压看包结构。很多扩展项目会把 Java 源码、Python 源码、构建脚本混在一起不能直接把 zip 扔进 Burp。unzip burpFakeIP-master.zip -d burpFakeIP cd burpFakeIP ls -la正常会看到一个扩展主文件可能是burpFakeIP.py也可能是编译好的burpFakeIP.jar。如果只有 Java 源码目录需要本地用 gradle 或 maven 打包如果有build.gradle最简单的是执行gradle fatJar之类命令。我不建议在没编译的情况下直接把.java文件选进 Burp会直接报 ClassNotFoundException。手动加载步骤很固定Burp Suite 打开Extender - Extensions - Add在弹窗里把Extension Type选成和包对应的语言。Python 版选 PythonJava 版选 Java。文件位置选择刚才解压目录里的主文件不是 README。加载成功后Output标签页会打印类似插件名称和初始化日志。如果什么都不显示就去Errors标签看 traceback。另一个常见问题是扩展用了第三方 Python 库比如requests但 Burp 内置的 Jython 是 2.7 且没有 pip加载直接报ImportError: No module named requests。遇到这种情况优先找不依赖第三方库的版本或者改用 Java 编译版本。2.3 核心配置字段拿到插件先调这四项加载完先别急着开全局开关先把配置面板过一遍。这类插件的配置通常围绕四个维度作用于哪些 Header、用哪种 IP 策略、命中哪些请求、是否覆盖已有值。以我常用的 Jython 版为例面板里大致是这些字段配置项默认值说明总开关关闭开始正式测试再打开避免污染日常浏览流量Header 列表X-Forwarded-For, X-Real-IP, Client-IP需要改写/插入的请求头按序勾选IP 策略randomrandom / fixed / inc 三选一Scope 规则空正则表达式命中才改写写法参考 Burp Target ScopeIP 池1.1.1.1 起fixed 模式轮询inc 模式作为起始地址多值追加关闭开启后保留原 XFF 并在其后面追加模拟链路代理场景插件核心逻辑在processHttpRequest回调里大致是这样一个结构class BurpExtender(IBurpExtender, IHttpListener): def processHttpRequest(self, toolFlag, messageIsRequest, messageInfo): if not messageIsRequest: return request messageInfo.getRequest() analyzed self._helpers.analyzeRequest(request) headers list(analyzed.getHeaders()) headers.insert(1, X-Forwarded-For: self._strategy.next()) messageInfo.setRequest( self._helpers.buildHttpRequest(request, headers) )逻辑说明analyzeRequest返回的headers列表里第 0 项是请求行后面是原始请求头。把伪造的X-Forwarded-For插到第 1 个位置也就是 Host 头前后符合常见反代追加的顺序。buildHttpRequest重建完整请求时只重写头部请求体不变。参数说明messageInfo.setRequest接收的是字节数组不是字符串用helpers转换封装会省掉很多编码问题。不要直接对messageInfo的原生字节做字符串 split容易把 Content-Length 改坏。3. 三种 IP 策略与作用域把 FakeIP 用出代理池的效果3.1 随机 IP默认可用但别踩保留地址随机策略是最常见的默认值每次请求生成一个随机公网 IP。核心生成逻辑不复杂import random class RandomIpStrategy: def next(self): return ..join( str(random.randint(1, 254)) for _ in range(4) )这段代码故意避开了 0、255 和保留段。原因很朴素很多后端会先做 IP 合法性校验把0.0.0.0、255.255.255.255直接判成畸形数据而127.0.0.1、10.x、192.168.x这类内网地址写在 XFF 里会导致访问控制模块解析出“内网来源”可能意外放行。随机模式的适用场景是批量化探测比如爬一个公开数据页或者刷一批不存在图片防盗链的静态资源。风控意识强的目标连续几万个请求带着不同 IP 飘过本身就异常随机 IP 更适合“让日志审计没法按 IP 快速收敛”的场景。随机模式也有缺点它跨请求不连续后端如果做“同一个 IP 短时间内多次请求”的计数随机 IP 恰好能绕开但如果后端对 IP 做了信誉库校验随机到的某些网段可能整体被 WAF 标记反而触发拦截。所以我一般不会把随机模式用在严谨的越权测试上那个更适合固定或递增。3.2 固定 IP 与轮询更新适合模拟单一身份固定模式本质是把一组 IP 放进列表轮询每个请求换下一个 IP 或者随机从池里抽。它的意义是模拟“同一拨客户端从不同 IP 进来”的场景。典型例子一个业务系统按 IP 记录用户登录会话如果换 IP 后原会话还能继续操作说明会话没绑定 IP这种逻辑漏洞用固定 IP 轮询最容易验证。class RotateIpStrategy: def __init__(self, ips): self.ips list(ips) self.index 0 def next(self): ip self.ips[self.index % len(self.ips)] self.index 1 return ip参数说明传入的ips列表会按顺序取出取完一轮回到第一个取模保证不越界。使用上要注意如果目标站限制单 IP 并发固定模式会在同一 IP 上打多个请求反而更容易触发限制想测“IP 维度限流”就换成随机想测“IP 维度鉴权”就用固定。还有一种常见需求是让 XFF 看起来像一个经过多层代理的链路比如X-Forwarded-For: client_ip, proxy1, proxy2。这种多值写法有些插件通过“追加模式”实现开启后保留原有 XFF再在尾部追加新 IP。但要注意后端取链路里哪个值是个玄学有的取最左客户端有的取最右离服务器最近加追错了等于白加。3.3 递增 IP从 1.1.1.1 走到 2.1.1.1白名单逐个测递增策略是我测“IP 白名单绕过”时最常用的。它从起始地址开始每次加 1生成一个连续地址序列。极端情况下可以只买一点代理出口但故意让后端认为请求来自某个连续网段用来确认目标是不是只看前三段。例如目标只允许10.0.0.0/24段访问从10.0.0.1开始逐个加一每个请求换一个尾号很快就能摸清边界。def inc_ip(start, step1): parts list(map(int, start.split(.))) carry step for i in range(3, -1, -1): total parts[i] carry parts[i] total % 256 carry total // 256 return ..join(map(str, parts))逻辑说明从 IPv4 的最低字节开始加碰到进位就把进位传给上一字节。这个写法和十进制的加法进位一致避免每次都把 IP 解析成整数再转回字符串。参数说明step默认 1可以改成 2 或 256 来跳过 C 段起始地址选1.1.1.1时要小心255.255.255.255回绕变成0.0.0.0如果程序没做防回绕后面生成的 IP 会突然变成内网地址。在目标只校验 A 段或 B 段时效果明显比如白名单只看前两段10.0.x.x递增模式下每 255 个请求就能换一个 B 段覆盖面远大于随机。递增模式最关键的限制是作用域。如果开着全局递增你访问自己公司的 OA、Jira 日志也背着同一个伪造 IP容易被运维当成攻击流量。因此递增强度不要拉太高建议配合下面说的 Scope 正则只在目标域名上生效。3.4 作用域白名单与 Header 过滤别污染无关流量作用域是这类插件最容易被忽略的部分。插件默认可能只在启用后对所有出站请求生效而一个正常的 Burp 会同时代理浏览器、其他扩展的流量、甚至更新检查。把自己的登录请求也改成随机 IP后端 session 绑定 IP 的话会立刻掉线这是最常见的翻车现场。配置 Scope 时我会写成完整的正则避免光写域名导致子域误伤。比如只针对api.test.com下的接口限流路径^https?://api\.test\.com/api/ip-limited/.*如果插件面板支持 Burp 的 Target Scope 联动那就在 Burp Target 里维护Include和Exclude插件只对In scope请求生效。Header 过滤同样重要默认列表里有 4 到 5 个常见 IP 头如果业务系统自己定义了X-Debug-Client-IP不一定需要改。原则上只保留目标真正读取的那一个多写只会增加日志审计的噪音。有些系统会同时校验X-Forwarded-For和X-Real-IP是否一致不一致就拒绝。遇到这种目标勾选多个头反而坏事不如只留一个让后端短路过不了强校验。4. 避坑与排查四个翻车现场4.1 现象后台回显的还是真实出口 IP这个坑我掉进去过好几次。现象是你开了 FakeIPRepeater 里也看到了伪造头但目标后台的操作日志、接口回显里的 IP 仍然是办公网出口。为什么先看链路Burp 只是修改了从 Burp 发往目标服务器的 HTTP 请求但这个请求可能要经过系统代理、CDN、Nginx 多层。比如 Nginx 配置了real_ip_header X-Real-IP并且用real_ip_recursive off它会用上一层连接的真实来源覆盖X-Real-IP你改的那个值在到达业务应用之前就被替换。CDN 也类似很多 CDN 默认忽略客户端传的 XFF用边缘节点和用户建连的真实地址生成自己的 XFF。解决思路不是硬加大力度伪造而是先绕过链路。我会用 curl 直连源站 IP 加 Host 头访问看能不能绕过 CDN如果能就在本地 hosts 把域名临时指向源站再让 Burp 带着 FakeIP 打过去这样后端拿到的就是插件改出来的头。另一个隐蔽原因是后端取 XFF 最右侧的地址。如果你只插入一个伪造值链路中的代理又在尾部追加了真实 IP后端按最右取就会失败。这种情况建议在插件里开启“覆盖模式”而不是“追加模式”并且让 Burp 作为唯一的代理出口。4.2 现象明明只是换头WAF 却把我拦了有次我开着随机 IP 打一个接口流量一上去就被 WAF 拦成一片响应头里出现安全厂商的标准拦截页。第一反应以为是频率问题后来把请求体拿下来单发发现只要把X-Forwarded-For设成1.2.3.4就能通过换成一个随机大网段就 403。这背后通常是 WAF 做了两层校验一层是格式校验非 IP 字符直接丢另一层是信誉库把某些云机房段、代理段整体标记为高风险。随机生成 IP 有一个隐藏风险就是可能生成到目标内部网段或已知恶意地址附近。解决方法是先小流量测试把随机段限制到一个可控范围。比如只生成101.0.0.0到122.255.255.255这段常见运营商 IP而不是全 32 位空间乱跳。插件如果支持配置 IP 前缀就把前三段固定只随机最后一段。另一个更隐蔽的坑是伪造头里带了特殊字符。有人为了绕过 WAF 会写X-Forwarded-For: 1.2.3.4, 127.0.0.1 OR 11这种奇怪拼接在一些老系统里可能造成 SQL 注入但现在的 WAF 基本都会先拦掉这种畸形头。所以插件生成的值必须保证是纯数字加三个点的 IP 格式不要混入其他字符串。4.3 现象BApp 商店搜不到、Extender 加载报错有的用户找插件直接去 BApp 商店搜搜不到就以为没有。其实不少 github 项目没有提交到 BApp 商店或者商店里版本很旧master 分支才是最新代码。搜不到不是问题手动加载一样能用。加载报错的坑主要集中在两个地方第一zip 解压后多了一层目录Burp 加载时选了外层的 README 或者项目说明文件第二Jython 版本太老Python 扩展里用了 f-string、from urllib.request import urlopen这类 Python 3 语法直接报SyntaxError。排查手法很固定先看Extender - Extensions - Errors标签里面是完整堆栈再看Output标签确认插件是否初始化。遇到ImportError先确认扩展是否依赖第三方包。burpFakeIP 这种小工具通常写成了零依赖纯标准库如果一个包写了import requests在 Jython 里解决依赖很麻烦建议直接换实现。还有个容易忽略的问题扩展文件路径不能带中文和空格。某次我把 zip 解压到桌面“新建文件夹”加载时 Burp 报找不到文件把目录改成纯英文后一次就过。4.4 现象加完头接口开始报签名错误这类场景多见于有网关统一鉴权的业务系统。网关会对请求的部分头做签名校验或者把X-Forwarded-For、User-Agent、Authorization一起拼进签名原文。你只改了 IP 头签名没重新算后端验签失败。这种问题不是插件 bug而是数据完整性被破坏了。解决方法是把目标域名加进插件的排除名单只针对真正需要测试的接口开启如果做不到接口级控制就先关掉插件用正常的请求头确认接口本身逻辑正常。更麻烦的一种是后端把头部写进了分布式链路追踪 ID。改掉 IP 头后链路追踪系统把新 IP 作为唯一标识导致日志里之前排到的问题查不到了。这种情况我一般建议在测试环境操作或者保留一份原始请求的镜像。另一个容易让人误判的是接口返回的 IP 不是业务应用解析的而是网关日志模块直接透传的。比如返回体里的clientIp是网关解析的和业务授权逻辑用的 IP 不是同一个来源。这时改 IP 头影响了日志字段但授权逻辑没变看起来就像“头失效了”。所以排查签名问题时不要只看响应体要抓完整的请求链路和网关注入的头。5. 进阶技巧和 Repeater、Session 规则联动顺便验证头有没有生效5.1 Repeater 里快速切换 IP 模式FakeIP 的配置面板一般只提供全局模式切换。想在 Repeater 里针对单个请求临时换策略我通常开两个 Burp Tab一个加载随机模式一个加载递增模式或者直接利用插件的 Scope 区分域名。Repeater 不比命令行的代理池它强在手工构造请求配合 FakeIP 时重点看“修改后的响应差异”而不是高并发。比如改一次 IP 后响应从 403 变成了 200这比盲目猜一个固定 IP 高效很多。5.2 Session 规则配合宏自动打频率限制更自动化的玩法是配合 Session Handling Rules。你可以定义一个宏宏的请求先访问一次目标接口把当前 IP 配额拿回来然后用 Session 规则调用 FakeIP 的下一个 IP再发送实际请求循环直到出现预期状态码。这个玩法本质是把“改头 看响应”变成循环适合验证“单 IP 限制 N 次”的后端逻辑。注意不要开太快否则即使 IP 不同也可能触发更上层的账号维度风控。实现伪代码思路是for i in range(1, 100): inc_ip(10.0.0. str(i), 1) resp send_with_burp() if resp.status 200: break逻辑说明这里不是让插件控制循环而是在测试脚本里调用递增策略生成每次请求的 IP再交给 Burp 发送。参数说明inc_ip的 step 可以配合目标网段宽度调整如果目标是按 C 段限流就 step256 跨段走。5.3 最笨但最有效的验证看后台操作日志验证 FakeIP 有没有真正被后端识别最好的方法不是看响应头而是找一个能记录来源 IP 的后台功能登录一次然后去后台的“操作日志”“登录日志”里看记录的 IP。记录里显示的是伪造 IP就说明从接入到应用层整条链路都认了新头显示的还是原 IP就说明中间某一层强制覆盖了。这个验证方式简单直接比依赖返回字段里的clientIp可靠得多。从那以后我每次拿新目标测试前都强制走一遍流程先探后端取哪个头再设最小 Header 白名单最后小流量验证确认后台日志里头生效了才上量。这条流程看起来平平无奇但真的帮我躲过了不少“改了半天其实没生效”的无用功。希望帮到你。本文还有配套的精品资源点击获取