命令注入新玩法:巧借环境攻击目标

栏目: 编程工具 · 发布时间: 5年前

内容简介:*本文作者:yangyangwithgnu,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。在一次漏洞赏金活动中,挖掘到一个不标准的命令注入漏洞,我无法用命令分隔符、命令替换符注入新命令让系统执行,所以,从”型态”上讲,它不算是命令注入漏洞;但我又可以借助目标环境让载荷到达系统命令行,实现读写文件、执行新命令,所以,”神态”来看,它又像是命令注入。这类借助环境间接注入命令的利用手法,很少在常规讨论命令注入的文章中看到,有必要落笔成文,与你分享。由于受赏金厂商保密协议所限,我无法公开原始漏洞详情,但我

*本文作者:yangyangwithgnu,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。

在一次漏洞赏金活动中,挖掘到一个不标准的命令注入漏洞,我无法用命令分隔符、命令替换符注入新命令让系统执行,所以,从”型态”上讲,它不算是命令注入漏洞;但我又可以借助目标环境让载荷到达系统命令行,实现读写文件、执行新命令,所以,”神态”来看,它又像是命令注入。这类借助环境间接注入命令的利用手法,很少在常规讨论命令注入的文章中看到,有必要落笔成文,与你分享。

0×00 酷趣 wargame

由于受赏金厂商保密协议所限,我无法公开原始漏洞详情,但我更清楚 “talk is cheap, show me the code”,耗时费神,找到一个 wargame,相较赏金漏洞,不但体现了相同精髓,这个 wargame 还多了些限制条件,所以,让它变得更加有趣、更有挑战。

我把 wargame 源码写入 CMDi_lab/escaping_quotation/index.php,核心如下:

命令注入新玩法:巧借环境攻击目标

快速过下源码。首先,用 GET 方法获取 f1、f2 两个参数;然后,用相同的正则过滤 f1、f2,包括过滤引号防止利用环境写 webshell,过滤常见命令分隔符(;)、命令替换符($())防止注入新命令,过滤常见命令(ls、cat)禁止基础操作;接着,用引号再建一道防御工事,让所有输入均在引号内,让命令行元字符失效;最后,以 f1、f2 为命令参数执行系统命令 file。

怎么样!看上去是很完善的防御体系。先正常访问试试:

命令注入新玩法:巧借环境攻击目标

服务端执行 file 命令,正确识别出目录和文件的类型。尝试提交命令分隔符(;)和命令替换符(“):

命令注入新玩法:巧借环境攻击目标

由于服务端正则表达式匹配上 ; 和 “,导致提交的文件名被置为空,所以,file 提示无法找到相关文件。

经验主义,我将从三个层面寻找突破口:攻击正则、攻击引号、攻击命令行。那么,我就准备开动了,各位。

0×01 成败正则

在命令注入场景下审查正则表达式,我习惯关注四个方面:是否使用多行模式修饰符(/foo/m)、是否遗漏匹配对象末尾的换行符(/^\d+$/)、是否允许空白字符(\s)、是否误写反斜杠匹配模式(/\\/)。

使用多行模式修饰符。把多行模式用于匹配希望允许的字符时,就会存在逻辑问题。比如,如下代码:

命令注入新玩法:巧借环境攻击目标

原本希望只允许 xx.xx.xx.xx 格式的 IP 地址,由于使用多行模式,只要输入中某行满足条件即可,那么,我可以用换行符输入多行,第一行满足要求 127.0.0.1、第二行任意内容,这样轻松绕过正则限制:

命令注入新玩法:巧借环境攻击目标

本 wargame 未使用多行模式,所以不存在这个问题。

遗漏匹配对象末尾的换行符。某些模式在匹配时会忽略字符串末的换行符,而换行符自身又是一个有效的目录分隔符,将导致注入新命令。如下代码:

命令注入新玩法:巧借环境攻击目标

原意是过滤掉输入中非字母、数字外的其他所有字符,输入换行符试试:

命令注入新玩法:巧借环境攻击目标

果然被过滤了。但,若把换行符放至字符串末尾,正则反而无法匹配上:

命令注入新玩法:巧借环境攻击目标

这可有趣了,又能愉快地注入新命令了:

命令注入新玩法:巧借环境攻击目标

