逆向万例| No.00001【滑块篇】喜某拉某web端登录滑块逆向

声明:本文仅供学习交流用途,切勿用于非法行为,否则由此产生的一切后果均与作者本人无关。未经授权禁止转载本文。如有侵权,请及时通过本人公众号「逆向扬」联系删除。

0x1 开始之前

网站地址:YUhSMGNITTZMeTkzZDNjdWVHbHRZV3hoZVdFdVkyOXRMdz09(提示:如果解密不成功,可以试着多考虑一步)

本文目标:逆向该网站登录滑块验证

进入网站后,选择密码登录,在输入账号(手机号或邮箱)和密码后,会弹出一个滑块验证:

这个网站的滑块难度属于入门级别,因此很适合逆向新手将这个作为滑块逆向的入门例子。

下面我们来逆向这个滑块。

0x2 抓包分析

2.1 整体流程

首先我们对网站的整个登录请求过程进行分析。打开 chrome 的开发者工具,分析一下网络包。

在点击登录按钮后,会发送请求,用于获取滑块的底图和缺口图片:

滑块后,会发送一个 slider 请求。如果没滑到正确位置,会返回验证失败的响应信息:

若滑到了正确位置,则会返回验证成功的信息和一个 token 值:

这个 token 会被放到 cookie 的 fds_otp 中,并发送一个请求,获取之后请求登录接口所需要用到的 nonce 参数值:

最后,会发起对登录接口的请求,不过在本文中不讲解这一步。关于如何逆向该网站登录接口的参数,将在之后的文章中讲到:

2.2 关键包分析

这里最关键的是滑块验证请求 slider 。

这个包的请求参数分析:

  • bpId:固定值,到时候直接写死就行。
  • captchaText:关键参数,格式是:"鼠标在x方向的滑动距离,鼠标在y方向的滑动距离"
  • sessionId:固定值,直接写死就行。
  • startTime:滑动开始时间。
  • startX:滑动开始时,鼠标与浏览器左边界的距离。这个参数不是很关键,可以随便填,但有范围要求,只要在一个合理范围内即可,我简单验证过。
  • startY:滑动开始时,鼠标与浏览器下边界的距离。值的要求同 startX 。
  • type:固定值,写死就行。

因此,在这里,我们需要弄明白的是captchaText这个参数是如何生成的,只要能逆向这个参数,就能拿下这个网站的滑块。下面我们开始分析。

0x3 验证码底图获取

通过 get 这个请求可以获取到验证码的底图,获取到底图后,需要注意网站会以 0.8 的比例显示滑块验证码图片:

获取底图的代码:

payload = {
    "bpId": "139",
    "sessionId": "xm_leqnng8w237jib"
}

r = requests.get("https://mobile.ximalaya.com/captcha-web/check/slide/get",
                 headers=headers,
                 params=payload,
                 cookies=cookie)

print(r.json())
data = r.json()["data"]

image_url_list = {"fg": data["fgUrl"], "bg": data["bgUrl"]}
for k, v in image_url_list.items():
    rr = requests.get(v, headers=headers)
    with open(f"{k}.png", "wb") as f:
        f.write(rr.content)

拿到底图后,我们就可以用验证码识别库,比如 ddddocr 。可以直接拿着原图识别,而不需要事先将滑块图片和底图缩小为原来的 0.8,然后将通过原图识别出来的距离缩小为原来的 0.8 倍即可。

要注意这里有个小坑,captchaText 的 x 值时,你直接写这个识别出来的距离再乘上 0.8 是不行的,得加上一个偏移量,在 10 像素左右都行,至于偏移量的来源,我目前还没不知道。如果有知道的大佬,欢迎在评论区留言。

0x4 captchaText 参数分析

废话不多说,直接开始调试分析。我们需要定位到这个参数是如何生成的。我个人目前比较习惯直接通过请求的调用栈来做定位。点击 slider 请求,可以找到下图的方法中出现了我们想要分析的参数:

我们可以看到这里的实参 o 是从外部传到方法中的,因此继续往上跟栈,一步步跟,最终可以找到 captchaText 参数的生成位置:

captchaText 的生成规则如下:

其中,c 值就是滑动滑块时鼠标在 y 方向的滑动距离,a 值则是滑动滑块时鼠标在 x 方向的滑动距离。d.ZOOM 则是图像的缩小比例。

按照常规来说,直接传递 a 值和 c 值给网站后台即可通过滑块验证,但是网站前端在 getSliderLeft 方法中还对 a 值进行了一些额外的计算处理。

getSliderLeft 方法如下,其中的计算逻辑复现很简单,因此就不细讲了:

用 python 复现一下 getSliderLeft 方法,供大家参考:

def get_img_left(t):
    return -12 * 0.8 + (t + 10) * (380 - 84.8 + 24 * 0.8) / (380 - 40)

def get_slider_left(t):
    return int(get_img_left(t) / 0.8 + 44)

最后贴上滑块验证的代码:

def verify_slide():
    payload = {
        "bpId": "139",
        "sessionId": "xm_leqnng8w237jib"
    }

    r = requests.get("https://mobile.ximalaya.com/captcha-web/check/slide/get",
                     headers=headers,
                     params=payload,
                     cookies=cookie)

    print(r.json())
    data = r.json()["data"]

    image_url_list = {"fg": data["fgUrl"], "bg": data["bgUrl"]}
    for k, v in image_url_list.items():
        rr = requests.get(v, headers=headers)
        with open(f"{k}.png", "wb") as f:
            f.write(rr.content)

    det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)
    with open('fg.png', 'rb') as f:
        fg_bytes = f.read()
    with open('bg.png', 'rb') as f:
        bg_bytes = f.read()
    res = det.slide_match(fg_bytes, bg_bytes, simple_target=True)
    print(res)

    def get_img_left(t):
        return -12 * 0.8 + (t + 10) * (380 - 84.8 + 24 * 0.8) / (380 - 40)

    def get_slider_left(t):
        return int(get_img_left(t) / 0.8 + 44)

    x = int((res["target"][0] + 25) * 0.8) 
    distance = int(get_slider_left(x))
    slide_payload = {
        "bpId": 139,
        "sessionId": "xm_leqnng8w237jib",
        "type": "slider",
        "captchaText": f'{distance},0',
        "startX": 563,
        "startY": 357,
        "startTime": int((time.time() - 2) * 1000)
    }

    print(slide_payload)
    slide_r = requests.post("https://mobile.ximalaya.com/captcha-web/valid/slider",
                            headers=headers,
                            cookies=cookie,
                            json=slide_payload)

    print(slide_r.text)
    print(slide_r.json()["token"])

验证

可以看到滑块验证通过,并且拿到了 token 值:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容