天天看點

極驗驗證碼破解(二)

一、網站http://www.gsxt.gov.cn滑動驗證碼概述

二、極驗驗證碼破解-抓包分析

三、極驗驗證碼破解-搭建本地驗證碼服務

四、極驗驗證碼破解-分析geetest.js,得到所需參數

五、極驗驗證碼破解-Track的擷取

六、極驗驗證碼破解-擷取背景圖檔及缺口距離d的計算

七、極驗驗證碼破解-總結

參考文獻

運作截圖

四、極驗驗證碼破解-分析geetest.js,得到所需參數

  1. 為了找出如何生成userresponse和a,我們在geetest.js中搜尋userrespnse,發現隻有一處提到userresponse,如下所示:
    極驗驗證碼破解(二)

    可以看出userresponse和a都在上述代碼中指派。

    首先,我們追蹤ca.ra,得到下面代碼:

    極驗驗證碼破解(二)

    計算userresponse需要參數l和challenge,challenge我們已知,下面分析l(先猜測為滑塊移動的距離)。

    極驗驗證碼破解(二)
    可得到a由n生成,
    極驗驗證碼破解(二)

由上述可知oa.qa的傳回值是f,下面繼續追蹤f:

極驗驗證碼破解(二)

由上述可知(console為我添加,目的是列印資訊),f的傳回值即為所求a,觀察其包含!!資訊,比較所需a值:

極驗驗證碼破解(二)

可以發現,目前推測無誤。

2. 我們發現f依賴于oa下的c函數,追蹤c函數:

極驗驗證碼破解(二)
極驗驗證碼破解(二)

觀察c函數的參數a,由a[h+1][1]可知a應該是一個二維數組。

添加如下資訊,輸出a的内容:

極驗驗證碼破解(二)

重新整理http://localhost:8000/,檢視console控件下的資訊:

極驗驗證碼破解(二)
極驗驗證碼破解(二)

可以發現,這很大可能就是我們所要找的滑動軌迹Track。

回到之前userresponse中的l參數,我們在相應位置輸出:

極驗驗證碼破解(二)

檢視Console發現:

極驗驗證碼破解(二)

之前我們猜測l為滑動距離,比較l與Track最後一個坐标,可以發現l與Track[-1][0]相等,是以驗證我們猜想—l是滑動距離。

3. 要想得到userresponse,需要得到l,需要得到Track,由于Track是随機采樣生成的離散軌迹坐标序列,是以我們需要根據缺口的位置來模拟Track。由于Track較難模拟,我們先假設已根據缺口距離生成了Track。

則可以寫出生成userresponse的函數:

def cal_userresponse(a,b):
    d=[]
    c=b[:]
    for e in range(len(c)):
        f=ord(str(c[e]))
        tmp=f- if f> else f-
        d.append(tmp)

    c=*d[]+d[]
    g=int(round(a))+c
    b=b[:]

    i=[[],[],[],[],[]]
    j={}
    k=
    e=
    for e in range(len(b)):
        h=b[e]
        if h in j:
            pass
        else:
            j[h]=
            i[k].append(h)
            k+=
            k= if (k==) else k

    n=g
    o=
    p=""
    q=[,,,,]
    while n>:
        if n-q[o]>=:
            m=int(random.random()*len(i[o]))
            p+=str(i[o][m])
            n-=q[o]
        else:
            del(i[o])
            del(q[o])
            o-=
    return p
           

參數a和b分别是l和challenge。上述函數是我根據

極驗驗證碼破解(二)

改寫成Python形式

至此,userresponse參數破解成功,接下來看a的生成。

4. 之前分析a是由oa下的f函數生成:

極驗驗證碼破解(二)

其中參數a是Track。其中f函數用到了c函數、e函數和d函數。

極驗驗證碼破解(二)

根據js函數源碼,我将其改寫成python函數。

# 計算每次間隔   相當于c函數
def fun_c(a):
    g=[]
    e=[]
    f=
    for h in range(len(a)-):
        b=int(round(a[h+][]-a[h][]))
        c=int(round(a[h+][]-a[h][]))
        d=int(round(a[h+][]-a[h][]))
        g.append([b,c,d])

        if b==c==d==:
            pass
        else:
            if b==c==:
                f+=d
            else:
                e.append([b,c,d+f])
                f=
    if f!=:
        e.append([b,c,f])
    return e
           
def fun_e(item):   # 相當于e函數
    b=[[, ], [, ], [, -], [, ], [, ], [, -], [, ], [, -], [, ]]
    c='stuvwxyz~'
    for i,t in enumerate(b):
        if t==item[:]:
            return c[i]
    return 
           
def fun_d(a):
    b='()*,-./0123456789:[email protected]_abcdefghijklmnopqr'
    c=len(b)
    d=''
    e=abs(a)
    f=int(e/c)
    if f>=c:
        f=c-
    if f>:
        d=b[f]
    e%=c
    g=''
    if a<:
        g+='!'
    if d:
        g+='$'
    return g+d+b[e]
           
def fun_f(track_list):
    skip_list=fun_c(track_list)
    g,h,i=[],[],[]
    for j in range(len(skip_list)):
        b=fun_e(skip_list[j])
        if b:
            h.append(b)
        else:
            g.append(fun_d(skip_list[j][]))
            h.append(fun_d(skip_list[j][]))
        i.append(fun_d(skip_list[j][]))
    return ''.join(g)+'!!'+''.join(h)+'!!'+''.join(i)
           

代碼隻截取部分,具體細節後面會開源。

完整的f函數如上所示,參數為Track,傳回值即為f(也就是所需的a)。

至此,參數a也破解完成!!!隻差最會一步,Track如何得到。

極驗驗證碼破解(二)