HW期间,为防范钓鱼,即日起FreeBuf将取消投稿文章的一切外部链接。给您带来的不便,敬请谅解~
写在前面的话
研究人员通过研究后发现,一些用于处理IP地址和网络掩码的Perl模块存在安全漏洞,并有可能导致使用了这些模块的应用程序易暴露在网络风险之中。受影响的模块包括但不仅限于:
Net-Netmask:v2.00000及其之前版本受影响,更新后不受影响。
Net-CIDR-Lite:受影响,已不维护。
Net-IPAddress-Util:受影响。
Data-Validate-IP:具体取决于它的使用方式,详见下文。
Socket:未受影响。
Net-DNS:未受影响。
NetAddr-IP:未受影响。
Net-Subnet:未受影响。
Net-Patricia:未受影响。
就在昨天,研究人员曝光了一个关于NPM数据包netmask的安全问题。(https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/)
问题本身十分简单,你的操作系统将允许一个类似010.0.0.1的IP地址或一个类似010.0.0.0/8的子网掩码。这里的010会被当作一个八进制数,而不是一个以0开头的十进制数。这也就意味着, 010.0.0.1实际上就是8.0.0.1,我们可以使用ping命令来进行验证:
ping 010.0.0.1 PING 010.0.0.1 (8.0.0.1) 56(84) bytes of data.
但NPM的netmask包会将其视作10.0.0.1。这种混淆意味着一个应用程序可以被攻击者操作,并将一个公共IP-8.0.0.1视作私有子网10.0.0.0/8中的一部分。或者,攻击者也可以欺骗应用程序,让它认为私有IP-10.0.0.1(写作012.0.0.1)是一个公共子网12.0.0.1中的一部分。
这对任何试图区分公共和私有IP地址或访问控制、防火墙等网络的应用程序都会带来安全影响。
开启分析之路
我阅读完研究人员的报告之后,我突然意识到,Perl的代码也有可能受到这个问题影响!因此,我便开始深入研究这个问题,研究并查看各种用于处理IP地址、网络和网络掩码的CPAN模块。
以下是CPAN模块的当前状态,大致按它们在The River of CPAN中的位置排序(这基本上意味着有多少模块依赖于它们)。
Net-Netmask
当前版本有22个直接依赖和总共30个依赖。
2.0000版本之前的模块情况如下:
perl -MNet::Netmask -E 'say defined Net::Netmask->new2(q{010.0.0.0/8}) ? 1 : 0' 0
注意这里的new2构造器,旧的new构造器无法经过修改并返回undef(回退兼容性问题)。幸运的是,这并不是一个可以被利用的漏洞,因为它会返回一个0长度的子网:
perl -MNet::Netmask -E 'say Net::Netmask->new(q{010.0.0.0/8})' 0.0.0.0/0
Net-CIDR-Lite
这个版本有24个直接依赖和总共36个依赖:
perl -MNet::CIDR::Lite -E 'my $c = Net::CIDR::Lite->new; $c->add("010.0.0.0/8"); say $_ for $c->list_range' 10.0.0.0-10.255.255.255
Net-IPAddress-Util
这个版本无任何依赖:
perl -MNet::IPAddress::Util=IP -E 'say IP(q{010.0.0.1})' 10.0.0.1
Data-Validate-IP
这个版本有21个直接依赖和总共60个依赖。
如果is_*_ipv4方法中包含了八进制数字,那么这个版本的模块只会返回false。因此,is_private_ipv4('010.0.0.1')和is_public_ipv4('010.0.0.1')都将返回false。
如果你正在使用此发行版,我强烈建议你在安全上下文中审核你对它的使用方式!
Socket
这个版本有275个直接依赖和总共9936个依赖:
perl -MSocket -E 'say inet_ntoa(inet_aton(q{010.0.0.1}))' 8.0.0.1 perl -MSocket=inet_pton,inet_ntop,AF_INET -E 'say inet_ntop(AF_INET, inet_pton(AF_INET, q{010.0.0.1}))' Bad address length for Socket::inet_ntop on AF_INET; got 0, should be 4 at -e line 1.
inet_pton()函数针对这种八进制格式的地址只会返回undef。
Net-DNS
这个版本有104个直接依赖和总共561个依赖。
如果你想要尝试解析一个IP地址,它会将请求转为一个反向Lookup查询,但它会将IP地址以文本的形式解析:
perl ./demo/perldig 010.0.0.1 ;; Response received from 127.0.0.53 (40 octets) ;; HEADER SECTION ;; id = 6342 ;; qr = 1 aa = 0 tc = 0 rd = 1 opcode = QUERY ;; ra = 1 z = 0 ad = 0 cd = 0 rcode = NXDOMAIN ;; qdcount = 1 ancount = 0 nscount = 0 arcount = 0 ;; do = 0 ;; QUESTION SECTION (1 record) ;; 1.0.0.010.in-addr.arpa. IN A
NetAddr-IP
这个版本有36个直接依赖和总共110个依赖:
perl -MNetAddr::IP -E 'say NetAddr::IP->new(q{010.0.0.024})' 8.0.0.20/32
Net-Subnet
这个版本有3个直接依赖和总共7个依赖:
perl -MNet::Subnet -E 'my $m = subnet_matcher(q{10.0.0.0/8}); say $m->(q{012.0.0.1}) ? 1 : 0' 1 perl -MNet::Subnet -E 'my $m = subnet_matcher(q{012.0.0.0/8}); say $m->(q{10.0.0.1}) ? 1 : 0' 1
Net-Patricia
这个版本有1个直接依赖和总共1个依赖:
perl -MNet::Patricia -E 'my $p = Net::Patricia->new; $p->add_string("010.0.0.0/8"); say $p->match_string("8.0.0.1") ? 1 : 0' 1 perl -MNet::Patricia -E 'my $p = Net::Patricia->new; $p->add_string("8.0.0.0/8"); say $p->match_string("010.0.0.1") ? 1 : 0' 1
参考资料
https://sick.codes/universal-netmask-npm-package-used-by-270000-projects-vulnerable-to-octal-input-data-server-side-request-forgery-remote-file-inclusion-local-file-inclusion-and-more-cve-2021-28918/
https://github.com/rs/node-netmask
http://search.cpan.org/dist/Net-Netmask/
https://neilb.org/2015/04/20/river-of-cpan.html
https://metacpan.org/release/Net-Netmask
https://metacpan.org/release/Net-CIDR-Lite
https://metacpan.org/release/Net-IPAddress-Util
https://metacpan.org/release/Data-Validate-IP
https://metacpan.org/pod/Data::Validate::IP#USAGE-AND-SECURITY-RECOMMENDATIONS
https://metacpan.org/release/Socket
https://metacpan.org/release/Net-DNS
https://metacpan.org/release/NetAddr-IP
https://metacpan.org/release/Net-Subnet
https://metacpan.org/release/Net-Patricia
https://blog.urth.org/2021/03/29/security-issues-in-perl-ip-address-distros/#fnref:1