示例代码
搭建环境:
nginx(1.24.0)+php(5.6.40)
session_start();
function
client_ip
()
{
return
!
empty
($_SERVER[
'HTTP_X_FORWARDED_FOR'
]) ? $_SERVER[
'HTTP_X_FORWARDED_FOR'
] : $_SERVER[
'REMOTE_ADDR'
];
}
$ip = client_ip();
if
(!filter_var($ip, FILTER_VALIDATE_IP) || !in_array($ip,
array
(
'localhost'
,
'127.0.0.1'
))){
die
(htmlspecialchars(
"Not allowed!n"
));
}
if
(!
isset
($_SESSION[
'auth'
])){
header(
"Location: error.php"
);
}
echo
call_user_func($_GET[
'cmd'
], $_GET[
'arg'
]);
请查看上述代码,找出其中的漏洞。
时间到
漏洞位置
if
(!filter_var($ip, FILTER_VALIDATE_IP) || !in_array($ip,
array
(
'localhost'
,
'127.0.0.1'
))){
die
(htmlspecialchars(
"Not allowed!n"
));
}
echo
call_user_func($_GET[
'cmd'
], $_GET[
'arg'
]);
漏洞原理
代码验证X-Forwarded-For标头不够严格,攻击者可以伪造X-Forwarded-For:127.0.0.1进行绕过检测。攻击者在$_session['auth']中没有有效的会话,这会自动导致重定向到另一个页面。重定向之后代码会继续向下运行,因而重定向没有任何效果,代码运行到call_user_func(),它允许执行任意的PHP代码或命令。
漏洞复现
Burpsuite抓包,更改请求包中的
X-Forwarded-For:127.0.0.1
提交参数:?cmd=exec&arg=pwd
修复方案
对于
对于call_user_func函数造成的命令执行漏洞,需要对`$_GET['cmd']`和`$_GET['arg']`进行严格的过滤和验证。只允许执行白名单中的命令,并且只允许这些命令接受预定义的参数。对输出可以使用`htmlspecialchars()`函数来转义。
相关知识
call_user_func
call_user_func 是 PHP 中的一个函数,它用于调用由用户定义的回调函数。这个函数可以调用任何可调用的 PHP 对象,包括函数、方法、闭包等。
call_user_func(callable
$callback
, ...
$args
)
-
$callback:要调用的回调函数。这是一个必需参数,可以是一个函数名、方法名、闭包等。 -
...$args:要传递给回调函数的参数列表。这是一个可选参数,你可以根据需要传递任意数量的参数。
call_user_func 函数会调用 $callback 指定的回调函数,并将传递的参数列表作为回调函数的参数。它会返回回调函数执行的结果。
原文始发于微信公众号(洞源实验室):代码审计 | call_user_func 命令执行
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论