简述CMS判别的方法

/ 0评 / 0

一直想写这篇文章来着,但是最近心比较累,还有某些事干扰着,就一直拖拖拖,现在回到家了,趁着还没去苏杭旅游了,就先补补这篇文章把。

CMS判别,可以说是渗透测试中最爽的一个方式,现在的网站都很少自己编写整体框架的,一些小众的CMS,也就是自己编写的内容管理系统,漏洞会很多的,就像我博客旁站一个卖酒的,用的ZMCMS,SQL注入漏洞一大堆,重点是后台还有个功能防止SQL并记录 IP ,,这个功能是开着的,但是啥都没记录,感觉就是个摆设。。。

如果渗透一个站点,能知道这个站点用的什么CMS,那就可以直接去网上寻找公开的漏洞,有针对性的攻击,如果没有最新的漏洞,那就自己下载源码,用工具去审计审计,看看能不能找到存在的漏洞,我准备等彻底静下心来,就去学学代码审计。

所有市面上的CMS判别无外乎就是特征式的判别,每个CMS都会有各自的不同的特征,而判别也就是根据这些固定的特征去判别的。

1,利用 robots.txt 去判别

robots.txt 是一个SEO 中的公开的一个规则,一般网站在被网络爬虫爬取收录时,会进行全部爬取,如果设置了这个文件,那网络爬虫看到这个文件就会不去爬取里面所禁止爬取的,有些CMS会自动生成这个文件,有的还会直接在里面显示该CMS特征。

一开始我是纯粹的直接写程序流程的,不过看了 loid表哥 给我样板后,我感觉我变懒,我直接写个整体函数,一套用就行了。毕竟他提供的样板,太那个啥了,我都不需要改啥 = =!

这里我们先导入 requests 和 Re 这两个模块,一个用来请求连接,一个用来正则匹配。

import requests
import re

然后,我们创建一个把网址地址和探测地址连接在一起,如果返回 200 的话,就把整体网址的 url 返回到函数本身。

def getmatch(url, fingerfile):
    response = requests.get(url + fingerfile)
    if response.status_code == 200:
        return response.content

其中 response.status_code 是获取网址的返回码,response.content 是返回请求的这个页面的 txt 形式。这个函数主要用来我们匹配时用的。

我们再创建一个字典,这里 loid表哥 他是用的函数返回来呈现的字典,等调用的时候,转为元祖,我是第一次见 = =!

def robotsList():
    return {
        "Discuz": [r"Discuz",r'/uc_client/'],
        "Dedecms": [r"/plus/"]
            }

这里就以这两个例子为代表把,毕竟 robots.txt 这个判别方法,很多时候都无法很正确的判别出来。

最后就是调用起来的代码。

robots = robotsList()
for finger, values in robots.items():
    for value in values:
        output = getmatch("http://v57.demo.dedecms.com/", "/robots.txt")
        if re.search(value, output):
            print "CMS: " + finger
            print "特征文件: " + "robots.txt"
            print "特征值: " + value
            exit(0)

这里可能不好理解,第一步我们把那个字典函数赋值给 robots ,然后利用 items 这个字典函数,把字典文件转换为元组的形式,这样,就可以用 for 循环来一个一个遍历,其中 finger 为键值对中的键,也就是刚才列的那个字典里的名字,而 values 是值,也就是特征。

然后,我们继续在此循环 values 这个特征,然后用 if 判断的形式,来看这个页面是否存在该特征字母,如果存在,就直接输出。

效果图:

CMS: Dedecms
特征文件: robots.txt
特征值: /plus/

2,利用 MD5 来判别

对比 MD5 值一般都是用来对比,CMS 中那些特定的图标或者图片,特有的那些,很少用来对比 CSS,或者 javascript ,我看的大多数都是这样的,这里我就只简单的列一下对比 MD5 值的。

我们先导入 md5 这个模块

import hashlib

然后写一个加密的函数,用来和我们的指纹库对比,是否存在一致,进行判断。

def md5en(string):
    m = hashlib.md5()
    m.update(string)
    return m.hexdigest()

这里 m = hashlib.md5() 使用来生产一个 md5 的哈希值的对象,然后用 m.update() 来输入你需要加密的字符串或者其他什么的,最后用 md5.hexdigest() 来获取加密的哈希值。

loid表哥 他给我的字典是存放在 txt 文本里的,然后利用 os 模块去打开,然后再用切割的方法整理出来,最后组成一个元组的形式,我又不造大工具,只是简单的说下这个方法,所以就弄了一个简单的字典。

md5 = {
    "dedecms":{"/favicon.ico":"7ef1f0a0093460fe46bb691578c07c95"},
    "dicusz":{"/favicon.ico":"c028c4822428e83a358c60a93ef65381"}
}

字典放好了,我们就调用上面用过的那个 getmatch( ) 这个函数。

for a in md5 :
    for b in md5[a]:
        geturl = getmatch("http://v57.demo.dedecms.com",b)
        if md5pd(geturl) == md5[a][b] :
            print "CMS: "+ a
            print "特征文件: "+ b
            print "MD5: "+ md5[a][b]
            exit(0)

这里的步骤就特别简单了,利用两层 for 循环把最里面的字典也给遍历出来了。这里 md5 是字典,a 是字典里的 键 ,也就是 dedecms ,然后第二层 md5[a] 就是把里面的 dedecms 这个字典里面的 /favicon.ico 给遍历出来了,那剩下的 md5[a][b] 就更简单了,就是 md5 值了。

最后的效果和上一个一样的。

 

CMS: dedecms
特征文件: /favicon.ico
MD5: 7ef1f0a0093460fe46bb691578c07c95

 

3,访问特定路径或者特定文件来判别

每个 CMS 总会有和其他 CMS 不同的地方,或者说自己特有的路径和特定文件,比如帝国 CMS 的数据库路径会在 /e/data/ 这个问价里里,还有 wp 的这个常用于博客的 CMS ,他的后台肯定是在 /wp-admin/ 这个路径下,这就是独有的特征,我们只要通过判别是否存在这个文件,就可以模糊的测试这个是什么 CMS 。

先上一下路径字典,演示一下。

lujin = {
    "dedecms":("/data/index.html","/templets/default/style/dedecms.css")
}

然后继续利用 for 循环去判断返回码来验证。

for a in lujin:
    for b in lujin[a]:
        c = "http://v57.demo.dedecms.com"+ b
        d = requests.get(c)
        e = d.status_code
        if e == 200 :
            print "CMS: "+ a
            print "特征路径: "+ c
            exit(0)
        elif e == 404 :
            pass

不过这个写法好慢啊 = =!最后的结果为:

CMS: dedecms
特征路径: http://v57.demo.dedecms.com/templets/default/style/dedecms.css

4,网站首页底部标识或者后台登录标识

一般有些 CMS 都会在首页的底部,直接显示出该网站使用了什么 CMS ,比如织梦的 Powered by DedeCMS_V57_UTF8_SP1 ,或者南方数据站点的  All Rights Reserved Theme by 南方数据  ,不过有些人会修改这些标识,改成自己网站的。

后台标识这个比较好,因为这些大部分都是无法修改的,如果自己见的后台多了,很容易猜出来是使用了什么 CMS 。

总结:

上述的除了前三个是需要靠强大的指纹库去用工具扫,第四个是靠经验来判别,还有一种就是看报错,我记得是哪个 CMS 来着,通过报错页面就会显示出该CMS的名字,不记得了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注