使用Fiddle 5 自动转发打造自动微信图片采集器
Fiddle 是用C#写出来的,它包含一个简单却功能强大的基于JScript .NET 事件脚本子系统,它的灵活性非常棒,可以支持众多的http调试任务,并且能够使用.net框架语言进行扩展。他的主要功能有查看通讯数据(Observe Traffic)、断点调试、修改通讯数据(Modify Traffic)、保存(载入)通讯数据(Save-And-Load Traffic)、支持脚本拓展(Extend Fiddler),今天我们通过一个案例来体会下Fiddler 强大的脚本拓展(Extend Fiddler)功能。
1、系统目的:用Fiddler抓取微信WEB端包,然后通过Fiddler代理POST抓到的内容到自己的阿里云服务器,
最后通过PHP CURL 下载图片,最后展示出来。
2、情景描述图:
准备工具:
1、Fiddler 5.0。
2、谷歌浏览器。
3、一套自己的应用系统(我用的是阿里云centos7+thinkphp5.0)。
4、一个可以通过网页登录的微信号(必须一年以上的微信号,否则无法web登录)。
下面正式开始:
1、用谷歌浏览器打开微信WEB(https://wx.qq.com/)网站,登录微信号,注意必须 为一年以上的老微信号才能登录微信 WEB端。
2、去Fiddler官方网址(https://www.telerik.com/download/fiddler)下载Fiddler5.0,安装完成后点击 tool->option 做如下设 置:打开启动Fiddler 点击菜单Tools->options-Https,下图配置:
设置HTTPS证书
设置代理与远程连接:
导出证书到桌面:
修改Fiddler script脚本,在脚本后面增加一个函数:
// OnDone 表示一个会话结束后触发的函数
static function OnDone(oSession: Session){
/*要捕捉微信WEB端返回的这个链接地址
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=q09H5HU2Tb&skey=@crypt3b3& pass_ticket=M8ke%252FU55sYmaIglv%252F%252F5y%252FadSqwgdAxZoIFn%252BTvxqla7HCXaI%252F0SNnNU%252F%252BB3s7pHu
*/
/*请求主体
{"BaseRequest":{"Uin":11规范的过5115,
"Sid":"q09H5H",
"Skey":"@crypt_3",
"DeviceID":"e07350043"},
"SyncKey":{"Count":7,"List":[{"Key":1,"Val":682191962},
{"Key":2,"Val":682192257},
{"Key":3,"Val":682192244},
{"Key":11,"Val":682191300},
{"Key":201,"Val":1533960420},
{"Key":1000,"Val":1533942242},
{"Key":1001,"Val":1533942314}]},
"rr":-657288573}
*/
/*返回主体
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
},
"AddMsgCount": 1, //是一条新的消息
"AddMsgList": [{
"MsgId": "3261083751916094449",
"FromUserName": "@fe88639gdfgfhsghtreh86209da10",
"ToUserName": "@egfdgfdgrdhdfhga0",
"MsgType": 3, //类型为3代表是一条图片消息
"Content": "@b23142cbdea6d4afa0975c5dfd1f6df25c6af5763521a14ef2a441c14677d6bd6220985805ebf78f84bfc42fccd08faa4ff9630994afdf22382218de1f85c6524767791614b1a04415fc26209d05029cdf7bc8f6cdd1abbf6a2ab7c75001dfcc5ef7376fa9ddc1698d39273e4a6d6b56cfc7ebdf93f6bb7417622d81e928d50c7a1fff932cd816cf3e0b072c00713aa458ff3bb4af11a6661dea846739eb860c01e2943365655da165c164b468e273a852d7ba35aefbb475bf35e49c0a09b5040deeee08c703482b7f1732288d92dc59d4dd474a477fcfef15b6624164090fa85ce534aa1d6e5d380fcd420dd5618e2436d07b5dfc1532ba53a0aa37957602e0e22420e41d881e05527bdf562eec93825f602d38113f0bb1931d6ee162bdb059b6916f0ace8bb09052948a763a2d1fe30b5b08d0d0e9d5d6698e81ac2479699ace2e31bd8a12a621ce2a5fd853cab3ac180c5b4b05092a0ea4d98b5cf1b83afdcf062ca0551ba53d32b5b6ee6d5fa036cbe3f40b321a5657f9a1bef35c2875dee61afe591fd278d3454b961732ed7d5cfcaadb6e709b93fb28ab837a84a4f2577dd7765c41d3ae3b3cb41dbe616ce6b84adaa44172eef3eb7a26c93f2714b5809a10be65bb94f97bb4da502d7042294aa93bdef8b3b538cc7fe771745fafd371c22e4d46771b2437c580b28a936af826484f9fd0b551582fa08b1274104d624d06a149222d43379ca796b7a5f09b689f26573adf91f74138ed60df6e1b22861d0ee0136b09f76916ac4b8c3c63e1af96acb459107ae8f4cb5e9bac07b3db45ec3e1c99911bb8d202fc8a8324929f1cff58cb22c0c83f2e38de8efc0f74b8056297e6c93df58cd18adebd05b7cd7a377a902333cae7024ab3ab02b562b0e3a71b6e89b5bf7ff32497a3917ae107cb94de9af97e67fe1c8bd84dfd79482b33f19d351a53368451622063db0e349faaf13a0f978bbdac45bebdb44e2fa350820143f886db8bb69a33813a5c08c25a28ba93",
"Status": 3,"ImgStatus": 2,"CreateTime": 1533960611,"VoiceLength": 0,"PlayLength": 0,
"FileName": "","FileSize": "","MediaId": "","Url": "",
"AppMsgType": 0,"StatusNotifyCode": 0,"StatusNotifyUserName": "",
"RecommendInfo": {"UserName": "","NickName": "","QQNum": 0,.....
*/
/* 1、如果主机是来自于wx.qq.com的请求。
2、请求串中包含"mmwebwx-bin/webwxsync"。
3、请求主体长度大于300。
4、返回主体长度大于1000。
*/
if((oSession.RequestHeaders["Host"] == "wx.qq.com") && (oSession.RequestHeaders.RequestPath.IndexOf('mmwebwx-bin/webwxsync') != -1) && (oSession.GetResponseBodyAsString().Length > 1000)&&(oSession.GetRequestBodyAsString().Length > 300))
{
/* 获取当前回话请求主体并转成数组 */
var requestbody = eval("("+oSession.GetRequestBodyAsString()+")");
/* 获取当前回话返回主体并转成数组 */
var responsebody = eval("("+oSession.GetResponseBodyAsString()+")");
/*一条新消息,如果发的是图片3表示是图片 */
if((responsebody['AddMsgCount']== "1")&&(responsebody['AddMsgList'][0]['MsgType'] == "3"))
{
/*获取图片地址wx_img_url */
var wx_img_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg?&MsgID="+responsebody['AddMsgList'][0]['MsgId']+"&skey="+requestbody['BaseRequest']['Skey'];
/*立即创建并发送一个新的请求 */
/*创建新的POST请求主体包含微信图片真实地址,cookie值*/
var str_cookie = oSession.RequestHeaders['Cookie'];
var str_requestbody ="wx_img_url="+wx_img_url+"&wx_cookie=Cookie: " + str_cookie;
var bty_requestbody=System.Text.Encoding.Default.GetBytes ( str_requestbody );
/*创建新的requesheaders对象 */
var currentrequestheaders = new HTTPRequestHeaders();
/*设置请求头*/
var str_requestheaders = "POST /xxx/Wx/index HTTP/1.1"+"\r\n"+
"Host: www.xxxx.cn"+"\r\n"+
"Connection: keep-alive"+"\r\n"+
"Content-Length: "+str_requestbody.Length+"\r\n"+
"Cache-Control: max-age=0"+"\r\n"+
"Origin: http://www.baidu.com"+"\r\n"+
"Upgrade-Insecure-Requests: 1"+"\r\n"+
"Content-Type: application/x-www-form-urlencoded"+"\r\n"+
"User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"+"\r\n"+
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"+"\r\n"+
"Referer: http://www.baidu.com"+"\r\n"+
"Accept-Encoding: gzip, deflate"+"\r\n"+
"Accept-Language: zh-CN,zh;q=0.9"+"\r\n"+
Cookie: thinkphp_show_page_trace=0|0; admin_username=admin; _d_id=af7285c37b41ad8afa27eee9343fa1"+"\r\n"+
"Pragma: no-cache"+"\r\n"+
"\r\n";
currentrequestheaders.AssignFromString(str_requestheaders);
/*是否为https,默认为http,如果你接收服务器为https这里要设置*/
currentrequestheaders.UriScheme="https";
/*通过Fiddler代理发起request请求 */
FiddlerApplication.oProxy.SendRequest(currentrequestheaders,bty_requestbody,null);
/* FiddlerApplication.oProxy.SendRequest(oSession.RequestHeaders,oSession.ResponseBody,null);*/
}
}
}
向你的微信发送图片后:
查看抓到的这包,1、为微信群组用户在群组中发送图片后,微信服务器推送到你WEB微信端时被Fiddler抓取到的。
Fiddler发送到阿里云的数据包:
阿里云应用服务器接收Fiddler post过来的图片地址与cookies,并通过curl下载图片:
后台控制器代码:
$wx_img_url = $this->request->post("wx_img_url");
$MsgID = $this->request->post("MsgID");
$skey = $this->request->post("skey");
$cookie = $this->request->post("wx_cookie");
$img_url = $wx_img_url . "&MsgID=" . $MsgID . "&skey=" . $skey;//微信图片URL地址
$my_cookies = preg_replace('/(?
//CURL下载图片
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 跳过ssl验证
curl_setopt($ch, CURLOPT_HTTPHEADER, array());
curl_setopt($ch, CURLOPT_COOKIE, $my_cookies );
curl_setopt($ch, CURLOPT_URL, $img_url );
ob_start();
curl_exec($ch);
$return_content = ob_get_contents();
ob_end_clean();
$d_path = 'upload/' . date('Ymd');
if (! file_exists($d_path)) {
mkdir($d_path);
}
$img_path = $d_path . '/' . time() . '.png';
$fp = fopen($img_path, "a");
$flag = fwrite($fp, $return_content); // 写入文件
return array(
'flag' => $flag,
'savepath' => $img_path
);
最后前端显示出图片:
踩过的坑: