背景
笔者从去年6月份开始研究IP地址,陆续踩了很多很多坑,也结识了一大批同行业的前辈。
我能说我是这个圈子里年龄最小的么…..我一直在承受我这个年纪不该有的智慧和经历。
关于IP地址的研究,此前我写过一个完整的系列,先后被未央网、雷锋网和先知社区转载。如果你想看的话,可以戳这里:反欺诈专栏
我们首次建模完成之后,迫不及待地让同事帮忙把数据提取出来,进行人工审核评估,却发现结果中有很多很多保留IP,心里哇凉哇凉的。每次和客户对接,我都花很长的时间跟对方的技术人员解释如何正确地获取来源IP地址,但是每家公司的情况都有所差别,没有一个标准方法。也有一些公司,由于相关的代码已经存在了很久,没有人维护,而业务系统的架构已经变更了多次,原有的代码,获取出来的IP都是错的。
想象一下,每天都有人在问你:127.0.0.1这个IP是啥?这个IP怎么发了那么多请求?这是不是个基站?还是服务器IP?难不成是代理?还是我们被攻击了?诶你说话啊?
关于保留IP
下面是从维基百科上摘录的保留IP地址段,共计16个(最后两个段一般会合并,也可以认为是15个)。
原文地址:https://en.wikipedia.org/wiki/Reserved_IP_addresses
保留地址段 | 地址起始 | IP地址数量 | 用途 |
---|---|---|---|
0.0.0.0/8 | 0.0.0.0 – 0.255.255.255 | 16,777,216 | 软件 |
10.0.0.0/8 | 10.0.0.0 – 10.255.255.255 | 16,777,216 | 内网 |
100.64.0.0/10 | 100.64.0.0 – 100.127.255.255 | 4,194,304 | 内网 |
127.0.0.0/8 | 127.0.0.0 – 127.255.255.255 | 16,777,216 | 主机(本机) |
169.254.0.0/16 | 169.254.0.0 – 169.254.255.255 | 65,536 | 本地子网(DHCP Failed) |
172.16.0.0/12 | 172.16.0.0 – 172.31.255.255 | 1,048,576 | 内网 |
192.0.0.0/24 | 192.0.0.0 – 192.0.0.255 | 256 | 内网 |
192.0.2.0/24 | 192.0.2.0 – 192.0.2.255 | 256 | “TEST-NET” |
192.88.99.0/24 | 192.88.99.0 – 192.88.99.255 | 256 | 6to4 anycast |
192.168.0.0/16 | 192.168.0.0 – 192.168.255.255 | 65,536 | 内网 |
198.18.0.0/15 | 198.18.0.0 – 198.19.255.255 | 131,072 | 内网 |
198.51.100.0/24 | 198.51.100.0 – 198.51.100.255 | 256 | “TEST-NET-2″ |
203.0.113.0/24 | 203.0.113.0 – 203.0.113.255 | 256 | “TEST-NET-3″ |
224.0.0.0/4 | 224.0.0.0 – 239.255.255.255 | 268,435,455 | 预留 |
240.0.0.0/4 | 240.0.0.0 – 255.255.255.254 | 268,435,455 | 预留 |
255.255.255.255/32 | 255.255.255.255 | 1 | 广播 |
我经常拿这个问题去刁难人,能说出三个段的人,至少是具备网络基础知识的,说出5个以上的,一般我会请他喝酒。
连保留IP是啥都不知道的,我就得尝试用另外一种方式去跟他解释这个问题了。
保留IP可以说是TCP/IP协议的约定吧,每一个段都有相应的使用说明,都有与之对应的RFC文档。
比如,中国境内,移动设备在 4G 环境下获取到的内网IP,一般是 10.0.0.0/8 或者 100.64.0.0/10 的。
非物理隔离的网络系统,一般会是用 192.168.0.0/16,172.16.0.0/12,10.0.0.0/8 内划分内网地址,比较常见。
据@高春辉说,除了这些之外,还有一些很小的保留 IP 段,如果不详细去看完整的 whois 数据,可能都不会发现。
聊聊XFF
X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。 Squid缓存代理服务器的开发人员最早引入了这一HTTP头字段,并由IETF在HTTP头字段标准化草案中正式提出。
XFF的工作机制是,每经过一层代理,由代理服务器,把tcp报文中的Source IP,添加到XFF的末尾,多个IP以逗号分隔。这里说的代理是广义的,包括负载均衡(比如阿里云SLB),反向代理(比如Nginx),缓存服务器(比如Squid)。
一方面,XFF提供了向后端业务系统传递用户IP的机制,后端业务系统,可以通过XFF感知到访问者的真实IP。
另一方面,XFF非常易于伪造。很多浏览器插件,可以随机填充XFF字段,如果没有一套正确的机制来处理XFF字段,而盲目地提取XFF中第一个IP作为访问者的IP,就一定会出问题。
前面提到了,来源IP是保留IP的情况,其实大多数是由于业务系统直接以TCP报文中的remote address作为来源IP使用了。而这个IP,一般是企业自己的反向代理服务器。
除此之外,XFF伪造的过程中,IP地址是随机生成的,可能会出线保留IP,非法IP,有少数情况可能会出现“未启用IP”,也就是说这个IP已经分配给特定的运营商,但是运营商还没有添加这个IP的路由,这个IP无法被外界访问,也不会访问任何人。
这些IP是动态变化的,据老高说,只有分析BGP数据的时候,才能看到哪些IP是没有被启用的。
业务系统获取来源IP的正确姿势
下面是一个简单的示意图,简单地把整个访问链路划分成可信区域和不可信区域。
可信区域,就是平台自己,或者友商建立的系统,可以保证从这些系统中获取并传递的数据是真实的、可信的。
获取来源IP的正确方式,是提取并记录本次请求首次进入可信区域时的remote address。不论这个IP是不是代理。
XFF伪造的情况其实非常普遍,也陆续地出现了一些替代方案,我司目前使用的,是设置一个专用的字段来传递这个IP,不会和XFF相覆盖。
此外,某些CDN服务商,会有自己定制化的Header字段,情况比较多,建议结合具体的情况来决定如何获取用户的来源IP。
比如,之前遇到一个客户,使用了阿里云的SLB负载均衡,SLB会给每一个请求都加上X-Forwarded-For字段,他们自己的反向代理又加一次。那么其实只要获取XFF中倒数第三个IP,作为来源IP即可。
一种参考方式如下:
在反向代理(Nginx)上配置,增加Real-IP字段:
location /{ ... proxy_set_header Real-IP $remote_addr; ...}
业务系统中,获取来源IP的代码如下(Java示例):
@SuppressWarnings("unchecked") public static ClientIps getClientIpAddr(HttpServletRequest request) { // 获取真实ip String ip = request.getHeader("real-ip"); if (StringUtils.isBlank(ip) || ("unknown".equalsIgnoreCase(ip.trim()))) {
ip = request.getHeader("remote-host");
} if (StringUtils.isBlank(ip) || ("unknown".equalsIgnoreCase(ip.trim()))) {
ip = request.getRemoteAddr();
}
ClientIps clientIps = new ClientIps();
clientIps.setTrueIp(StringUtils.trimToEmpty(ip)); // 获取代理ip ip = request.getHeader("x-forwarded-for");
StringBuilder proxyIps = new StringBuilder(); if (StringUtils.isNotBlank(ip) && (StringUtils.contains(ip, ","))) {
String temp = StringUtils.substringBeforeLast(ip, ","); if (StringUtils.isNotBlank(temp)) {
proxyIps.append("x-forwarded-for:");
proxyIps.append(temp);
proxyIps.append("\n");
}
}
这个问题实在是简单到爆炸,懂技术的同学看到,肯定会喷我,居然写这种没水平的文章。
但是呢,作为一个数据分析师,看着每天系统里辣么多保留IP,非法IP传进来,真的很憋屈。体谅下咯~
而且,每每看别人说攻击溯源….我满脑子想的都是:你连获取到的IP是不是真的你都不知道,你在追溯个啥?
By the way,欢迎有兴趣深入研究IP地址的童鞋一起交流,没准能带你跟老高一块儿喝羊汤。
- 上一篇:一款短小精致的SSH后门分析
- 下一篇:跟着DVWA学Web安全开发
猜你还喜欢
- 07-08八年专业安全团队承接渗透入侵维护服务
- 08-06SQLMAP的注入命令以及使用方法
- 08-03白帽故事汇:网络安全战士从来不是「男生」的专利
- 07-27编辑器漏洞手册
- 07-12web安全之如何全面发现系统后台
- 02-22常见Web源码泄露总结
- 07-25网站后台登陆万能密码
- 07-23破解emlog收费模板“Begin”
- 01-12批量检测SQL注入
- 01-22Apache Solr远程代码执行漏洞(CVE-2017-12629)从利用到入侵检测
- 随机文章
-
- Syborg:一款带有断路躲避系统的DNS子域名递归枚举工具
- JMX远程代码漏洞研究
- 玩家与黑客:对游戏公司和游戏玩家的网络威胁
- 网络犯罪天堂Deer.io之死
- PrivescCheck:一款针对Windows系统的提权枚举脚本
- 实战黑客入侵网站教程轻松拿下1000个网站
- 实战案例:精准入侵号码交易网与黑客远程定位
- 文件解压引发的Getshell
- 如何解密AWVS?15行代码就够了!
- NSA披露Web Shell漏洞列表,警惕黑客部署后门
- 入侵中国长达3个月,越南黑客组织欲窃取新冠肺炎情报
- xShock:一款针对Shellshock漏洞的利用工具
- uDork:一款功能强大的Google Hacking工具
- Metaspolit下配合Ngrok同时实现内网反弹+转发
- 黑客有哪几种类型?(10类黑客的介绍)
- 进攻即是最好的防御!19个练习黑客技术的在线网站
- 2019年最受欢迎的20款黑客工具
- 通过代码重用攻击绕过现代XSS防御
- GitHound:一款针对GitHub的API密钥和敏感数据搜索工具
- 手把手用C++解密Chrome80版本数据库
- 热门文章
-
- 八年专业安全团队承接渗透入侵维护服务
- Emlog黑客站模板“Milw0rm”发布
- Stuxnet纪录片-零日 Zero.Days (2016)【中文字幕】
- SQLMAP的注入命令以及使用方法
- 白帽故事汇:网络安全战士从来不是「男生」的专利
- 编辑器漏洞手册
- web安全之如何全面发现系统后台
- 常见Web源码泄露总结
- 渗透测试培训(第五期)
- 深入理解JAVA反序列化漏洞
- cmseasy前台无需登录直接获取敏感数据的SQL注入(有POC证明)
- 网站后台登陆万能密码
- 黑麒麟2016渗透培训系列教程
- 破解emlog收费模板“Begin”
- 那些强悍的PHP一句话后门
- Android平台渗透测试套件zANTI v2.5发布(含详细说明)
- 渗透工具BackTrack与KaliLinux全套视频教程
- Python列为黑客应该学的四种编程语言之一 初学者该怎么学
- CVE-2017-11882漏洞复现和利用
- 恶意程序报告在线查询工具
文章存档
- 2021年3月(4)
- 2020年12月(4)
- 2020年11月(5)
- 2020年10月(8)
- 2020年9月(8)
- 2020年8月(20)
- 2020年7月(47)
- 2020年6月(70)
- 2020年5月(41)
- 2020年4月(21)
- 2020年3月(120)
- 2020年2月(26)
- 2019年12月(12)
- 2019年11月(13)
- 2019年10月(17)
- 2019年9月(15)
- 2019年8月(13)
- 2019年7月(15)
- 2019年6月(15)
- 2019年5月(19)
- 2019年4月(23)
- 2019年3月(19)
- 2019年2月(11)
- 2019年1月(29)
- 2018年12月(24)
- 2018年11月(56)
- 2018年10月(79)
- 2018年9月(20)
- 2018年8月(17)
- 2018年7月(16)
- 2018年6月(7)
- 2018年5月(10)
- 2018年3月(6)
- 2018年2月(2)
- 2018年1月(11)
- 2017年11月(18)
- 2017年10月(6)
- 2017年9月(8)
- 2017年8月(7)
- 2017年7月(7)
- 2017年6月(15)
- 2017年5月(30)
- 2017年4月(7)
- 2017年3月(1)
- 2017年2月(4)
- 2017年1月(1)
- 2016年12月(3)
- 2016年11月(7)
- 2016年10月(6)
- 2016年9月(6)
- 2016年8月(102)
- 2016年7月(24)
- 2013年7月(1)
- 文章标签
-