文件参数Shell命令注入
1.问题信息
可能会在web服务器上运行远程命令,未对用户输入正确执行危险字符清理,存在操作系统命令注入的至少以下两种子类型:
- 应用程序计划使用外部提供的输入作为参数,执行受其控制的单个固定程序。例如,使用nslookup命令探测DNS域传送漏洞,appscan工具官方描述:程序可能使用 system("nslookup [HOSTNAME]") 来运行 nslookup,并允许用户提供 HOSTNAME 以用作参数。攻击者无法阻止 nslookup 执行。但是,如果程序不从 HOSTNAME 参数中除去命令分隔符,攻击者就可以将分隔符放置到参数中,从而能够在 nslookup 完成执行后执行其自己的程序。
- 应用程序接受输入,将完整命令重定向至操作系统。appscan工具官方描述:例如,程序可能使用“exec([COMMAND])”来执行用户提供的 [COMMAND]。如果 COMMAND 受到攻击者的控制,那么攻击者可以执行任意命令或程序。值得注意的是,如果命令是使用 exec() 和 CreateProcess() 之类的函数执行的,攻击者可能无法将多个命令组合到同一行中。这些变体代表两种不同类型的编程错误。在第一个变体中,程序员清楚地表明来自不可信方的输入将作为要执行的命令中的部分参数。在第二个变体中,程序员不希望命令可供任何不可信方访问,但未考虑到恶意攻击者可提供输入的所有方式。示例
- open(FILE,"/bin/ls") - 打开文件 /bin/ls
- open(FILE,"/bin/ls|") - 运行文件 /bin/ls
2.测试响应举例:
POST /reqxml HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Referer: http://XXX/dist/src/market-data-analysis/index.html Cookie: H5Token=M0T5I0wcM1T5I0w5N2j0E5x2McD7Mb10N9T4Eaz8N6z1kbz2M2jbYawdM7jdM9z2 Connection: keep-alive Host: XXX:7781 X-Requested-With: XMLHttpRequest Content-Length: 205 tztWebdataEncrypt: 1 Accept: */* Origin: http://XXX:7781 Accept-Language: en-US Content-Type: application/x-www-form-urlencoded; MobileCode=null&channels=&Reqno=13800138000&ReqlinkType=2&newindex=1&action=51602&begindate=2020-10-05&enddate=2021-01-05&type=2$(../../../../../../../../../../../../bin/sleep 11)&tfrom=h5&cfrom=mobile
- 描述:将参数值设置为:[originalValue]$(../ (12 times) /bin/sleep [timeout])
- 差异:以下更改已应用到原始请求,已将参数“type”的值设置为“2$(../../../../../../../../../../../../bin/sleep 11)”
- 推理:AppScan 接收到“超时”响应,指示注入的“Sleep”命令已成功
3.解决方法
- 创建并使用库调用,库调用是建立在系统调用上,通常用于为应用程序提供更加方便的功能,这些过程调用可以分为4类:进程管理、文件管理、目录与文件系统管理和杂项。
- 沙盒安全机制,为运行中的程序提供的隔离环境。可以有效限制软件可访问特定目录中的哪些文件或执行哪些命令,例如,网络访问、对输入设备的读取、控制程序可使用资源(文件描述符、内存、磁盘空间)。具体表现:(参考百科)
- 软件监狱:限制网络访问、受限的文件系统名字空间。最常用于虚拟主机上。
- 基于规则的执行:通过按照一系列预设规则给用户及程序分配一定访问权限,完全控制程序的启动、代码注入及网络访问。也可控制程序对于文件、注册表的访问。
- 虚拟机:运行于真实硬件,模拟完整的宿主系统。
- 主机本地沙盒:创建一个模拟真实桌面的环境,研究人员就能观察恶意软件是如何感染一台主机。
- 在线判题系统:编程竞赛中用来测试参赛程序的在线系统。
- 安全计算模式:Linux内核内置的一个沙盒。启用后,seccomp仅允许write()、read()、exit()和sigreturn()这几个系统调用。
- 库或框架:例如,java防止js注入使用ESAPI进行编码。
- 输入验证:使用严格黑白名单根据请求中参数的预期值来限制字符集。适当的输出编码、转义和引用是防止操作系统命令注入的最有效解决方案,例如,调用邮件程序时,可能需要允许主题字段包含在其他情况下很危险的输入(如“;”和“>”字符),这些输入需要转义或以其他方式进行处理。
- Asp.Net:提供多种方法在打开文件前对文件名进行验证。
- J2EE:文件路径验证、输入数据验证(必须字段、字段数据类型(缺省情况下,所有 HTTP 请求参数都是“字符串”)、字段长度、字段范围、字段选项、字段模式、cookie值、HTTP响应)。
- 用于服务器端验证的Java框架:Jakarta Commons Validator、JavaServer Faces。
- PHP:文件路径验证,输入数据验证(必须字段、字段数据类型(缺省情况下,所有 HTTP 请求参数都是“字符串”)、字段长度、字段范围、字段选项、字段模式、cookie值、HTTP响应)。