之前我们讲过的都是代码注入,注入的代码相当于网页中新的代码,比如去执行数据库读取的操作,我们想办法插入一段代码去执行,这就是代码执行。
命令注入:
命令注入执行的是系统中的命令,使目标服务器的命令在目标服务器上去执行我们想要执行的命令,系统命令的执行还是要基于某些函数的调度去实现的。
1、system函数
例如system函数执行系统命令并输出相应的结果:
String system(string command, int&return_var)
这里就给了个代码示例。
2 、exec函数
system函数是关键函数,不论是CTF还是挖洞最初都要对弱点函数做追踪,第一个就是system,第二个就是exec。
不会因为返回值受限一定要把它把传递给某个变量才可以。
3 、passthru函数
String shell _exec(string command) command是要执行的命令
4、运算符
与shell_exec功能相同,执行shell命令并返回输出的字符串
加引号后会直接执行系统命令,比如说echo,执行ls那么它是输出的是ls,如果要执行的是反引号中的ls,相当于打印出ls命令执行之后的一个结构。
在实际过程中,想去嵌入还是比较困难的,变量可控,存在反引号之间的,反引号传递不了,我们可以控制变量靠后的值,不管是get还是post单引号还是双引号,传递上去的值肯定是在引号之间的。
1. 换行符
换行符,比如说%0a就相当于换了一行,%0d也就是回车符。连续指令,理解上可能就相当于SQL语句,比如说第一句select 123那么理论上来说,如果你真的是写完整语法的,肯定是用分号去结尾,然后另起一行下一句,包括PHP它也是以分号来做换一行一行结束的。那么在shell中也是用这样去使用的。我用把0d换成一个分号的时候,一样是能够去实现执行的,就是这样一个效果,分号的作用就是说它会忽视掉两者之间的关系,就无论你上一条什么状态,就是你执行完了,或者你报错了,然后就执行下一句一句就是两者互不影响。
2. 后台进程
后台进程,是看有没有用后台进程,比如echo 123,放后台之后,它其实就会产生一个ID号的。你在实际这个里面去执行的时候,它这里是没有回显所以说你实际过程中要去试看能不能回显,以及为什么不回显都可以去考虑。
管道符|,其实这个地方用的场景也是非常多的,因为Linux是shell比如说echo 123,我们知道echo 123,它打印出来的就是123,那么如果说把它作为参数去传递给一个试试看这个地方,echo 123如果说作为参数去传递给echo $0了,它这也没有什么效果。就是说echo你会看到是这样的一个效果。
如果没有bash,它是没有回显的你会看到上面执行一个ls的一个效果,echo ls相当于把它分割开来,然后ls作为参数传递给bash,那bash其实类似一个shell就相当于新开一个窗口,实际执行的就是ls两个语句是能够合并的,它能够作为参数传递给它。第二个就是把它作为参数传递给第二个命令去使用。
3. 双竖线||和&&
双竖线||和一个&&,它其实有点类似于互和和的作用。双竖线的话其实就是类似于或,上一个命令为false的时候,它会执行下一条语句。我要像前面是一个PWD的时候,它就会只会去执行PWD而不会去执行ls所以是这样的一个效果。所以说对应的它就是&&,它其实就是一个和逻辑,就只有上一条为true的时候,它会执行下一条语句。
如果它是管道符|的话传递过去,这个要注意它做可能编码之后能够传递过去的状态。其实它这个地方,会作为去分割变量的一个问题。就是1=2,然后接下来就可能是第二个变量名,很多时候其实命令执行的时候,就是不让你去使用某些符号,因为过滤,你敲的都是字母,那么字母的话肯定没问题,但是很多时候它就比如说去过滤空格这种之类的,经常讲到一个东西,如何去绕过一个空格的过滤,空格过滤的时候就用到这些。这边提到相当于一个像<,我们知道,如果说你是向右,就是把它输出到什么东西里面,那么向左的时候,它其实可以起到一个空格的作用。可以看到这里还要提到那些什么$IFS等等这些东西,这里的话你就可以把它理解成一个内部的预分割符,它这里的话就相当于理解成了一个空格,然后$IFS ${IFS} $IFS$9暂时也不用太过于关注,后面会提这个问题。
它这地方把这一串给合并掉了那么这里就要加引号,要是不加引号没有IFS其实就是不行的。那么其实这里也提到一个问题,就是命令在识别的时候,它如何知道$IFS到哪里结尾到底是IFS 还是exec,所以就推出了一个像刚才那样子。IFS这个地方,它就用它的大括号去把它给括起来,括起来的作用是和直接执行命令是一致的,这样的话它能够更加明确你命令就这个命令到底是多长,而不会说它不认识。
思路:相当于把它第几个参数给拿过来意思就是,我们写一个shell的时候,比如说a.sh后面是跟好几个参数,那么它就是把你第几个参数渠道传给shell,就是这个意思,$9这些都是空的,所以它是没有值的,是不会有影响。这个%09的话,它其实是用一个在URL中做传递的,刚才我们看到PWD就是能够实现的,比如说我echo 222,这个地方是因为有空格才能够去实现的如果没有空格,它是没有用的,但是我要是跟上一个%09的时候,它又是能够实现的,所以说%09在这里的作用其实又是一个空格的一个作用。
接下来再看一下一些命令执行的一些绕过。这些绕过的话其实就是一些思路了。因为我们知道命令的话,其实就是一些字母组成的东西,对不对?那么像a=1;b=s;$a$b拼接起来是不是就是ls它的效果就可以看一下。
思路:它就实现了一个ls,这种时候你就能去实现任何的命令拼接也不会出现说非常敏感的那种关键词,比如说它检测的是ls,这里是没有ls,那你就可以实现一个绕过。那么像下面这种可能用的更多了,就是用base64的编码去做一个绕过,因为base64是命令在Linux中是一般来说都是存在的,整个可能参数上会有点区别,大写的就是像第二个参数,base64-D,那么我们对它打印出来的结果做base64编码就是base64-D大写的D那么这样的话其实解出来之后,它其实就是打一个whoami并没有去执行命令,对不对?所以说我还对它多执行一步,那么这里用的就是一个反引号,反引号以后对它这个是这条语句执行的最终结果去做一个命令执行,那么它就会去执行whoami命令,去输出一个我是谁的效果。那么所以说编码方式在实际利用中其实是比较多的,因为用通过base64的话,基本上会过滤掉任何关键字。
4.语法substr string pos len
它就有点类似于叫什么SQL注入中的节长度的一个过程。所以的话它相当于比如说${PATH:0:1},就01肯定就取的是$开始这个变量的第一个字符串。
expr去配合的话思路上也是一样的,就是去从字符串中去读到某个位置的字符串,比如说像命令去执行的时候。反斜杠的作用是它其实就是去分隔开。因为之前IFS如果说没有杠的话,它直接黏粘在一起,它可能无法分辨自己命令到底有多长。
思路:之前提到了IFS其实是因为空格的作用,那么这条命令的实质就expr substr然后加一个命令,然后取从第一位开始,就是相当于你能够获取到一串字符串,你从这个字符串中去选取命令,从这个字符串中去选取那个位置某个字母,那么下面这个也是一样的,只不过最终语句实现上可能会有点区别,PWD和pwd有什么区别?以及${}里面有什么区别?其实就是${PWD}和PWD是一样的,是没有任何区别的,只不过刚才提到这种的形式,它会更加明确你的命令语句是哪一些。pwd是纯粹的命令去执行,PWD代表是环境变量,就是它肯定能读取到。比如$PWD它是代表是环境变量,然后像下面也是一样,就是这个地方。所以说的话,如果你知道这些环境变量的名称,那么你可以通过这些方法去读任何你想要的内容。比如像这个地方没有这杠的话,就是IFS1那么它可能就不知道自己是个IFS这是这样的一个效果。所以的话就是命令执行的话,这些空格的一些过滤,我就先讲这么多了,那么在下一次过程中可能会找到一些例题来讲,或者说去讲一些无字母效的一些问题,这次就先这样了。