矛与盾 - 记一次刷票经历

1,036 阅读5分钟

背景

事情是这么开始的。国庆回家和亲戚欢聚一堂,开心嘛,自然要打麻将。

打了几圈下来,一不小心赢了八大姑10块钱。躺在床上,正在美滋滋地数钱。

突然八大姑一个微信找过来,说他的同事的媳妇的妹妹,要参加一个XXX比赛。要刷票!

亲情,伦理,普世价值观一瞬间在心头涌现,手里的钱它突然就不香了。

在这一时刻,我做出了一名党员应有的判断。

拿人钱财,替人消灾。

刷票的一般步骤

就像江湖,只要有投票存在的地方,有会有刷票的人。

《马克思主义基本原理》中应该对这个现象应该有过详细的解释,只是马原的课上我大概率在睡觉,也没怎么听。反正人类社会就没有马原不能解释的🐶。

人们习惯把刷票的人,称为刷子。就比如说我。有时候遇到对手,比拼刷票速度,排行榜上会出现两个票数奇高的选手,你方唱罢我登场,疯狂涨票。

人们惊呼,有两把刷子。

刷票其实是有一些乐趣的,就像游戏一样,升级打怪,步步为营。

1. 绕过微信UA

直接在PC端打开页面,发现有一层微信浏览器的验证。

种情况,通常可能是ua的验证,或者是需要授权openId的验证。先绕过UA试试。把UA修改为:

Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5.255

一发入魂,进入投票界面。投一票试试:

POST: https://op.bookan.com.cn/index.php
-------------------------------
FormData:
    op: ReadScreen.operateSoundLimit
    instanceId: 0
    weChatId: 
    id: 1377928
    level: 2
    uniCode: fbHCGPyaraaRg64oo4tt1570604768281
    type: 2
    key: SXPg6VhOYYeCsiTrDvZZensypfwhbi
    token: 3b18fb13165cc5c86683fcb5ce221b29

其它参数都很好理解,uniCode / key / token 这三个参数在这种时候就显得非常灵性了。显然,这个页面是做了加密参数的校验。

2. 绕过前端加密

全文搜索 operateSoundLimit,找到这个ajax的请求源,打上断点,点击。找到了这个请求的发出地址。

不断反复debug,找到这几个参数的生成函数。由于js是经过压缩混淆,看不懂,没关系,粘出来。

TokenJs := `function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<<t|n>>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<<r%32,n[14+(r+64>>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e<n.length;e+=16)i=l,a=g,d=v,h=m,g=f(g=f(g=f(g=f(g=c(g=c(g=c(g=c(g=u(g=u(g=u(g=u(g=o(g=o(g=o(g=o(g,v=o(v,m=o(m,l=o(l,g,v,m,n[e],7,-680876936),g,v,n[e+1],12,-389564586),l,g,n[e+2],17,606105819),m,l,n[e+3],22,-1044525330),v=o(v,m=o(m,l=o(l,g,v,m,n[e+4],7,-176418897),g,v,n[e+5],12,1200080426),l,g,n[e+6]...`
TokenExecJs := `var zzzaaa = A('BO0KanIsGoOd%s')`

随便找个js执行引擎:otto

func GetToken(key string) string {
   vm := otto.New()
   _, err := vm.Run(TokenJs)
   if err != nil {
      panic(err)
   }
   vm.Run(fmt.Sprintf(TokenExecJs, key))
   value, _ := vm.Get("zzzaaa")
   return value.String()
}

3. 验证码识别

用PostMan导入脚本测试了几下之后,发现返回居然变了,里面带上了一个验证码图片的Base64。需要二次请求验证。

基于规则的验证码识别可以识别绝大多数的弱验证码。 再复杂的,就得上机器学习堆各种层,各种网络了,这个就超出了我的知识范畴了。

至于这个验证码,太简单了,直接接个OCR,就搞定: gosseract

// 抽取返回中的 key 和 验证码base64
func GetCaptureUrl(str string) (key string, pngBase64 string) {
   defer func() {
      if err := recover(); err != nil {
      }
   }()
   
   bytes := []byte(str)
   data := map[string]interface{}{}
   _ = json.Unmarshal(bytes, &data)
   key = strconv.FormatFloat(data["data"].(map[string]interface{})["key"].(float64), 'f', -1, 64)
   pngBase64 = strings.TrimSpace(strings.ReplaceAll(data["data"].(map[string]interface{})["image"].(string), "data:image/png;base64,", ""))
   return
}
// 识别结果
func ReadPng(data string) (id, valus string) {
   key, pngBase64 := "", ""
   for key == "" {
      key, pngBase64 = GetCaptureUrl(data)
   }
   b, _ := base64.StdEncoding.DecodeString(pngBase64)
   client := gosseract.NewClient()
   defer client.Close()
   client.SetImageFromBytes(b)
   text, _ := client.Text()
   re, _ := regexp.Compile("[^0-9]") // 由于验证码只有数字,去掉非数字字符
   text = re.ReplaceAllString(text, "") 
   return key, text
}

4. 代理IP池

刷了一段时间之后,发现单IP到达100票左右的时候,继续投也无法成功了。

上代理IP池! github.com/awolfly9/IP… 最怕的就是搭环境,直接找个热心人士编译的docker run起来。 registry.hub.docker.com/u/yeclimeri…

写一段获取代理IP的方法:

func GetProxy() []string {
   var s []string
   resp, _ := http.Get(ProxyPoolUrl)
   reader, _ := simplejson.NewFromReader(resp.Body)
   array, _ := reader.Array()
   for _, a := range array {
      s = append(s, a.(string))
   }
   fmt.Println("proxy:", s)
   return s
}

刷票的车轮就飞快地运转起来了~

5. 尾声

作者此时正在回家的途中,没有办法操作,于是10分钟之后:

刷票一时爽啊 T.T。逃...

天下没有刷不了的票

有一些投票特别严格,需要人脸验证。或者是需要银行卡实名认证。基本就没办法通过程序自动化完成了。这种严格的投票,票数通常也不会特别多。

这时候,你可以充分享受中国的廉价劳动力以及人口红利带来的优势。手动狗头。

祭出法宝:猪八戒大法。


欢迎风控,反作弊的同学提问~

附录

代码: code.byted.org/niejunhao/t…

收费代理池: 收费代理池推荐

收费在线打码: 云打码 打码兔(推荐)

短信验证码: 接码平台推荐