谈escapeshellarg绕过与参数注入漏洞

参数注入漏洞是指,在执行命令的时候,用户控制了命令中的某个参数,并通过一些危险的参数功能,达成攻击的目的。

0x01 从gitlist 0.6.0远程命令执行漏洞说起

我们从gitlist说起,gitlist是一款使用PHP开发的图形化git仓库查看工具。在其0.6.0版本中,存在一处命令参数注入问题,可以导致远程命令执行漏洞。

在用户对仓库中代码进行搜索的时候,gitlist将调用git grep命令:

<?php
public function searchTree($query, $branch)
{if (empty($query)) {return null;}$query = escapeshellarg($query);try {$results = $this->getClient()->run($this, "grep -i --line-number {$query} $branch");} catch (\\RuntimeException $e) {return false;}

其中,$query是搜索的关键字,$branch是搜索的分支。

如果用户输入的$query的值是--open-files-in-pager=id;,将可以执行id命令:

[<img src=“https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/3/16325a2ccfd14c8d~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fcdn.ioin.in%2Fmedia%2Fattachment%2F2018%2F04%2F29%2Fdd89dc70-2446-48e1-a728-5693d1fa868a.png “https://cdn.ioin.in/media/attachment/2018/04/29/dd89dc70-2446-48e1-a728-5693d1fa868a.png”” style=“margin: auto” />

0x02 escapeshellarg为什么没有奏效?

导致这个漏洞的原因,有几点:

1.开发者对于escapeshellarg函数的误解,造成参数注入
2.git grep的参数--open-files-in-pager的值,将被直接执行

理论上,在经过$query = escapeshellarg($query);处理后,$query将变成一个由单引号包裹的字符串。但不出漏洞的前提是,这个字符串应该出现在“参数值”的位置,而不是出现在参数选项(option)中。

我们可以试一下如下命令:

git grep -i --line-number -e '--open-files-in-pager=id;' master

[<img src=“https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/3/16325a2cce81c632~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fcdn.ioin.in%2Fmedia%2Fattachment%2F2018%2F04%2F29%2F840cca46-5780-4713-bf2a-319f296368b7.png “https://cdn.ioin.in/media/attachment/2018/04/29/840cca46-5780-4713-bf2a-319f296368b7.png”” style=“margin: auto” />

如上图,我将$query放在了-e参数的值的位置,此时它就仅仅是一个字符串而已,并不会被当成参数--open-files-in-pager

这应该作为本漏洞的最佳修复方法,也是git官方对pattern可能是用户输入的情况的一种解决方案(以下说明来自man-page):

-e> The next parameter is the pattern. This option has to be used for patterns starting with - and should be used in scripts passing user input to grep. Multiple patterns are combined by> or.

当然,gitlist的开发者用了另一种修复方案:

<?php
public function searchTree($query, $branch)
{if (empty($query)) {return null;}$query = preg\_replace('/(--?\[A-Za-z0-9\\-\]+)/', '', $query);$query = escapeshellarg($query);try {$results = $this->getClient()->run($this, "grep -i --line-number -- {$query} $branch");} catch (\\RuntimeException $e) {return false;}

首先用preg_replace-开头的非法字符移除,然后将$query拼接在--的后面。

在命令行解析器中,--的意思是,此后的部分不会再包含参数选项(option):

A – signals the end of options and disables further option processing. Any arguments after the – are treated as filenames and arguments. An argument of - is equivalent to --.

If arguments remain after option processing, and neither the -c nor the -s option has been supplied, the first argument is assumed to be the name of a file containing shell commands. If bash is invoked in this fashion, $0 is set to the name of the file, and the positional parameters are set to the remaining arguments. Bash reads and executes commands from this file, then exits. Bash’s exit status is the exit status of the last command executed in the script. If no commands are executed, the exit status is 0. An attempt is first made to open the file in the current directory, and, if no file is found, then the shell searches the directories in PATH for the script.

举个简单的例子,如果我们需要查看一个文件名是--name的文件,我们就不能用cat --name来读取,也不能用cat '--name',而必须要用cat -- --name。从这个例子也能看出,单引号并不是区分一个字符串是“参数值”或“选项”的标准。

[<img src=“https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/3/16325a2cce0d9cf6~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fcdn.ioin.in%2Fmedia%2Fattachment%2F2018%2F04%2F29%2Fd70ec825-c4fc-4874-88b7-d4c8bbebfd70.png “https://cdn.ioin.in/media/attachment/2018/04/29/d70ec825-c4fc-4874-88b7-d4c8bbebfd70.png”” style=“margin: auto” />

所以官方这个修复方案也是可以接受的,只不过第一步的preg_replace有点影响正常搜索功能。

0x03 这不是PHP的专利

熟悉PHP语言的同学一定对PHP执行命令的方法感受深刻,PHP内置的命令执行函数(如shell_execsystem),都只接受一个“字符串”作为参数。而在内核中,这个字符串将被直接作为一条shell命令来调用,这种情况下就极为容易出现命令注入漏洞。

由于这个特点,PHP特别准备了两个过滤函数:

  • escapeshellcmd
  • escapeshellarg

二者分工不同,前者为了防止用户利用shell的一些技巧(如分号、反引号等),执行其他命令;后者是为了防止用户的输入逃逸出“参数值”的位置,变成一个“参数选项”。

但我在0x02中也已经说清楚了,如果开发者在拼接命令的时候,将$query直接给拼接在“参数选项”的位置上,那用escapeshellarg也就没任何效果了。

Java、Python等语言,执行命令的方法相对来说更加优雅:

import subprocess

query = 'id'
r = subprocess.run(\['git', 'grep', '-i', '--line-number', query, 'master'\], cwd='/tmp/vulhub')

默认情况下,python的subprocess接受的是一个列表。我们可以将用户输入的query放在列表的一项,这样也就避免了开发者手工转义query的工作,也能从根本上防御命令注入漏洞。但可惜的是,python帮开发者做的操作,也仅仅相当于是PHP中的escapeshellarg。我们可以试试令query等于--open-files-in-pager=id;

[<img src=“https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2018/5/3/16325a2cd013ff4b~tplv-t2oaga2asx-zoom-in-crop-mark:4536:0:0:0.image)](https://link.juejin.cn/?target=https%3A%2F%2Fcdn.ioin.in%2Fmedia%2Fattachment%2F2018%2F04%2F29%2F8296bbd4-40cd-481e-9147-6f11e80967d8.png “https://cdn.ioin.in/media/attachment/2018/04/29/8296bbd4-40cd-481e-9147-6f11e80967d8.png”” style=“margin: auto” />

可见,仍然是存在参数注入漏洞的。原因还是0x02中说的原因,你把query放在了“参数选项”的位置上,无论怎么过滤,或者换成其他语言,都不可能解决问题。

0x04 举一反三

参数注入的例子还比较多,因为大部分的开发者都能理解命令注入的原理,但处理了命令注入后,往往都会忽略参数注入的问题。

最典型是案例是Wordpress PwnScriptum漏洞,PHP mail函数的第五个参数,允许直接注入参数,用户通过注入-X参数,导致写入任意文件,最终getshell。

另一个典型的例子是php-cgi CVE-2012-1823 ,在cgi模式中,用户传入的querystring将作为cgi的参数传给php-cgi命令。而php-cgi命令可以用-d参数指定配置项,我们通过指定auto_prepend_file=php://input,最终导致任意代码执行。

客户端上也出现过类似的漏洞,比如Electron CVE-2018-1000006,我们通过注入参数--gpu-launcher=cmd.exe /c start calc,来让electron内置的chromium执行任意命令。electron的最早给出的缓解措施也是在拼接点前面加上“–”。

网络安全基础入门需要学习哪些知识?

网络安全学习路线

这是一份网络安全从零基础到进阶的学习路线大纲全览,小伙伴们记得点个收藏!

img[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hC32KGxL-1676914760651)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]编辑

阶段一:基础入门

img[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9U9qg3fZ-1676914760652)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

网络安全导论

渗透测试基础

网络基础

操作系统基础

Web安全基础

数据库基础

编程基础

CTF基础

该阶段学完即可年薪15w+

阶段二:技术进阶(到了这一步你才算入门)

img[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5brJAcoN-1676914760652)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

弱口令与口令爆破

XSS漏洞

CSRF漏洞

SSRF漏洞

XXE漏洞

SQL注入

任意文件操作漏洞

业务逻辑漏洞

该阶段学完年薪25w+

阶段三:高阶提升

img[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D9sDCFPO-1676914760653)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

反序列化漏洞

RCE

综合靶场实操项目

内网渗透

流量分析

日志分析

恶意代码分析

应急响应

实战训练

该阶段学完即可年薪30w+

阶段四:蓝队课程

img[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oN53aLeb-1676914760653)(data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)]

蓝队基础

蓝队进阶

该部分主攻蓝队的防御,即更容易被大家理解的网络安全工程师。

攻防兼备,年薪收入可以达到40w+

阶段五:面试指南&阶段六:升级内容

img

需要上述路线图对应的网络安全配套视频、源码以及更多网络安全相关书籍&面试题等内容

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值