如果你的Web应用中存在Python代码注入漏洞的话,攻击者就可以利用你的Web应用来向你后台服务器的Python解析器发送恶意Python代码了.这也就意味着,如果你可以在目标服务器中执行Python代码的话,你就可以通过调用服务器的操作系统的指令来实施攻击了.通过运行操作系统命令,你不仅可以对那些可以访问到的文件进行读写操作,甚至还可以启动一个远程的交互式Shell(例如nc、Metasploit和Empire).
为了复现这个漏洞,我在最近的一次外部渗透测试过程中曾尝试去利用过这个漏洞.当时我想在网上查找一些关于这个漏洞具体应用方法的信息,但是并没有找到太多有价值的内容.在同事Charlie Worrell(@decidedlygray)的帮助下,我们成功地通过Burp POC实现了一个非交互式的shell,这也是我们这篇文章所要描述的内容.
因为除了Python之外,还有很多其他的语言(例如Perl和Ruby)也有可能出现代码注入问题,所以呢Python代码注入属于服务器端代码注入的一种.实际上,如果各位同学和我一样是一名CWE的关注者,那么下面这两个CWE也许可以给你提供一些有价值的参考内容:
假设你现在使用Burp或者其他工具发现了一个Python注入漏洞,而此时的漏洞利用Payload又如下所示:
eval(compile("""for x in range(1):\\n import os\\n os.popen(r'COMMAND').read()""",'','single'))实际上,你甚至都不需要使用for循环,直接使用全局函数"__import__"就可以了.具体代码如下所示:
eval(compile("""__import__('os').popen(r'COMMAND').read()""",'','single'))其实我们的Payload代码还可以更加简洁,既然我们已经将import和popen写在了一个表达式里面了,那么在大多数情况下,你甚至都不需要使用compile了.具体代码如下所示:
__import__('os').popen('COMMAND').read()
为了将这个Payload发送给目标Web应用,你需要对其中的某些字符进行URL编码.为了节省大家的时间,我们今天这一节已经将上面所列出的Payload代码编码完成了,具体如下所示:
搭建一个包含漏洞的服务器
git clone VulnApp
./install_requirements.sh
python PyCodeInjectionApp.py
漏洞分析
当你在网上搜索关于python的eval()函数时,几乎没有文章会提醒你这个函数是非常不安全的,而eval()函数就是导致这个Python代码注入漏洞的罪魁祸首.如果你遇到了下面这两种情况,说明你的Web应用中存在这个漏洞:
\
大家可以看到,eval()函数是上述代码中唯一一个存在问题的地方.除此之外,如果开发人员直接对用户的输入数据(序列化数据)进行拆封的话,那么Web应用中也将会出现这个漏洞.
不过需要注意的是,除了eval()函数之外,Python的exec()函数也有可能让你的Web应用中出现这个漏洞.而且据我所示,现在很多开发人员都会在Web应用中不规范地使用exec()函数,所以这个问题肯定会存在.
自动扫描漏洞
为了告诉大家如何利用漏洞来实施攻击,我通常会使用扫描器来发现一些我此前没有见过的东西.找到之后,我再想办法将毫无新意的PoC开发成一个有意义的exploit.不过我想提醒大家的是,不要过度依赖扫描工具,因为还很多东西是扫描工具也找不到的.
这个漏洞也不例外,如果你在某个Web应用中发现了这个漏洞,那么你肯定使用了某款自动化的扫描工具,比如说Burp Suite Pro.目前为止,如果不使用类似Burp Suite Pro这样的专业扫描工具,你几乎是无法发现这个漏洞的.
当你搭建好测试环境之后,启动并运行包含漏洞的示例应用.此时此刻呢,使用Burp Suite Pro来对其进行扫描.扫描结果如下图所示:
下图显示的是Burp在扫描这个漏洞时所使用的Payload:
将PoC升级成漏洞利用代码
使用time.sleep()来验证漏洞的存在的确是一种很好的方法.此时此刻呢,为了执行操作系统指令并接收相应的输出数据,我们可以使用os.popen()、subprocess.Popen()、或者subprocess.check_output()这几个函数.当然了,应该还有很多其他的函数同样可以实现我们的目标.
下面这个Payload应该可以适用于绝大多数的场景:
# Example with one expression
# Examples with one expression
eval(compile("""for x in range(1):\n import os\n os.popen(r'COMMAND').read()""",'','single'))eval(compile("""for x in range(1):\n import subprocess\n subprocess.Popen(r'COMMAND',shell=True, stdout=subprocess.PIPE).stdout.read()""",'','single'))eval(compile("""for x in range(1):\n import subprocess\n subprocess.check_output(r'COMMAND',shell=True)""",'','single'))如果包含漏洞的参数是一个GET参数,那么你就可以直接在浏览器中利用这个漏洞了:
如果是POST参数的话,我建议各位直接使用类似Burp Repeater这样的工具.如下图所示,我在subprocess.check_output()函数中一次性调用了多个系统命令,即pwd、ls、-al、whoami和ping.
漏洞利用工具-PyCodeInjectionShell
你可以直接访问PyCodeInjectionShell的GitHub主页获取工具源码,我们也提供了相应的工具使用指南.在你使用这款工具的过程中会感觉到,它跟sqlmap一样使用起来非常的简单.除此之外,它的使用方法跟sqlmap基本相同.
因为你引用了其他模块的函数,但是该模块里面有不是包含在函数中的代码,你在引用该模块中的函数时候会先执行被引用模块的代码.例如:
a.py里面有 a = 10
print(a)
def test():
然后你在b.py 文件中引入了test函数 :from a import test
test() 执行的顺序就是 先执行 a = 10 ,print(a) ,test() 执行b.py中的代码的时候从from 那一句开始所以a 中的代码也被执行了
在设置界面中,可以设置程序的安装和修复方式,需要提醒自己,然后进行修复操作
打开腾讯电脑管家——工具箱——修复漏洞,进行漏洞扫描和修复.
以上就是土嘎嘎小编为大家整理的python函数漏洞相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!