本 wargame 未能成功过滤掉换行符,但不是因为上面的原因。

允许空白字符。空白字符包括空格、换行符、水平制表符、垂直制表符等四个,命令注入的好朋友换行符也在其中。代码:

命令注入新玩法:巧借环境攻击目标

本意只允许字母、数字、空格等字符,但遗漏了换行符,导致命令注入漏洞:

命令注入新玩法:巧借环境攻击目标

本 wargame 未能成功过滤掉换行符,但不是因为上面的原因。

误写反斜杠匹配模式。正则表达式自身是个字符串,并非直接传递给正则引擎,而是先由语言对字符串进行处理后再传递给正则引擎。我希望匹配上反斜杠(\),逆向思考下这个过程,由于反斜杠在正则引擎是个特殊字符,所以 \\ 才能让正则引擎正确识别到反斜杠 \;正则引擎之前,\\ 经过语言的的字符串处理,由于反斜杠在字符串中也是特殊字符,所以,一个 \ 就得用 \\ 表示、两个 \ 就得用 \\\\ 表示。那么,但凡用正则表达式匹配斜杠,必须得用 \\\\。这是不具备原生字符串特性(r)的脚本语言的通病,是有一点绕。比如:

命令注入新玩法:巧借环境攻击目标

访问看看:

命令注入新玩法:巧借环境攻击目标

记得 wargame 也过滤了反斜杠,回过头看看,哇喔,的确误用了:

命令注入新玩法:巧借环境攻击目标

OK,在正则部分,由于误写匹配模式,我找到了漏网之鱼,反斜杠。如何利用?不知道,走一步看一步。

0×02 引号逃逸

接着我来琢磨下 25、26 行。这两行目的很清晰,用引号包裹输入字符串,预防可能因正则过滤不严传递一些个特殊字符到命令行环境,思路是对的,但效果就差强人意了。

载荷一旦进入引号内,都将退化成普通字符串,好无杀伤力,唯一例外,命令替换符(“ 或 $()),遗憾的是,命令替换符被正则严防死守,无法到达 25、26 行。所以,下意识地想到,引号逃逸。

引号逃逸,目的是让输入跳脱至引号外,恢复特殊字符的身份,而不再被引号所束缚,仅仅是个普通字符。我常用两种手法,一是闭合、二是转义。

闭合手法逃逸引号。在输入中添加一个引号,让其与左引号结对,自然闭合,接着输入中就能出现恶意字符,最后输入中再添加一个引号,与右引号结对,或者,输入注释符以忽略右引号。比如:

命令注入新玩法:巧借环境攻击目标

我的所有输入都只能留在引号内,导致命令分隔符无法被命令行正确识别:

命令注入新玩法:巧借环境攻击目标

我在输入中增加两个引号(②、③),这样刚好与代码中的引号闭合(① 和 ②、③ 和 ④),所以,我的其他输入字符(;id;)就能出现在引号之外,成功逃逸引号:

命令注入新玩法:巧借环境攻击目标

转义手法逃逸引号。引号自身也是个特殊字符,如果有办法让它变成普通字符,那么输入的其他特殊字符就能让命令行正确识别。反斜杠可以办到!如下代码:

命令注入新玩法:巧借环境攻击目标

含有恶意字符的输入被限定在引号内:

命令注入新玩法:巧借环境攻击目标

假设服务端生成的命令模型为 file “foo” “;date”,这时,我利用反斜杠将 ② 号引号转义为普通字符,那么 ① 和 ③ 号引号将自然结合,接着利用注释符将 ④ 号引号注释掉,;date 对于命令行直接可见,逻辑上我能用 file “foo\” “;id #bar” 注入任意命令,再次逃逸到引号外:

命令注入新玩法:巧借环境攻击目标

注,注释符 # 需要 URL 编码为 %23。

好了,还记得前面我找到正则漏洞无法过滤反斜杠么,wargame 中的引号已经无法束缚我,虽然当下无法直接利用,但至少又让我向前迈出一步。

0×03 选项注入

继续看 29、30 两行的命令执行代码。显然这与命令注入漏洞多少有些关系。命令注入常见三种手法:利用命令分隔符注入命令、利用命令替换符注入命令、利用命令选项注入命令。

