吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5037|回复: 24
收起左侧

[Python 转载] 不光问卷搜集, 还让别人的女朋友叫我爸爸 !!!

[复制链接]
miss85246 发表于 2020-9-13 04:47
本帖最后由 miss85246 于 2020-9-13 06:11 编辑

震惊!别人的女朋友改口叫我爸爸!!!

写在前面的话:

我是一个潜水多年的水友, 这么多年来都是需要工具的时候才来, 也没有什么贡献, 今天在浏览论坛的时候突然发现一个惊人的事情, 创造太阳的女票居然喊他爸爸!!!! 这可亮瞎了我的钛金狗眼, 经过一番思绪后, 我决定抢走他的女票, 让他的女票喊我爸爸。于是就有了现在这篇文章。

在看我这篇文章之前如果你不明白我在干什么的话, 可以先去看一下这篇 创造太阳 的文章
女朋友急的叫“爸爸”了,我只好用python帮女朋友迅速完成问卷搜集任务...  好了, 该废话的都废话了, 下面我们开始来正式的讨论问题吧。

对问卷星页面的逆向

首先我们来打开这个调查问卷的页面
我们按 F12 先简单的看一看页面的 html, 看一下有没有什么有用的信息:

这个时候我们发现这个提交按钮的 class 样式是 submitButton
了解了这里以后我们可以先随便提交一个, 看一看 devtools 能不能抓到像样的包, 有没有我们想要的数据

可以看到, 它在提交之后立刻做了一个刷新, 我并没有抓到想要的包, 当然,如果有不信邪的小伙伴可以自己试一下,
其实只要你手速够快, 完全可以抓住那个包的(手动滑稽)

那这里就很大可能性的说明这个提交信息的函数也包含有submit 的字样, 我们再来看一下它的资源

发现这里有一些js文件, 我们可以逐步的去每个js文件里面搜索一下看有没有 submit 相关的字样

功夫不负有心人, 在 jqnew2.js?v=1328 这个文件中有135个包含有 submit 的地方
我们逐一的进行排除一下, 发现在第 3194 行 出现了一个 function, 名为 submit 还带了一个参数 a
可以推测大概率是这里, 先在函数内部任意一个位置打上断点. 然后再随便填写一份问卷进行提交

我们可以看到, 在我们打断点的地方, 浏览器停了下来, 说明提交就是通过这里来的, 我们再仔细的看一下这个
函数, 发现最后有一行这样的内容:

 d.send("submitdata=" + l)

说明这里是最终发送数据的地方, 我们在这里打上断点, 再次进行调试

截住后,我们通过控制台, 输入 l 来查看它发送的内容

"1%241%7D2%2445%7D3%244%7D4%244%7D5%241%7D6%241%7D7%244%7D8%242%7D9%242%7D10%247%7D11%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%7D12%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%7D13%242%7D14%241%7D15%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%7D16%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%2C8!1%7D17%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%2C8!1%2C9!1%2C10!1%7D18%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%2C8!1%2C9!1%2C10!1%7D19%241%7D20%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%7D21%241%7D22%241!1%2C2!1%2C3!1%2C4!1%2C5!1%2C6!1%2C7!1%2C8!1%2C9!1%2C10!1%2C11!1%2C12!1%7D23%24%E5%95%8A%E5%95%8A%E5%95%8A"

我们拿到了这样一段字符串, 很奇怪是吗? 我们来进行一下 urldecode, 看一下具体的内容是什么吧

"1$1}2$45}3$4}4$4}5$1}6$1}7$4}8$2}9$2}10$7}11$1!1,2!1,3!1,4!1,5!1,6!1,7!1}12$1!1,2!1,3!1,4!1,5!1,6!1}13$2}14$1}15$1!1,2!1,3!1,4!1,5!1,6!1}16$1!1,2!1,3!1,4!1,5!1,6!1,7!1,8!1}17$1!1,2!1,3!1,4!1,5!1,6!1,7!1,8!1,9!1,10!1}18$1!1,2!1,3!1,4!1,5!1,6!1,7!1,8!1,9!1,10!1}19$1}20$1!1,2!1,3!1,4!1,5!1,6!1,7!1}21$1}22$1!1,2!1,3!1,4!1,5!1,6!1,7!1,8!1,9!1,10!1,11!1,12!1}23$啊啊啊"

