长亭百川云 - 文章详情

安全开发之 python subprocess

安全小黄鸭

66

2024-07-14

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

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

一句话总结: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是这样的:

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

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

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

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2