DVWA:全等级命令行注入

全等级命令行注入

  Command Injection,即为命令行注入,是指在某些需要输入数据的位置,构造恶意的代码破坏原先的语句结构。而如果系统缺少有效的过滤,入侵者最终就会达到破坏数据、信息泄露甚至掌控电脑的目的。多数命令都采用PHP命令,PHP命令注入攻击漏洞是PHP应用程序中常见的脚本漏洞之一。

 

LOW

  我们把难度调节为LOW,然后进入Command Injection:

   我们看到文本框左边的提示,输入你的IP地址,我们输入本机的IP试一下,这里我设置的IP地址是:192.168.1.1,输入,点击Submit,发现变成了这样:

   只要使用过Linux命令的都知道,ping命令是测试网络连通性的最基本命令,当在ping后面加IP地址的时候,就可以尝试连接那个IP来测试连通性,测试成功后就会出现上图这些语句,说明我们连接成功。

  所以其实在你输入的每一条内容之前,都相当于自动加上了“ping”这个字符,我们的目的当然还是获取到数据,现在这个隐性的ping的添加,使得我们输入语句有了困难,我们势必要想办法绕过它。使得我们的语句正常。这个时候,我们就需要打开源码查看一下,具体的路径如下图:

 

   我们看到上图中选中的地方使用了未知的函数,所以需要明确他们的作用,我们才能正确分析语句:

stristr(string,search,before_search)

  stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回FALSE。参数string规定被搜索的字符串,参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的ASCII值的字符),可选参数before_true为布尔型,默认为“false”,如果设置为“true”,函数将返回search参数第一次出现之前的字符串部分。

php_uname(mode)

  这个函数会返回运行php的操作系统的相关描述,参数mode可取值”a” (此为默认,包含序列”s n r v m”里的所有模式),”s”(返回操作系统名称),”n”(返回主机名),” r”(返回版本名称),”v”(返回版本信息), ”m”(返回机器类型)。

  可以看到,服务器通过判断操作系统执行不同ping命令,但是对ip参数并未做任何的过滤,导致了严重的命令注入漏洞。

   window和linux系统都可以用&&来执行多条命令,而其实使用不同符号作用也不同,根据不同的需求来选择不同的连接符号:

  Command 1&&Command 2

  先执行Command 1,执行成功后执行Command 2,否则不执行Command 2

  Command 1&Command 2

  先执行Command 1,不管是否成功,都会执行Command 

  Command 1|Command 2

  “|”是管道符,表示将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果。

  我们在这里可以先pingIP地址再执行语句,在文本框中输入192.168.1.1(主机地址)&&net user,真实语句执行时即为:ping 192.168.1.1(主机地址)&&net user,这样就绕开了隐藏的ping字符:

   发现存在乱码?这等于没有获取到啊,我们修改下图中的文件(路径如下),找到dvwaPage.inc.php文件中所有的”charset=utf-8”,修改”charset=gb2312”即可:

   然后输入”127.0.0.1 && net user SUPPORT_388945a0”,得到SUPPORT_388945a0账号的属性,然后就随你开心了,增删改查,改密码账户,都可以操作。

Medium

  还是一样,我们把难度调到中级,打开命令注入:

   我们打开PHP文件看源码,发现与Low相比,这一级进行了防范措施,服务器端对ip参数做了一定过滤,即把”&&” 、”;”删除,本质上采用的是黑名单机制,因此依旧存在安全问题。事实上没有什么用处,因为过滤的只有‘&&’和‘;’,所以“&”不会有影响,我们继续构造语句即可,这里构造的方法多种多样,可以构造没有被删除的&:

  192.1681.1&net user   

   也可以利用它本身删除符号的漏洞,;(分号)会被删除,所以我们在&&中间加一个;,躲避它的转义即可: 

  192.168.1.1&;&net user

   其余与Low相同,不再赘述。

High

  打开源码,发现几乎所有的路全部堵死了,然而我们仔细看下图选中的地方:

   “|”符号后面竟然有个空格?看来还是给我们留下一线生机,所以我们用“|”(管道符)来构造语句:

  192.168.1.1|net user

  因为管道符的这条语句将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果,所以返回的结果里,只有用户名和分组以及后面访问属性的字段:

Impassble

  打开代码,发现写的非常严谨,无法使用命令行注入。

原文地址:https://www.cnblogs.com/FHBBS/p/12449516.html