可以和我们的内容对比一下, 可以轻松的发现内容的格式就是

单选题, 填空题 的格式是: 
    题号$所选内容
多选题的格式是: 
    题号$所选内容1,所选内容2...
多行的选择题(不知道怎么描述了,如下图)的格式是 : 
    题号$行号!选项,行号!选项...

好的, 现在我们已经掌握了钥匙的大概样子了, 但是我们貌似还不知道门在哪里, 我们需要继续来调试, 找到大门最终的位置

我们看到了 请求是由 d 这个对象发出的, 我们来打印一下 d 对象, 看看能不能找到想要的内容:

看了一下打印结果, 貌似没有我们想要的内容, 那没有办法, 只能去翻看源码了, 看一下在哪里设置了什么东西

通过这里我们发现了他在发送请求之前先设置了请求头, 我们全局搜索一下, 发现只有这一个地方设置了请求头,
记录下请求头的内容,以备不时之需

headers = {"Content-Type": "application/x-www-form-urlencoded"}

再向上看, 发现有一句 这样的语句:

d.open(v, x, !1)

我们打印一下 v 的内容, 返回了一个 post 这下好了, 知道去大门的方式了, 但是走那条路呢?
还有一个 x 对象, 我们也打印出来看一下.
打印之后, 就会发现, x 对象是一个 url, 我们在控制台打印一下就会得到这个东西:

submittype=1&curID=88736026&t=1599929576059&starttime=2020%2F9%2F13%200%3A42%3A03&ktimes=851&rn=2006085889.87028755&hlv=1&jqnonce=9f0955dc-ee33-40a1-9950-e7f0cad9bde8&jqsign=8g1844eb%2Cdd22%2C51%600%2C8841%2Cd6g1b%60e8ced9&jpm=13

老规矩, 使用 url decode 看一下究竟是什么内容:

submittype=1&curID=88736026&t=1599929576059&starttime=2020/9/13 0:42:03&ktimes=851&rn=2006085889.87028755&hlv=1&jqnonce=9f0955dc-ee33-40a1-9950-e7f0cad9bde8&jqsign=8g1844eb,dd22,51`0,8841,d6g1b`e8ced9&jpm=13

好了, 这下子钥匙的完整样子都有了, 剩下的就是搞明白这些参数是干什么的, 然后进行模拟了.

具体的分析过程我就不说了, 有兴趣的小伙伴可以多多留言, 评论要是多的话, 我就发出怎么判断的

参数 猜测作用
submittype 提交类型
curID 问卷的标识id
t 提交时间戳
starttime 文件开始的时间
ktimes 相对于所有问卷,这是第几份问卷
rn 系统变量, 直接填写就行了
hlv 固定写 1 即可
jqnonce 系统变量, 直接填写
jqsign jqnonce的签名信息
jpm 尚不清楚是什么,影响不大

好, 有了 headers, 有了 参数, 我们就可以开始动手写代码了:

import re
import time           
import requests
from urllib import parse
from string import ascii_letters
from random import randint, choice, sample