命令分隔符注入命令。命令分隔符包括换行符(\n)、分号(;)、逻辑与(&&、&)、逻辑或(||、|),若在 win 批处理脚本中还能用 %1A。比如:

命令注入新玩法:巧借环境攻击目标

命令替换符注入命令。shell 优先执行命令替换符内的命令,目的是便于运维人员将前个命令的输出作为后个命令的输入。命令替换符包括 $(…)、反引号 `…`。比如:

命令注入新玩法:巧借环境攻击目标

命令选项注入命令。命令选项(option)和命令参数(argument)是两个概念,国内外很多文献都将他俩混淆。比如:

命令注入新玩法:巧借环境攻击目标

其中,-d 是命令选项、/tmp/ 是命令参数。很多时候,蓝队过滤掉所有命令分隔符、命令替换符,虽然我无法直接注入命令,但我可以注入其他命令选项,这就给我很大想像空间,某些选项可以读取文件、有些又能写入文件、甚至执行其他命令。比如,有个页面,可以将 web 目录打包为你指定的归档文件,输入为归档文件名 $archive 参数,服务端过滤所有命令注入相关字符,调用 system(“tar -cf” . $archive . “*”) 执行命令:

命令注入新玩法:巧借环境攻击目标

但我通过注入 tar 命令的 –checkpoint、–checkpoint-action=exec 两个选项,成功执行命令 id:

命令注入新玩法:巧借环境攻击目标

wargame 中执行的是 file 命令,查看下它有哪些用得上的选项,比如,是否有选项可以读文件,man 中搜索 read,找到 -f 选项:

命令注入新玩法:巧借环境攻击目标

仔细看下,该参数并不能读取显示文件内容,只是从该文件中获取文件列表,没意思(。・_・。)。等等,报错信息中有啥提示:

命令注入新玩法:巧借环境攻击目标

哇噢,历害啦,通过注入命令选项 -f,让我可以读取 wargame 的文件内容。

0×04 全面瓦解

管它金城汤池还是铜墙铁壁,一颗松滑螺钉,它将全面瓦解。

将多个独立漏洞组合成漏洞链,完成目标攻击,绝对是我的 G 点。回顾前面的成果,由于误写正则表达式,导致无法过滤反斜杠;通过反斜杠,可以逃逸引号;通过引号逃逸,创造出命令选项注入的条件;通过注入 -f 选项,实现 flag 文件读取。过滤反斜杠的正则,就是那颗松滑的螺钉。

现在,攻击目标前,还剩一个问题,我并不清楚 flag 文件路径及文件名。首先想到的是暴破。土!的确很土气,用常见的 flag、FLAG、f14g 等等常见 flag 名暴了一遍,毫无收获。换个手法,通配符模式匹配。这下洋气了吧。

通配符模式匹配(globbing patterns),也叫路径名扩展(pathname expansion),简单来说,在表示文件名/目录名或路径时,你可以用 ? 代表任一可见字符、用 * 代表零或多个可见字符、用 [a-z] 代表字符范围,唯一例外,以 . 开头的文件或目录、以 / 分隔的路径必须显式写明,否则无法被模式匹配。

比如,我并不还知道 /tmp/ 目录下有个名为 FindMe 的文件,但,借助通配符多次测试,不但刺探出该文件的存在,还成功查看到文件内容:

命令注入新玩法:巧借环境攻击目标

好,现在一切就绪,攻击 CMDi_lab/escaping_quotation。有了前面的分析,我构造了载荷 f1=foo\&f2=-f ? bar #,将 file “foo” “bar” 转换为 file “foo\” “-f ? bar #”,猜解文件名只有一个字符的文件:

命令注入新玩法:巧借环境攻击目标

显然,没找到这样的文件,相同思路,借助 burp 自动查找文件名长度在 [1, 16] 的所有文件:

命令注入新玩法:巧借环境攻击目标

跑完还是没有找到任何文件。这就奇怪了,前面说过,通配符无法匹配 .,莫非是隐藏文件,调整下载荷, f1=foo\&f2=-f .? bar #,再次暴破:

命令注入新玩法:巧借环境攻击目标

找到名为 .f1a9_ 的目录,继续调整载荷 f1=foo\&f2=-f .f1a9_/.? bar #,暴破:

