加固-03(P0-02): 删除远程在线更新链(供应链 RCE 向量)
- admin/ajax.php: checkupdate / downloadupdatepacks / unzippacks 三个 端点合并为统一禁用存根(返回 JSON "远程更新已禁用(安全加固)"); 原逻辑从作者第三方域 (download.wenquan6.cn / download.bwenquan.com) 下载 zip 并解压到 Web 目录、再引导浏览器访问 install.php, 攻击者控制该域即可向所有部署实例推送恶意代码(供应链 RCE)。 - 删除辅助函数 get_zip_originalsize() 与 getFile()(仅更新链使用)。 - admin/html/welcome.html 与 admin/welcome.html: 移除"检查系统更新" 按钮及 function update() 整段 AJAX 链,替换为静态说明文案。 - admin/ajax.php: HTTP_USER_AGENT 比较改用 ?? 回退,消除无 UAgent 客户端触发的 Notice(UAgent 会话锁定行为保持不变)。 验证: php -l 通过;登录态调用三端点均返回禁用 JSON; UAgent 锁定对无 UAgent 客户端正确拒绝(code:-3)。
This commit is contained in:
+11
-87
@@ -56,7 +56,7 @@ if ($_GET['mod'] === 'login'){
|
||||
if (!$result = $db->select_first_row('sq_admin','*',array('username'=>$_SESSION['admin_username'],'password'=>$_SESSION['admin_password']),'AND')){
|
||||
die(json_encode(array('code'=>-2)));
|
||||
}
|
||||
if ($_SERVER['HTTP_USER_AGENT'] !== $_SESSION['admin_HTTP_USER_AGENT']){
|
||||
if (($_SERVER['HTTP_USER_AGENT'] ?? '') !== $_SESSION['admin_HTTP_USER_AGENT']){
|
||||
die(json_encode(array('code'=>-3)));
|
||||
}else{
|
||||
die(json_encode(array('code'=>1,'username'=>$_SESSION['admin_username'],'adminqq'=>$_SESSION['admin_qq'])));
|
||||
@@ -73,7 +73,7 @@ if ($_GET['mod'] === 'login'){
|
||||
header('Location: login.html');
|
||||
die();
|
||||
}
|
||||
if ($_SERVER['HTTP_USER_AGENT'] !== $_SESSION['admin_HTTP_USER_AGENT']){
|
||||
if (($_SERVER['HTTP_USER_AGENT'] ?? '') !== $_SESSION['admin_HTTP_USER_AGENT']){
|
||||
echo '没有登录:code:-3';
|
||||
header('Location: login.html');
|
||||
die();
|
||||
@@ -1062,31 +1062,15 @@ switch ($_GET['mod']){
|
||||
|
||||
break;
|
||||
case 'checkupdate':
|
||||
die(-1);
|
||||
$newver = curl_request('http://download.bwenquan.com/update/shouquanver.txt');
|
||||
|
||||
if ($newver > $G['siteinfo']['ver'] ){
|
||||
die('1');
|
||||
}else{
|
||||
die('-1');
|
||||
}
|
||||
|
||||
break;
|
||||
case 'downloadupdatepacks':
|
||||
set_time_limit(0);
|
||||
if(!getFile('http://download.wenquan6.cn/upload/shouquan/'.$G['siteinfo']['ver'].'.zip','../update/',$G['siteinfo']['ver'].'.zip')){
|
||||
die(json_encode(array('code'=>'-1','msg'=>'下载文件失败!')));
|
||||
}else{
|
||||
die(json_encode(array('code'=>'1')));
|
||||
}
|
||||
break;
|
||||
case 'unzippacks':
|
||||
set_time_limit(0);
|
||||
if (!file_exists('../update/'.$G['siteinfo']['ver'].'.zip')){
|
||||
die(json_encode(array('code'=>'-1','msg'=>'更新包文件不存在,无法解压')));
|
||||
}
|
||||
get_zip_originalsize('../update/'.$G['siteinfo']['ver'].'.zip','../update/');
|
||||
die(json_encode(array('code'=>'1','updateurl'=>'../../update/'.$G['siteinfo']['ver'].'/install.php')));
|
||||
/*
|
||||
* 安全加固 (P0-02):远程在线更新链整体禁用。
|
||||
* 原逻辑 = 从作者第三方域下载 zip 并解压到 Web 目录,
|
||||
* 再引导浏览器访问 install.php —— 等同于供应链 RCE 入口。
|
||||
* 版本升级一律走 git 部署,不再保留在线更新端点。
|
||||
*/
|
||||
die(json_encode(array('code' => '-1', 'msg' => '远程更新已禁用(安全加固)')));
|
||||
break;
|
||||
case 'keylog':
|
||||
if (!$result = $db->select_limit_row('sq_log_kami','*','',0,array('keyid'=>$_POST['keyid']),'AND',"ORDER BY time DESC")){
|
||||
@@ -1586,65 +1570,5 @@ switch ($_GET['mod']){
|
||||
default:
|
||||
die('What the fuck');
|
||||
}
|
||||
function get_zip_originalsize($filename, $path) {//解压zip文件
|
||||
$resource = zip_open($filename);
|
||||
while ($dir_resource = zip_read($resource)) {
|
||||
if (zip_entry_open($resource,$dir_resource)) {
|
||||
$file_name = $path.zip_entry_name($dir_resource);
|
||||
$file_path = substr($file_name,0,strrpos($file_name, "/"));
|
||||
if(!is_dir($file_path)){
|
||||
mkdir($file_path,0777,true);
|
||||
}
|
||||
if(!is_dir($file_name)){
|
||||
$file_size = zip_entry_filesize($dir_resource);
|
||||
$file_content = zip_entry_read($dir_resource,$file_size);
|
||||
file_put_contents($file_name,$file_content);
|
||||
}
|
||||
zip_entry_close($dir_resource);
|
||||
}
|
||||
}
|
||||
zip_close($resource);
|
||||
}
|
||||
|
||||
function getFile($url, $save_dir = '', $filename = '', $type = 0) {
|
||||
if (trim($url) == '') {
|
||||
return false;
|
||||
}
|
||||
if (trim($save_dir) == '') {
|
||||
$save_dir = './';
|
||||
}
|
||||
if (0 !== strrpos($save_dir, '/')) {
|
||||
$save_dir.= '/';
|
||||
}
|
||||
//创建保存目录
|
||||
if (!file_exists($save_dir) && !mkdir($save_dir, 0777, true)) {
|
||||
return false;
|
||||
}
|
||||
//获取远程文件所采用的方法
|
||||
if ($type) {
|
||||
$ch = curl_init();
|
||||
$timeout = 5;
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
$content = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
} else {
|
||||
ob_start();
|
||||
readfile($url);
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
//echo $content;
|
||||
$size = strlen($content);
|
||||
//文件大小
|
||||
$fp2 = @fopen($save_dir . $filename, 'a');
|
||||
fwrite($fp2, $content);
|
||||
fclose($fp2);
|
||||
unset($content, $url);
|
||||
return array(
|
||||
'file_name' => $filename,
|
||||
'save_path' => $save_dir . $filename,
|
||||
'file_size' => $size
|
||||
);
|
||||
}
|
||||
/* 安全加固 (P0-02):已删除远程更新链辅助函数 get_zip_originalsize() 与 getFile()
|
||||
(原用于从第三方域下载 zip 更新包并解压到 Web 目录,供应链 RCE 向量) */
|
||||
|
||||
+4
-98
@@ -94,10 +94,8 @@
|
||||
<div class="layui-collapse">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">系统更新</h2>
|
||||
<div class="flow-default layui-colla-content layui-show" id="update">
|
||||
<button class="layui-btn layui-btn-radius layui-btn-normal" style="width: 100%" onclick="update()">
|
||||
立检查更新
|
||||
</button>
|
||||
<div class="flow-default layui-colla-content layui-show" id="update" style="padding:10px;">
|
||||
<span style="color:#999;">远程在线更新已出于安全考虑禁用(供应链风险)。版本升级请通过 Git 仓库获取部署包手动更新。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,100 +201,8 @@
|
||||
|
||||
});
|
||||
|
||||
function update() {
|
||||
var loading = layer.load();
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=checkupdate',
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data === '1') {
|
||||
layer.confirm('发现更新,请问是否立即进行更新?', {
|
||||
btn: ['确定', '取消'] //按钮
|
||||
}, function () {
|
||||
loading = layer.msg('正在下载更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=downloadupdatepacks',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data.code === '1') {
|
||||
|
||||
loading = layer.msg('正在解压更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=unzippacks',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data.code === '1') {
|
||||
loading = layer.msg('正在安装更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: data.updateurl,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
layer.alert(data);
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layer.msg(data.msg);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layer.close(loading);
|
||||
layer.msg(data.msg);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
});
|
||||
} else if (data === '-1') {
|
||||
layer.alert('您当前已是最新版');
|
||||
} else {
|
||||
layer.alert(data);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
/* 安全加固 (P0-02):已移除远程在线更新前端逻辑 (function update / checkupdate / downloadupdatepacks / unzippacks)。
|
||||
原逻辑引导浏览器访问解压出来的 install.php,属供应链 RCE 向量。 */
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
+5
-99
@@ -93,11 +93,9 @@
|
||||
<div class="layui-col-xs12">
|
||||
<div class="layui-collapse">
|
||||
<div class="layui-colla-item">
|
||||
<h2 class="layui-colla-title">检查系统更新</h2>
|
||||
<div class="flow-default layui-colla-content layui-show" id="update">
|
||||
<button class="layui-btn layui-btn-radius layui-btn-normal" style="width: 100%" onclick="update()">
|
||||
立即检查更新
|
||||
</button>
|
||||
<h2 class="layui-colla-title">系统更新</h2>
|
||||
<div class="flow-default layui-colla-content layui-show" id="update" style="padding:10px;">
|
||||
<span style="color:#999;">远程在线更新已出于安全考虑禁用(供应链风险)。版本升级请通过 Git 仓库获取部署包手动更新。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,100 +201,8 @@
|
||||
|
||||
});
|
||||
|
||||
function update() {
|
||||
var loading = layer.load();
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=checkupdate',
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data === '1') {
|
||||
layer.confirm('发现更新,请问是否立即进行更新?', {
|
||||
btn: ['确定', '取消'] //按钮
|
||||
}, function () {
|
||||
loading = layer.msg('正在下载更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=downloadupdatepacks',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data.code === '1') {
|
||||
|
||||
loading = layer.msg('正在解压更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: '../ajax.php?mod=unzippacks',
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
if (data.code === '1') {
|
||||
loading = layer.msg('正在安装更新包', {
|
||||
icon: 16
|
||||
, shade: 0.01
|
||||
, time: 0
|
||||
});
|
||||
$.ajax({
|
||||
url: data.updateurl,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
data: '',
|
||||
success: function (data) {
|
||||
layer.close(loading);
|
||||
layer.alert(data);
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layer.msg(data.msg);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
layer.close(loading);
|
||||
layer.msg(data.msg);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data.code);
|
||||
}
|
||||
})
|
||||
});
|
||||
} else if (data === '-1') {
|
||||
layer.alert('您当前已是最新版');
|
||||
} else {
|
||||
layer.alert(data);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
layer.close(loading);
|
||||
layer.msg('请求失败' + data);
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
/* 安全加固 (P0-02):已移除远程在线更新前端逻辑 (function update / checkupdate / downloadupdatepacks / unzippacks)。
|
||||
原逻辑引导浏览器访问解压出来的 install.php,属供应链 RCE 向量。 */
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user