class WJXSimulHelper:
    @staticmethod
    def data_creator():
        data = {
            1: randint(1, 2),
            2: choice(range(1995, 2010)),
            3: randint(1, 5),
            4: randint(1, 6),
            5: randint(1, 2),
            6: randint(1, 2),
            7: "|".join(sample(['1', '2', '3', '4', '5'], randint(1, 5))),
            8: "|".join(sample(['1', '2', '3'], randint(1, 3))),
            9: "|".join(sample(['1', '2', '3', '4'], randint(1, 4))),
            10: "|".join(sample([str(i) for i in range(1, 10)], randint(1, 9))),
            11: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 8)])]),
            12: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 7)])]),
            13: randint(1, 2),
            14: randint(1, 5),
            15: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 7)])]),
            16: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 8)])]),
            17: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 11)])]),
            18: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 11)])]),
            19: randint(1, 3),
            20: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 8)])]),
            21: randint(1, 3),
            22: ",".join([f"{index + 1}!{value}" for index, value in enumerate([randint(1, 6) for _ in range(1, 13)])]),
            23: "".join(sample(ascii_letters, randint(1, 26)))
        }
        return parse.quote("}".join([str(key) + '$' + str(value) for key, value in data.items()]))

    @staticmethod
    def param_creator():
        questionnaire_url = "https://www.wjx.cn/jq/88736026.aspx"
        page = requests.get(questionnaire_url).text
        cur_id = re.findall(r" var activityId = '(.*?)';", page)[0]
        jqnonce = re.findall(r'var jqnonce="(.*?)";', page)[0]
        rn = re.findall(r'var rndnum="(.*?)";', page)[0]
        ktime, now = randint(500, 2000), time.time()
        t = int(now + randint(20, 70) * 1000)
        start_time = parse.quote(time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(now)))
        jqsign = parse.quote("".join([chr((ord(char) ^ ktime % 10)) for char in jqnonce]))
        params = {"submittype": 1, "curID": cur_id, "t": t, "start_time": start_time, "ktimes": ktime,
                  "rn": rn, "hlv": 1, "jqnonce": jqnonce, "jqsign": jqsign, "jpm": 13}
        return "&".join([f"{key}={value}" for key, value in params.items()])

    def data_sender(self):
        data, params = self.data_creator(), self.param_creator()
        url = f"https://www.wjx.cn/joinnew/processjq.ashx?{params}"
        headers = {"Content-Type": "application/x-www-form-urlencoded"}
        json_data = {"submitdata": data}
        res = requests.post(url, json=json_data, headers=headers)
        assert res.status_code == 200, "添加问卷失败"
        print("添加问卷成功!")

if __name__ == '__main__':
    spider = WJXSimulHelper()
    spider.data_sender()

OK ! 到这里就结束了,效率提高了, 速度变快了, 人也不虚了, 还等什么? 找他女朋友去, 让她叫我爸爸!!!!

哈哈哈哈

注 : 本文不针对任何人发出敌对信号, 所有言辞均为写作效果, 请勿当真, 如果感觉不适请联系我删除

免费评分

参与人数 9吾爱币 +17 热心值 +7 收起 理由
一個賬號 + 1 + 1 热心回复!
我是一个外星人 + 1 热心回复!
苏紫方璇 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
小小宇6 + 1 + 1 多了一种方式
rookie_bixian + 1 是个狠人
kk1212 + 1 + 1 谢谢@Thanks!
Ldfd + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
漫漫长昼 + 1 + 1 谢谢@Thanks!
三滑稽甲苯 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| miss85246 发表于 2020-9-13 09:52
本帖最后由 miss85246 于 2020-9-13 09:55 编辑
hill_king 发表于 2020-9-13 09:29
勾选一下F12的保留日志不就抓到包了

timg.jpg
其实就算抓住了包, 不清楚参数的大概意思还是需要去里面解析的, 只不过能消耗更少一点的时间 (强行安慰自己)
9981难 发表于 2020-12-15 15:40
现在又改了,增加了:
"jcn=%E7%8E%83%E8%8A%B9%E8%8A%B9&"
"jqpram=1QYJWJOA&"
"u_atype=2"
这种参数,LZ如果能解密出来。。求分享。
青瓷i 发表于 2021-3-19 13:19
limit7 发表于 2020-12-15 15:51
牛逼,支持!
执笔为画卷 发表于 2020-9-14 10:43
这是个真正的大佬
dokuro 发表于 2020-9-13 12:18
城里人就是会玩
sddson 发表于 2020-9-13 11:29
谢谢分享
SKgarlic 发表于 2020-9-13 10:27
看完一脸蒙逼,大神就是牛比!1
sky995 发表于 2020-9-13 10:17
我只想看女友
 楼主| miss85246 发表于 2020-9-13 09:59
wushengli 发表于 2020-9-13 08:45
看的复杂,还是支持下!

还好了, 其实就是那么一个流程, 说复杂也没太复杂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 19:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表