命令注入新玩法:巧借环境攻击目标

找到名为 .f1a9_/.flag_15_here.txt 的文件,带上准确路径访问:

命令注入新玩法:巧借环境攻击目标

WTF!不应该啊,逻辑上说不通。别急,捋一捋,莫非载荷中新增部分有被过滤的字符?回到前面的正则源码处,的确过滤了 flag 关键字,我用通配符替换,载荷变成 f1=foo\&f2=-f .f1a9_/.fl?g_15_here.txt bar #,另外,命令选项 -f 前应该得加个空格,最终载荷为 f1=foo\&f2= -f .f1a9_/.fl?g_15_here.txt bar #,来一发:

命令注入新玩法:巧借环境攻击目标

多么愉悦的攻击体验!

0×05 非预期解法

丝滑般的思绪,真实而自然!思绪自然?!正则未正确过滤反斜杠、利用反斜杠逃逸引号、通配符模式猜解路径、注入命令选项读取文件,做作、别扭!以上是我为了凑字数、增篇幅写的,真实的攻击手法并非如此。

仔细审计正则过滤的代码。用 \\ 而非 \\\\ 表述反斜杠,不仅无法正确过滤反斜杠,还会引发连锁反应。你看,紧随 \\ 其后的是 |\n:

命令注入新玩法:巧借环境攻击目标

前面提过,\\ 结果字符串转义后到达正则引擎变成 \,它与 |\n 结合变成 \|\n,正则引擎误解成匹配竖线与换行符的组合。当我输入竖线与换行符的组合,确认被过滤:

命令注入新玩法:巧借环境攻击目标

换言之,服务端只过滤 |\n 而放行 \n。有换行符,我可以直接注入新命令,比如,执行命令 id:

命令注入新玩法:巧借环境攻击目标

既然能注入命令了,查看 flag 易如反掌!命令 grep -r . . 可以查看当前目录下所有文件内容,服务端过滤了 grep,我用内部空变量轻松绕过(g$1rep -r . .),或者,无效转义绕过(g\rep -r . .),或者,通配符绕过(/bin/gr?p -r . . 或 /bin/gr[d-f]p -r . .),我有 1024 种方式吊打目标。

OK,清晰,争取一次搞定,构造载荷 ?f1=foo\&f2=%0a/bin/gr[d-f]p+-r+.+.+%23,页面显示:

命令注入新玩法:巧借环境攻击目标

0×06 故事尾声

最后聊聊你关心的赏金漏洞。大致业务场景,服务端执行打包命令压缩几个固定目录,允许用户输入归档文件名,多次刺探确认使用的 zip 命令,类似:

命令注入新玩法:巧借环境攻击目标

其中,归档文件名 archive.tar 可控。服务端正则过滤所有命令分隔符、命令替换符、其他元字符,同时,禁止出口流量,显然无法直接注入命令。

一番尝试,发现允许横线(-),这就告诉我可以注入命令选项。我开始分析环境 zip 自身有哪些选项可以为我所用。先查找关键字 execute,一无所获;接着搜索关键字 command,找选项 –unzip-command(简写 -TT) 和 –test(简写 -T),允许用户指定第三方程序来校验归档文件的完整性:

命令注入新玩法:巧借环境攻击目标

换言之,选项 -T 和 –unzip-command 可以注入新命令 id:

命令注入新玩法:巧借环境攻击目标

成功拿到赏金。

命令注入攻击,除了常规的命令分隔符、命令替换符之外,利用环境自身也能实现。

注一,wargame 的原型来自 Kaibro 所写的 wargame,见 http://final.kaibro.tw:10002/

注二,escaping_quotation 源码,以及更多命令注入相关 wargame 见 https://github.com/yangyangwithgnu/CMDi_lab

*本文作者:yangyangwithgnu,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Is Parallel Programming Hard, And, If So, What Can You Do About

Is Parallel Programming Hard, And, If So, What Can You Do About

Paul E. McKenney

The purpose of this book is to help you understand how to program shared-memory parallel machines without risking your sanity.1 By describing the algorithms and designs that have worked well in the pa......一起来看看 《Is Parallel Programming Hard, And, If So, What Can You Do About 》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具