admin管理员组文章数量:1516870
最近拼多多客服软件暴露一个极端批量登陆功能,不需要账户密码登陆,不需要扫码,其实技术原理很简单。
原理:通过微信接口获取店铺列表,然后通过店铺ID获取微信的Token,直接将微信Token注入cefsharp即可实现登陆。
使用到的组件:
1.cefsharp,谷歌浏览器开源组件
2.Titanium数据包分析组件
实现方法:
1.先构建数据包拦截类,数据包拦截类官方示例稍微改动一下即可。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Titanium.Web.Proxy;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Http;
using Titanium.Web.Proxy.Models;
namespace PddService.FiddlerEx
{
public class NetFiddler
{
Action<int,string> LogAction { get; set; }
Action<string> DebugLog { get; set; }
public NetFiddler(Action<int, string> _LogAction, Action< string> _DebugLog)
{
LogAction = _LogAction;
DebugLog = _DebugLog;
}
public ProxyServer proxyServer = new ProxyServer();
public void StartRun(Action<int,string> _runCallBack)
{
try
{
proxyServer.BeforeRequest += OnRequest;
proxyServer.BeforeResponse += OnResponse;
//proxyServer.CertificateManager.TrustRootCertificate(true);
//proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.DefaultWindows;
//proxyServer.CertificateManager.EnsureRootCertificate();
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8036, true)
{
// Use self-issued generic certificate on all https requests
// Optimizes performance by not creating a certificate for each https-enabled domain
// Useful when certificate trust is not required by proxy clients
//GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password")
};
//explicitEndPoint.BeforeTunnelConnect += OnBeforeTunnelConnect;
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();
//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
foreach (var endPoint in proxyServer.ProxyEndPoints)
Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
// Only explicit proxies can be set as system proxy!
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitEndPoint);
// wait here (You can use something else as a wait function, I am using this as a demo)
// Unsubscribe & Quit
// explicitEndPoint.BeforeTunnelConnect -= OnBeforeTunnelConnect;
_runCallBack(0,"ok");
}
catch(Exception ex)
{
DebugLog(ex.StackTrace);
_runCallBack(-1,ex.Message);
}
//proxyServer.CertificateManager.TrustRootCertificate();
}
public void StopRun()
{
if(proxyServer.ProxyRunning)
{
proxyServer.BeforeRequest -= OnRequest;
proxyServer.BeforeResponse -= OnResponse;
proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
proxyServer.DisableAllSystemProxies();
proxyServer.Stop();
}
}
private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e)
{
string hostname = e.HttpClient.Request.RequestUri.Host;
if (hostname.Contains("dropbox.com"))
{
// Exclude Https addresses you don't want to proxy
// Useful for clients that use certificate pinning
// for example dropbox.com
e.DecryptSsl = false;
}
}
public async Task OnRequest(object sender, SessionEventArgs e)
{
Console.WriteLine(e.HttpClient.Request.Url);
DebugLog(e.HttpClient.Request.Url);
// read request headers
var requestHeaders = e.HttpClient.Request.Headers;
var method = e.HttpClient.Request.Method.ToUpper();
if ((method == "POST" || method == "PUT" || method == "PATCH"))
{
// Get/Set request body bytes
byte[] bodyBytes = await e.GetRequestBody();
e.SetRequestBody(bodyBytes);
// Get/Set request body as string
string bodyString = await e.GetRequestBodyAsString();
e.SetRequestBodyString(bodyString);
// store request
// so that you can find it from response handler
string url = e.HttpClient.Request.RequestUriString;
e.UserData = e.HttpClient.Request;
if (e.HttpClient.Request.RequestUri.AbsoluteUri.StartsWith(""))
{
LogAction(0,bodyString);
string ok = "";
}
}
// To cancel a request with a custom HTML content
// Filter URL
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("google.com"))
{
e.Ok("<!DOCTYPE html>" +
"<html><body><h1>" +
"Website Blocked" +
"</h1>" +
"<p>Blocked by titanium web proxy.</p>" +
"</body>" +
"</html>");
}
// Redirect example
if (e.HttpClient.Request.RequestUri.AbsoluteUri.Contains("wikipedia.org"))
{
e.Redirect("");
}
}
// Modify response
public async Task OnResponse(object sender, SessionEventArgs e)
{
// read response headers
var responseHeaders = e.HttpClient.Response.Headers;
DebugLog(e.HttpClient.Request.Url);
//if (!e.ProxySession.Request.Host.Equals("medeczane.sgk.gov.tr")) return;
if (e.HttpClient.Request.Method == "GET" || e.HttpClient.Request.Method == "POST")
{
string url = e.HttpClient.Request.RequestUriString;
if (e.HttpClient.Response.StatusCode == 200 && e.HttpClient.Request.RequestUri.AbsoluteUri.StartsWith(""))
{
byte[] bodyBytes = await e.GetResponseBody();
e.SetResponseBody(bodyBytes);
string body = await e.GetResponseBodyAsString();
e.SetResponseBodyString(body);
LogAction(1, body);
}
}
if (e.UserData != null)
{
// access request from UserData property where we stored it in RequestHandler
var request = (Request)e.UserData;
}
}
// Allows overriding default certificate validation logic
public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e)
{
// set IsValid to true/false based on Certificate Errors
if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
e.IsValid = true;
return Task.CompletedTask;
}
// Allows overriding default client certificate selection logic during mutual authentication
public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e)
{
// set e.clientCertificate to override
return Task.CompletedTask;
}
}OnRequest:
这个是获取微信票据wechatToken,这个票据在后续获取每个店铺微信Token需要到
OnResponse:这个是拦截服务器返回数据,其实就是返回的店铺信息列表,里面包括店铺的userID,userName登陆信息。
获取微信店铺列表的地址是
2.通过wechatToken和店铺的userID获取wxToken,用post就能获取了。
传递userID和wxToken即可获取
public Result WxPost(int userID, string wxToken)
{
lock (obj)
{
var postDataStr = new {
userId=userID,
wechatToken=wxToken,
smsCode=""
};
Result ret = new Result() { PostResult = null, PostState = false };
string url = "";
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
webReq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
SafeLink(webReq, url);
webReq.Method = "POST";
webReq.Accept = "application/json";
webReq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat";
webReq.ContentType = "application/json";
webReq.Referer = "";
webReq.Headers.Add("accept-encoding", "gzip, deflate, br");
webReq.MaximumAutomaticRedirections = 1;
webReq.AllowAutoRedirect = true;
try
{
string postData = Newtonsoft.Json.JsonConvert.SerializeObject(postDataStr);
byte[] buf = Encoding.UTF8.GetBytes(postData);
byte[] byteArray = System.Text.Encoding.Default.GetBytes(postData);
Stream newStream = webReq.GetRequestStream();
newStream.Write(buf, 0, buf.Length);
newStream.Close();
HttpWebResponse myResponse = (HttpWebResponse)webReq.GetResponse();
using (StreamReader sr = new StreamReader(myResponse.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
ret.PostResult = sr.ReadToEnd();
sr.Close();
myResponse.Close();
ret.PostState = true;
}
}
catch (Exception ex)
{
}
return ret;
}
}操作步骤:
1.运行程序,启动Titanium代理
2.运行微信电脑版本,点击小程序,打开拼多多商家版
3.点击【店铺管理】
4.点击【切换账户】
到这里,店铺列表和wechatToken都能被取到了,接下来就是如何循环读取微信Token啦。
版权声明:本文标题:Titanium.web.proxy助力拼多多购物体验升级:揭秘无验证码、扫码登陆大法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/biancheng/1772300560a3273303.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论