前言
DVWA四个等级:
- 没有做过滤
- 做了基础过滤(中级)
设置了命令黑名单’&&‘跟’;'过滤了 - 做了比较强的过滤
- 从逻辑上改了,将ip切割为四个部分,且都为数字
命令注入原理
原理: 通过web程序在服务器上拼接系统命令
危害: 如果在web应用使用的是root权限,则该漏洞可以导致攻击者在服务器上执行任意命令
一、注入流程
1.利用管道符 命令执行漏洞
执行ping命令以后查看目录
127.0.0.1|dir
2.命令管道符的补充:允许执行多条命令的符号
Windows系统支持的管道符如下:
" |" 前面命令输出结果作为后面命令的输入内容
"|| " 如果前面的语句执行失败,则执行后面的语句,前面的语句只能为假才行。
"& " 两条命令都执行,如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。
"&& " 如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
Linux系统支持的管道符如下:
" ; " 执行完前面的语句再执行后面的语句、同时执行多条命令。
" | " 显示后面语句的执行结果。
" || " 当前面的语句执行出错时,执行后面的语句。
" & "两条命令都执行,如果前面的语句为假则执行执行后面的语句,前面的语句可真可假。
"&&"如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句为真则两条命令都执行,前面的语句只能为真。
Linux系统还可以使用
分号(;)同时执行多条命令
还可以使用
重定向(>)在服务器中生成文件
或是使用(<)文件写入127.0.0.1&echo test>c:\1.txt
在c盘生成一个1.txt
二、源码分析
第一等级
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ]; //存放变量
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// 判断这个服务器的操作系统是不是windows、确定操作系统并执行ping命令
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
Shell exec
函数:让PHP的网页程序可以执行一些操作系统的命令、
如果不对用户输入的命令进行过滤,那么理论上就可以执行任意系统命令,
也就是相当于直接获得系统级的shell
命令执行语句
127.0.0.1 | net user
127.0.0.1 | net user test 123/add
127.0.0.1 | net localgroup admin istrators test/add
Windows下使用net user命令管理账户 net user 命令用法
1.查看所有用户 net user
2.查看单个用户信息net user 用户名
3.增加用户net user 用户名 密码 /add
4.删除用户net user 用户名 /delete
5.修改密码net user 用户名 *
最高等级
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$target = $_REQUEST[ 'ip' ];
$target = stripslashes( $target );
// Split the IP into 4 octects
$octet = explode( ".", $target );
// Check IF each octet is an integer
if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
// If all 4 octets are int's put the IP back together.
$target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
is_numeric:用来判断后面的变量的值是否是一个数字
对你输入的数据进行判断、首先分成四块、挨个判断、
这每一块是不是一个数字、数的个数是不是四个。
只要有一个条件不成立、下面的都不执行、只执行一个else输入一个echo
// Determine OS and execute the ping command.
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
// Windows
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
else {
// Ops. Let the user name theres a mistake
echo '<pre>ERROR: You have entered an invalid IP.</pre>';
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
防御
漏洞防御
Escapeshellcmd
()(一丝key普)函数:把字符串中所有可能瞒过shell而去执行另外一个命令的字符转义,如管道符(|)、分号(;)、重定向(>)、从文件读入(<)等
Escapeshellarg
()函数
在给定的字符串两边加上单引号,并把字符串中的单引号转义,这样这个字符就可以安全地作为命令的参数
修改low级别网页文件
dvwa\vulnerabilities\exec\source\low.php进行测试
$target = $_REQUEST[ 'ip' ];
下面加$target = escapeshellcmd() ($target);
问题一:乱码
解决方法:将dvwa
目录下includes
文件夹中dvwaPage.inc.php
文件的编码格式由utf8
改为GBK