1. FlyPython首页
  2. 网络安全

CVE-2021-29921——最新Python3.8 解析IP地址八进制错误的漏洞分析

今天,Python官方放出了一个因为IP地址解析问题导致的漏洞,影响的版本是Python3.8到Python3.10,截止目前漏洞还没有修复。
这个漏洞是因为python stdlib 中的 ipaddress 处理八进制不正确输入的验证导致不确定的SSRF & RFI ,主要的思路是把ip地址前置0,搞成八进制。

此漏洞CVE ID 为CVE-2021-29921漏洞详情链接:https://sick.codes/sick-2021-014/
在Python3.8.0到Python3.10版本中的stdlib ipaddress,当八进制字符串为输入的时候,验证允许未经身份验证的远程攻击者对许多依赖于Python stdlib ipaddress 的程序执行不确定的SSRF, RFI和LFI攻击。

这个漏洞导致IP地址保护被去除,不能作为有效的IP地址来计算。攻击者可以向依赖stdlib ipaddress的web应用,提交IP地址,通过输入八进制数据导致SSRF。攻击者提交的可利用的IP地址,如果是3位的八进制数,范围为08-099。例如:提交的IP为010.8.8.8,Python ipaddress 会将其评估为10.8.8.8
下面是验证程序:

#!/usr/bin/env python# Authors:      sickcodes, Victor Viale# License:      GPLv3+# Reference:    https://docs.python.org/3.10/library/ipaddress.html#ipaddress.IPv4Address
# Leading zeroes are tolerated only for values less than 8 (as there is no ambiguity between the decimal and octal interpretations of such strings).
import subprocessimport ipaddress
SUSPECT = '010.8.8.8'
print(ipaddress.ip_network(SUSPECT, strict=True))
BAD_IP = ipaddress.ip_address(SUSPECT)
print('http://'+str(BAD_IP))
print(str(subprocess.check_output("ping -W3 -v -c1 "+str(SUSPECT), shell=True, universal_newlines=True).strip()))
print(str(subprocess.check_output("ping -W3 -v -c1 "+str(BAD_IP), shell=True, universal_newlines=True).strip()))

运行结果:

10.8.8.8/32http://10.8.8.8PING 010.8.8.8 (8.8.8.8): 56 data bytes
--- 010.8.8.8 ping statistics ---1 packets transmitted, 1 packets received, 0.0% packet loss, 1 packets out of wait timeround-trip min/avg/max/stddev = 334.357/334.357/334.357/0.000 msTraceback (most recent call last): File "test.py", line 14, in <module> print(str(subprocess.check_output("ping -W3 -v -c1 "+str(BAD_IP), shell=True, universal_newlines=True).strip())) File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 411, in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 512, in run raise CalledProcessError(retcode, process.args,subprocess.CalledProcessError: Command 'ping -W3 -v -c1 10.8.8.8' returned non-zero exit status 2.

可以看到,经过ipaddress.ip_address处理的恶意IP地址010.8.8.8,变成了 10.8.8.8,去掉了前面的0,ping不成功。而直接使用010.8.8.8 进行ping 则成功解析到了8.8.8.8。

原创文章,作者:flypython,如若转载,请注明出处:http://flypython.com/sec/451.html