Sinisterly
[Lua] LMC - MD5 cracker - Printable Version

+- Sinisterly (https://sinister.li)
+-- Forum: Coding (https://sinister.li/Forum-Coding)
+--- Forum: Coding (https://sinister.li/Forum-Coding--71)
+--- Thread: [Lua] LMC - MD5 cracker (/Thread-Lua-LMC-MD5-cracker)

Pages: 1 2


[Lua] LMC - MD5 cracker - noize - 08-07-2013

LMC - Lua MD5 Cracker

Latest version: 2.4 (stable)
Latest stable: 2.4

Supports:

Code:
[*] wordlist-based attacks [*] bruteforcing (supports hash files, timeout for single hash, custom alphabets and word length (also ranges)) [*] hash/checksum generation [*] list (line-by-line) encryption [*] stdout + outfile [*] web crawling based password cracking (tries each word found on the web pages) [*] IP bruteforcing (for web crawling) [*] wordlist-based DNS forcing (for web crawling)

See --help or --about for more information.

Please, report/post any bug, suggestion or comment.

Code:
-------------------------------------------------------------------------------- -- LMC 2.4 -- -- (( Lua MD5 Cracker )) -- -------------------------------------------------------------------------------- -- You're allowed to edit and/or give away for free this code as whole or in -- -- part as long as you give credits. -- -------------------------------------------------------------------------------- -- LMC · coded by noize · 2013 -- -------------------------------------------------------------------------------- require("strbuf") require("list") require("md5") print("") local tried = {} -------------------------------------------------------------------------------- -- define error functions -------------------------------------------------------------------------------- local err = {} function err.few_args() print("not enough arguments.") os.exit(2) end function err.readf(file) print("error: failed to read " .. file .. "file.") os.exit(1) end function err.unknown_arg(argx,n) print("argument #" .. n .. " '" .. argx .. "' not recognized.") os.exit(2) end function err.wordlen_nan() print("error: word length must be a number.") os.exit(2) end function err.unexp_dash_in_len() print("error: unexpected dash in word length declaration.") os.exit(2) end -------------------------------------------------------------------------------- -- define handling functions -------------------------------------------------------------------------------- function rand(f,c) math.randomseed(os.time()) math.randomseed(math.random(os.clock(),os.time())) return math.random(f,c) end function generator(alphabet,length) local gen = {} if length then gen.length = length else gen.length = "4-12" end if gen.length:find("%-") then local splt = string.split(gen.length,"%-") if not splt[2] or splt[3] then err.unexp_dash_in_len() else gen.length = rand(splt[1],splt[2]) end end gen.length = tonumber(gen.length) if alphabet then gen.alphabet = {} for w in alphabet:gmatch("%S+") do table.insert(gen.alphabet,w) end else gen.alphabet = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0","!","&","-","_","."} end gen.pass = "" for s = 1, gen.length do gen.alphabet = shuffle(gen.alphabet) gen.pass = gen.pass .. gen.alphabet[rand(1,#gen.alphabet)] end while tried[gen.pass] do gen.pass = "" for s = 1, gen.length do gen.alphabet = shuffle(gen.alphabet) gen.pass = gen.pass .. gen.alphabet[rand(1,#gen.alphabet)] end end return gen.pass end function shuffle(array) local order, res = {}, {} for i = 1, #array do math.randomseed(os.time() / math.random()) math.randomseed(os.time() / math.random() * os.clock()) math.randomseed(os.clock() * math.random() / os.time()) order[i] = { rnd = math.random(), idx = i } end local f = array[1] table.insert(array,f) local r = math.random(1,#array) local t = array[r] table.remove(array,r) table.sort(order, function(a,b) return a.rnd < b.rnd end) table.insert(array,t) table.remove(array,1) for i = 1, #array do res[i] = array[order[i].idx] end return res end function force(hash,hashfile,timeout,outfile,alphabet,length) local t = os.clock() function try(str,hash) local len = {} len.max = (tonumber(length) or length) if type(len.max) ~= "number" then local split = len.max:split("%-") len.min = tonumber(split[1]) len.max = tonumber(split[2]) if not len.min or not len.max then err.wordlen_nan() end end if str:len() >= len.min and str:len() <= len.max then print("trying: " .. hash .. ":" .. str) if (md5.sumhexa(str) == hash) then if outfile then local f = io.open(outfile,"a") f:write(hash .. ":" .. str .. "\n") f:close() end return hash, str end end end while (os.clock() < t + (timeout or os.clock())) do local str = generator(alphabet,length) tried[str] = true tried[#tried + 1] = true if hashfile then for hash in io.lines(hash) do if wordtweak() then tweak(str,hash) else try(str,hash) end end else if wordtweak() then tweak(str,hash) else try(str,hash) end end end return hash, false end function checkf(file,error) local f = io.open(file,"r") if f then f:close() else err.readf(error) end end -------------------------------------------------------------------------------- -- define main functions -------------------------------------------------------------------------------- function usage() print(" ***********************************************\n") print(" *** LMC cracker by noize ***\n") print(" ***********************************************\n") print(" usage: lua lmc.lua [-c | -b | -h | -f | -l | -w | --help | --about]") print(" [wordlist | hash | -f hashfile [-t timeout] [-a alphabet]") print(" [-l length] | string | file | list | -b | -l wordlist]") print(" [-s hash | -f hashfile | -m | -o outfile]\n") print(" -c cracking mode") print(" wordlist password file to read passwords from") print(" -m enable word mangling") print(" -s single hash") print(" hash hash to crack") print(" -f read hashes from hashfile") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" -b bruteforcing mode") print(" hash hash to crack") print(" -f read hashes from hashfile") print(" hashfile file to read hashes to crack from") print(" -t set timeout in seconds per hash") print(" timeout go to next hash in case the hash wasn't cracked in time") print(" -a use custom alphabet (default is \"a b c d e f g h i j k l m n") print(" o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 ! & - _ .\")") print(" alphabet alphabet to use (characters are separated with whitespaces)") print(" -l custom password length (default is 4-12)") print(" length length for the password (ranges are allowed as above shown)") print(" -m enable word mangling") print(" -o write cracked passwords to outfile") print(" -h hashing mode") print(" string string to encrypt (enclosed in quotes for more words)") print(" -f file checksum mode") print(" file file to hash") print(" -o write checksum to outfile (if omitted stdout is used)") print(" -l list encryption mode") print(" list hash file line by line") print(" -o write output to outfile (if omitted stdout is used)") print(" -w web spider mode") print(" -b IP bruteforcing mode (see --about for more)") print(" hash hash to crack") print(" -f hashes file") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" -l wordlist wordlist-based DNS forcing mode (see --about for more)") print(" hash hash to crack") print(" -f hashes file") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" outfile output file (only with -o)") print("\n examples:\n") print(" lua lmc.lua -c wordlist.txt -s d41d8cd98f00b204e9800998ecf8427e") print(" lua lmc.lua -c password.lst -f hashes.txt") print(" lua lmc.lua -c wordlist.txt -f db_passwords -o success.txt") print(" lua lmc.lua -b 9dd8b2a63b2aae4a2633d04b14141294") print(" lua lmc.lua -b -f hashfile.txt") print(" lua lmc.lua -b -f hash.lst -l 3 -o psw.lst") print(" lua lmc.lua -b -f hashes.txt -t 60000 -o cracked.txt") print(" lua lmc.lua -b -f hashes.txt -o out.txt -a \"a b c 1 2 3\" -l 2-6") print(" lua lmc.lua -h \"a backslash escapes \\\"quotes\\\"\"") print(" lua lmc.lua -f exeimage") print(" lua lmc.lua -f pe.exe -o checksum.txt") print(" lua lmc.lua -l password.lst -o hashes.lst") print(" lua lmc.lua -w -b -f hashfile.lst") print(" lua lmc.lua -w -l sitenames.txt 9dd8b2a63b2aae4a2633d04b14141294") print(" lua lmc.lua -w -l wordlist.txt -f hashes.txt -o cracked.psw") end function about() print("=====================\n") print("LMC (Lua MD5 Cracker)\n") print("=====================\n") print("Program version: 2.4") print("Lua version: 5.1") print("\n=====================") print("\nLMC offers more than just usual hash cracking:") print("its options include:\n") print(" [ OK ] hash generation") print(" [ OK ] checksum generation") print(" [ OK ] list encryption") print(" [ OK ] bruteforcing") print(" [ OK ] word tweaking (see notes)") print(" [ OK ] web crawling based password cracking (see notes)") print("\n=====================") print("\nsupported algorithms:\n") print("=====================\n") print(" [ OK ] MD5") print("\n=====================") print("\nsupported attacks:\n") print("=====================\n") print(" [ OK ] bruteforce") print(" [ OK ] wordlist-based") print(" [ OK ] spider-based") print("\n=====================") print("\nnotes:\n") print("=====================\n") print(" - cracked passwords are output as well as saved to file when -o is used") print(" - in web spider mode, LMC crawls through the Internet and tries all the words") print(" it finds once (it won't try the same word more times)") print(" the DNS names it uses on the run are generated randomly (DNS bruteforcing)") print(" this tecnique is inspired to Deque's WikiCrawler wordlist generator") print(" I don't believe, though, that this kind of tecnique has ever been used for") print(" password cracking this way before") print(" - if you use the -w option with the -f option, you'll need to manually stop") print(" the program, 'cause it'll theorically run endlessly") print(" - you can enable word mangling (\"-m\" option) only with a cracking option.") print(" the following cracking methods support word mangling:") print(" [ OK ] bruteforcing") print(" [ OK ] wordlist cracking") print(" [ ] web-based cracking (will come)") print(" an example of a word picked from a list:") print(" password") print(" if word mangling is enabled, some of the words that will be tried include:") print(" Password") print(" PASSWORD") print(" password0") print(" password1234") print(" password123456") print(" p455w0rd") print(" passwordPASSWORD") print(" passwordpasswordpassword") print("\n=====================") print("\nknown bugs:\n") print("=====================\n") print(" - a known issue with the bruteforcing version of the mangling algorithm, is") print(" that it does not respect the defined word-length") print(" - for some still unknown to me reason it looks like sometimes, the") print(" bruteforcing algorithm throws in a \"ú\" character even when it is not") print(" present in the defined alphabet") print(" if you've got any idea why this is happening, please, let me know") print("\n=====================") print("\nLMC - coded by noize\n") print("=====================") end function checksum() checkf(arg[2],"") local f = io.open(arg[2],"r") if arg[4] then local o = io.open(arg[4],"w") end local checksum = md5.sumhexa(f:read("*a")) print(checksum) if arg[3] == "-o" then o:write(checksum) end f:close() end function listf() -- to avoid conflicts with the required list() function checkf(arg[2],"") local f = io.open(arg[2],"r") if not arg[3] == "-o" then for l in io.lines(arg[2]) do print(md5.sumhexa(l)) end else os.remove(arg[4]) local f = io.open(arg[4],"a") for l in io.lines(arg[2]) do f:write(md5.sumhexa(l) .. "\n") end end end function wordtweak() for i = 2, 15 do if arg[i] == "-m" then return true end end return false end function tweak(word,hash) function mangle(m) try(word .. m,hash) end mangle("") mangle(word) mangle(word .. word) mangle("00") mangle("007") mangle("0010") mangle("000") mangle("0001") mangle("12345") mangle("123456") for i = 0, 100 do mangle(i) end for i = 1900, 2100 do mangle(i) end mangle("123456") mangle(word:lower()) mangle(word:upper()) try(word:lower(),hash) try(word:upper(),hash) try(word:lower() .. word:upper(),hash) for c in word:gmatch("[^%s]") do mangle(c) try(c .. word,hash) try(c:upper() .. word:ltrim(c),hash) for i = 0, 100 do mangle(c .. i) mangle(c:upper() .. i) end break end local alph = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"} local leet = {"4","8","<","d","3","f","9","|-|","!","j","k","1","m","|\|","0","p","q","r","5","7","|_|","\/","w","><","y","2"} local chars = {} for c in word:gmatch(".") do table.insert(chars,c) end local trans = {} for i = 1, #chars do for j = 1, #alph do local split = chars[i]:gsub(alph[j],leet[j]) table.insert(trans,i,split) end end try(table.concat(trans),hash) mangle(table.concat(trans)) local new = {} new.s = trans[1] for i = 2, #chars do new.s = new.s .. chars[i] end try(new.s,hash) try(new.s:upper(),hash) new.s = "" for i = 1, #trans, 2 do new.s = new.s .. trans[i] if chars[i+1] then new.s = new.s .. chars[i+1] end end try(new.s,hash) try(new.s:upper(),hash) end function cracker() local list = arg[2] checkf(list,"wordlist ") local hash = arg[4] if arg[3] == "-s" then function try(word,hash) print("trying: " .. word) if md5.sumhexa(word) == hash then print("match found: " .. word) os.exit() end end for l in io.lines(list) do if wordtweak() then tweak(l,hash) else try(l,hash) end end elseif arg[3] == "-f" then function try(word,hash) print("trying: " .. hash .. ":" .. l) if md5.sumhexa(l) == hash then if arg[5] == "-o" and not io.open(outfile,"r") then local o = io.open(outfile,"w") o:write("hash:string\n") o:close() end print("match found: " .. hash .. ":" .. l) if arg[6] == "-o" then o:write(hash .. ":" .. l .. "\n") end end end local hashfile = arg[4] checkf(hashfile,"hashes ") local outfile = arg[6] local o = io.open(outfile,"a") for hash in io.lines(hashfile) do for l in io.lines(list) do if wordtweak() then tweak(l,hash) else try(l,hash) end end end else err.unknown_arg(arg[3],"3 (hash cracking mode)") end end function brute() local brute = {} function brute.argc(argx,key) for i = 3, 20 do if arg[i] == argx then brute[key] = arg[i+1] end end end brute.argc("-t","timeout") brute.argc("-o","outfile") brute.argc("-a","alphabet") brute.argc("-l","length") if arg[2] == "-f" then checkf(arg[3],"hashes ") if brute.outfile then local f = io.open(brute.outfile,"w") f:write("hash:string\n") f:close() end local cracks = {} cracks.done = 0 cracks.failed = 0 for l in io.lines(arg[3]) do local hash, cracked = force(arg[3],true,brute.timeout,brute.outfile,brute.alphabet,brute.length) if cracked then print("\nmatch found: " .. hash .. ":" .. cracked) print("hashes cracked: " .. cracks.done) print("failed cracks: " .. cracks.failed) print("words tried: " .. #tried .. "\n") cracks.done = cracks.done + 1 else print("\nfailed to crack " .. hash .. "\n") cracks.failed = cracks.failed + 1 end end elseif arg[2] then local hash, cracked = force(arg[2],brute.timeout,brute.outfile,brute.alphabet,brute.length) if cracked then print("\nmatch found: " .. cracked) print("words tried: " .. #tried) else print("\ncracking failed.") end else err.few_args() end end function crawler() if (not arg[3]) or (arg[3] == "-f" and not arg[4]) or (arg[4] == "-f" and not arg[5]) or (arg[2] == "-l" and not arg[4]) then err.few_args() elseif arg[3] == "-f" then checkf(arg[4],"hashes ") elseif arg[4] == "-f" then checkf(arg[5],"hashes ") end if arg[5] then local o = io.open(arg[5],"a") end if arg[4] == "-o" then os.remove(arg[5]) end if arg[2] == "-b" then function gen() local w = rand(1,255) local x = rand(1,255) local y = rand(1,255) local z = rand(1,255) local ip = w .. "." .. x .. "." .. y .. "." .. z return ip end elseif arg[2] == "-l" then checkf(arg[3],arg[3] .. " ") local host = {} if arg[4] == "-d" then host.domain = arg[5] else host.domain = ".com" end local rout = coroutine.create( function() for l in io.lines(arg[3]) do local hostname = l .. host.domain coroutine.yield(hostname) end return nil end ) function gen() local bool, hostname = coroutine.resume(rout) return hostname end else err.unknown_arg(arg[2],"2 (web crawling mode)") end if arg[3] ~= "-f" and arg[4] ~= "-f" then function try(w) if md5.sumhexa(w) == arg[3] then print("match found: " .. w) print("hostnames tried: " .. #tried.host) print("words tried: " .. #tried.word) os.exit(0) end end else if arg[3] == "-f" then checkf(arg[4],"hashes ") elseif arg[4] == "-f" then checkf(arg[5],"hashes ") end function try(w) for l in io.lines(arg[3]) do if md5.sumhexa(w) == l then print("match found: " .. w) print("hostnames tried so far: " .. #tried.host) print("words tried so far: " .. #tried.word .. "\n") if arg[4] == "-o" then o:write(l .. ":" .. w .. "\n") end end end end end require("socket") tried.host = {} tried.word = {} while true do tried.tmp = gen() while tried.host[tried.tmp] do tried.tmp = gen() end local host = tried.tmp if not host then print("no matches found.") print("hostnames tried: " .. #tried.host) print("words tried: " .. #tried.word) os.exit(0) end local s = socket.connect(host,80) if s then s:settimeout(0) s:send("GET / HTTP/1.0\r\n\r\n") while true do local data, stat, part = s:receive(1024) for w in (data or part):gmatch("%S+") do if not tried.word[w] then try(w) tried.word[w] = true tried.word[#tried.word + 1] = true end end if stat == "closed" then break end end s:close() tried.host[host] = true tried.host[#tried.host + 1] = true end end end -------------------------------------------------------------------------------- -- main structure -------------------------------------------------------------------------------- if not arg[1] or arg[1] == "--help" then usage() else if arg[1] == "--about" then about() elseif arg[1] == "-c" then if not arg[4] or not arg[2] then err.few_args() else cracker() end elseif arg[1] == "-b" then brute() elseif arg[1] == "-h" then print(md5.sumhexa(arg[2])) elseif arg[1] == "-f" then checksum() elseif arg[1] == "-l" then listf() elseif arg[1] == "-w" then crawler() else err.unknown_arg(arg[1],"1") end end



[Lua] LMC - MD5 cracker - noize - 08-07-2013

LMC - Lua MD5 Cracker

Latest version: 2.4 (stable)
Latest stable: 2.4

Supports:

Code:
[*] wordlist-based attacks [*] bruteforcing (supports hash files, timeout for single hash, custom alphabets and word length (also ranges)) [*] hash/checksum generation [*] list (line-by-line) encryption [*] stdout + outfile [*] web crawling based password cracking (tries each word found on the web pages) [*] IP bruteforcing (for web crawling) [*] wordlist-based DNS forcing (for web crawling)

See --help or --about for more information.

Please, report/post any bug, suggestion or comment.

Code:
-------------------------------------------------------------------------------- -- LMC 2.4 -- -- (( Lua MD5 Cracker )) -- -------------------------------------------------------------------------------- -- You're allowed to edit and/or give away for free this code as whole or in -- -- part as long as you give credits. -- -------------------------------------------------------------------------------- -- LMC · coded by noize · 2013 -- -------------------------------------------------------------------------------- require("strbuf") require("list") require("md5") print("") local tried = {} -------------------------------------------------------------------------------- -- define error functions -------------------------------------------------------------------------------- local err = {} function err.few_args() print("not enough arguments.") os.exit(2) end function err.readf(file) print("error: failed to read " .. file .. "file.") os.exit(1) end function err.unknown_arg(argx,n) print("argument #" .. n .. " '" .. argx .. "' not recognized.") os.exit(2) end function err.wordlen_nan() print("error: word length must be a number.") os.exit(2) end function err.unexp_dash_in_len() print("error: unexpected dash in word length declaration.") os.exit(2) end -------------------------------------------------------------------------------- -- define handling functions -------------------------------------------------------------------------------- function rand(f,c) math.randomseed(os.time()) math.randomseed(math.random(os.clock(),os.time())) return math.random(f,c) end function generator(alphabet,length) local gen = {} if length then gen.length = length else gen.length = "4-12" end if gen.length:find("%-") then local splt = string.split(gen.length,"%-") if not splt[2] or splt[3] then err.unexp_dash_in_len() else gen.length = rand(splt[1],splt[2]) end end gen.length = tonumber(gen.length) if alphabet then gen.alphabet = {} for w in alphabet:gmatch("%S+") do table.insert(gen.alphabet,w) end else gen.alphabet = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","1","2","3","4","5","6","7","8","9","0","!","&","-","_","."} end gen.pass = "" for s = 1, gen.length do gen.alphabet = shuffle(gen.alphabet) gen.pass = gen.pass .. gen.alphabet[rand(1,#gen.alphabet)] end while tried[gen.pass] do gen.pass = "" for s = 1, gen.length do gen.alphabet = shuffle(gen.alphabet) gen.pass = gen.pass .. gen.alphabet[rand(1,#gen.alphabet)] end end return gen.pass end function shuffle(array) local order, res = {}, {} for i = 1, #array do math.randomseed(os.time() / math.random()) math.randomseed(os.time() / math.random() * os.clock()) math.randomseed(os.clock() * math.random() / os.time()) order[i] = { rnd = math.random(), idx = i } end local f = array[1] table.insert(array,f) local r = math.random(1,#array) local t = array[r] table.remove(array,r) table.sort(order, function(a,b) return a.rnd < b.rnd end) table.insert(array,t) table.remove(array,1) for i = 1, #array do res[i] = array[order[i].idx] end return res end function force(hash,hashfile,timeout,outfile,alphabet,length) local t = os.clock() function try(str,hash) local len = {} len.max = (tonumber(length) or length) if type(len.max) ~= "number" then local split = len.max:split("%-") len.min = tonumber(split[1]) len.max = tonumber(split[2]) if not len.min or not len.max then err.wordlen_nan() end end if str:len() >= len.min and str:len() <= len.max then print("trying: " .. hash .. ":" .. str) if (md5.sumhexa(str) == hash) then if outfile then local f = io.open(outfile,"a") f:write(hash .. ":" .. str .. "\n") f:close() end return hash, str end end end while (os.clock() < t + (timeout or os.clock())) do local str = generator(alphabet,length) tried[str] = true tried[#tried + 1] = true if hashfile then for hash in io.lines(hash) do if wordtweak() then tweak(str,hash) else try(str,hash) end end else if wordtweak() then tweak(str,hash) else try(str,hash) end end end return hash, false end function checkf(file,error) local f = io.open(file,"r") if f then f:close() else err.readf(error) end end -------------------------------------------------------------------------------- -- define main functions -------------------------------------------------------------------------------- function usage() print(" ***********************************************\n") print(" *** LMC cracker by noize ***\n") print(" ***********************************************\n") print(" usage: lua lmc.lua [-c | -b | -h | -f | -l | -w | --help | --about]") print(" [wordlist | hash | -f hashfile [-t timeout] [-a alphabet]") print(" [-l length] | string | file | list | -b | -l wordlist]") print(" [-s hash | -f hashfile | -m | -o outfile]\n") print(" -c cracking mode") print(" wordlist password file to read passwords from") print(" -m enable word mangling") print(" -s single hash") print(" hash hash to crack") print(" -f read hashes from hashfile") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" -b bruteforcing mode") print(" hash hash to crack") print(" -f read hashes from hashfile") print(" hashfile file to read hashes to crack from") print(" -t set timeout in seconds per hash") print(" timeout go to next hash in case the hash wasn't cracked in time") print(" -a use custom alphabet (default is \"a b c d e f g h i j k l m n") print(" o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 ! & - _ .\")") print(" alphabet alphabet to use (characters are separated with whitespaces)") print(" -l custom password length (default is 4-12)") print(" length length for the password (ranges are allowed as above shown)") print(" -m enable word mangling") print(" -o write cracked passwords to outfile") print(" -h hashing mode") print(" string string to encrypt (enclosed in quotes for more words)") print(" -f file checksum mode") print(" file file to hash") print(" -o write checksum to outfile (if omitted stdout is used)") print(" -l list encryption mode") print(" list hash file line by line") print(" -o write output to outfile (if omitted stdout is used)") print(" -w web spider mode") print(" -b IP bruteforcing mode (see --about for more)") print(" hash hash to crack") print(" -f hashes file") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" -l wordlist wordlist-based DNS forcing mode (see --about for more)") print(" hash hash to crack") print(" -f hashes file") print(" hashfile file to read hashes to crack from") print(" -o write cracked passwords to outfile (if omitted stdout is used)") print(" outfile output file (only with -o)") print("\n examples:\n") print(" lua lmc.lua -c wordlist.txt -s d41d8cd98f00b204e9800998ecf8427e") print(" lua lmc.lua -c password.lst -f hashes.txt") print(" lua lmc.lua -c wordlist.txt -f db_passwords -o success.txt") print(" lua lmc.lua -b 9dd8b2a63b2aae4a2633d04b14141294") print(" lua lmc.lua -b -f hashfile.txt") print(" lua lmc.lua -b -f hash.lst -l 3 -o psw.lst") print(" lua lmc.lua -b -f hashes.txt -t 60000 -o cracked.txt") print(" lua lmc.lua -b -f hashes.txt -o out.txt -a \"a b c 1 2 3\" -l 2-6") print(" lua lmc.lua -h \"a backslash escapes \\\"quotes\\\"\"") print(" lua lmc.lua -f exeimage") print(" lua lmc.lua -f pe.exe -o checksum.txt") print(" lua lmc.lua -l password.lst -o hashes.lst") print(" lua lmc.lua -w -b -f hashfile.lst") print(" lua lmc.lua -w -l sitenames.txt 9dd8b2a63b2aae4a2633d04b14141294") print(" lua lmc.lua -w -l wordlist.txt -f hashes.txt -o cracked.psw") end function about() print("=====================\n") print("LMC (Lua MD5 Cracker)\n") print("=====================\n") print("Program version: 2.4") print("Lua version: 5.1") print("\n=====================") print("\nLMC offers more than just usual hash cracking:") print("its options include:\n") print(" [ OK ] hash generation") print(" [ OK ] checksum generation") print(" [ OK ] list encryption") print(" [ OK ] bruteforcing") print(" [ OK ] word tweaking (see notes)") print(" [ OK ] web crawling based password cracking (see notes)") print("\n=====================") print("\nsupported algorithms:\n") print("=====================\n") print(" [ OK ] MD5") print("\n=====================") print("\nsupported attacks:\n") print("=====================\n") print(" [ OK ] bruteforce") print(" [ OK ] wordlist-based") print(" [ OK ] spider-based") print("\n=====================") print("\nnotes:\n") print("=====================\n") print(" - cracked passwords are output as well as saved to file when -o is used") print(" - in web spider mode, LMC crawls through the Internet and tries all the words") print(" it finds once (it won't try the same word more times)") print(" the DNS names it uses on the run are generated randomly (DNS bruteforcing)") print(" this tecnique is inspired to Deque's WikiCrawler wordlist generator") print(" I don't believe, though, that this kind of tecnique has ever been used for") print(" password cracking this way before") print(" - if you use the -w option with the -f option, you'll need to manually stop") print(" the program, 'cause it'll theorically run endlessly") print(" - you can enable word mangling (\"-m\" option) only with a cracking option.") print(" the following cracking methods support word mangling:") print(" [ OK ] bruteforcing") print(" [ OK ] wordlist cracking") print(" [ ] web-based cracking (will come)") print(" an example of a word picked from a list:") print(" password") print(" if word mangling is enabled, some of the words that will be tried include:") print(" Password") print(" PASSWORD") print(" password0") print(" password1234") print(" password123456") print(" p455w0rd") print(" passwordPASSWORD") print(" passwordpasswordpassword") print("\n=====================") print("\nknown bugs:\n") print("=====================\n") print(" - a known issue with the bruteforcing version of the mangling algorithm, is") print(" that it does not respect the defined word-length") print(" - for some still unknown to me reason it looks like sometimes, the") print(" bruteforcing algorithm throws in a \"ú\" character even when it is not") print(" present in the defined alphabet") print(" if you've got any idea why this is happening, please, let me know") print("\n=====================") print("\nLMC - coded by noize\n") print("=====================") end function checksum() checkf(arg[2],"") local f = io.open(arg[2],"r") if arg[4] then local o = io.open(arg[4],"w") end local checksum = md5.sumhexa(f:read("*a")) print(checksum) if arg[3] == "-o" then o:write(checksum) end f:close() end function listf() -- to avoid conflicts with the required list() function checkf(arg[2],"") local f = io.open(arg[2],"r") if not arg[3] == "-o" then for l in io.lines(arg[2]) do print(md5.sumhexa(l)) end else os.remove(arg[4]) local f = io.open(arg[4],"a") for l in io.lines(arg[2]) do f:write(md5.sumhexa(l) .. "\n") end end end function wordtweak() for i = 2, 15 do if arg[i] == "-m" then return true end end return false end function tweak(word,hash) function mangle(m) try(word .. m,hash) end mangle("") mangle(word) mangle(word .. word) mangle("00") mangle("007") mangle("0010") mangle("000") mangle("0001") mangle("12345") mangle("123456") for i = 0, 100 do mangle(i) end for i = 1900, 2100 do mangle(i) end mangle("123456") mangle(word:lower()) mangle(word:upper()) try(word:lower(),hash) try(word:upper(),hash) try(word:lower() .. word:upper(),hash) for c in word:gmatch("[^%s]") do mangle(c) try(c .. word,hash) try(c:upper() .. word:ltrim(c),hash) for i = 0, 100 do mangle(c .. i) mangle(c:upper() .. i) end break end local alph = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"} local leet = {"4","8","<","d","3","f","9","|-|","!","j","k","1","m","|\|","0","p","q","r","5","7","|_|","\/","w","><","y","2"} local chars = {} for c in word:gmatch(".") do table.insert(chars,c) end local trans = {} for i = 1, #chars do for j = 1, #alph do local split = chars[i]:gsub(alph[j],leet[j]) table.insert(trans,i,split) end end try(table.concat(trans),hash) mangle(table.concat(trans)) local new = {} new.s = trans[1] for i = 2, #chars do new.s = new.s .. chars[i] end try(new.s,hash) try(new.s:upper(),hash) new.s = "" for i = 1, #trans, 2 do new.s = new.s .. trans[i] if chars[i+1] then new.s = new.s .. chars[i+1] end end try(new.s,hash) try(new.s:upper(),hash) end function cracker() local list = arg[2] checkf(list,"wordlist ") local hash = arg[4] if arg[3] == "-s" then function try(word,hash) print("trying: " .. word) if md5.sumhexa(word) == hash then print("match found: " .. word) os.exit() end end for l in io.lines(list) do if wordtweak() then tweak(l,hash) else try(l,hash) end end elseif arg[3] == "-f" then function try(word,hash) print("trying: " .. hash .. ":" .. l) if md5.sumhexa(l) == hash then if arg[5] == "-o" and not io.open(outfile,"r") then local o = io.open(outfile,"w") o:write("hash:string\n") o:close() end print("match found: " .. hash .. ":" .. l) if arg[6] == "-o" then o:write(hash .. ":" .. l .. "\n") end end end local hashfile = arg[4] checkf(hashfile,"hashes ") local outfile = arg[6] local o = io.open(outfile,"a") for hash in io.lines(hashfile) do for l in io.lines(list) do if wordtweak() then tweak(l,hash) else try(l,hash) end end end else err.unknown_arg(arg[3],"3 (hash cracking mode)") end end function brute() local brute = {} function brute.argc(argx,key) for i = 3, 20 do if arg[i] == argx then brute[key] = arg[i+1] end end end brute.argc("-t","timeout") brute.argc("-o","outfile") brute.argc("-a","alphabet") brute.argc("-l","length") if arg[2] == "-f" then checkf(arg[3],"hashes ") if brute.outfile then local f = io.open(brute.outfile,"w") f:write("hash:string\n") f:close() end local cracks = {} cracks.done = 0 cracks.failed = 0 for l in io.lines(arg[3]) do local hash, cracked = force(arg[3],true,brute.timeout,brute.outfile,brute.alphabet,brute.length) if cracked then print("\nmatch found: " .. hash .. ":" .. cracked) print("hashes cracked: " .. cracks.done) print("failed cracks: " .. cracks.failed) print("words tried: " .. #tried .. "\n") cracks.done = cracks.done + 1 else print("\nfailed to crack " .. hash .. "\n") cracks.failed = cracks.failed + 1 end end elseif arg[2] then local hash, cracked = force(arg[2],brute.timeout,brute.outfile,brute.alphabet,brute.length) if cracked then print("\nmatch found: " .. cracked) print("words tried: " .. #tried) else print("\ncracking failed.") end else err.few_args() end end function crawler() if (not arg[3]) or (arg[3] == "-f" and not arg[4]) or (arg[4] == "-f" and not arg[5]) or (arg[2] == "-l" and not arg[4]) then err.few_args() elseif arg[3] == "-f" then checkf(arg[4],"hashes ") elseif arg[4] == "-f" then checkf(arg[5],"hashes ") end if arg[5] then local o = io.open(arg[5],"a") end if arg[4] == "-o" then os.remove(arg[5]) end if arg[2] == "-b" then function gen() local w = rand(1,255) local x = rand(1,255) local y = rand(1,255) local z = rand(1,255) local ip = w .. "." .. x .. "." .. y .. "." .. z return ip end elseif arg[2] == "-l" then checkf(arg[3],arg[3] .. " ") local host = {} if arg[4] == "-d" then host.domain = arg[5] else host.domain = ".com" end local rout = coroutine.create( function() for l in io.lines(arg[3]) do local hostname = l .. host.domain coroutine.yield(hostname) end return nil end ) function gen() local bool, hostname = coroutine.resume(rout) return hostname end else err.unknown_arg(arg[2],"2 (web crawling mode)") end if arg[3] ~= "-f" and arg[4] ~= "-f" then function try(w) if md5.sumhexa(w) == arg[3] then print("match found: " .. w) print("hostnames tried: " .. #tried.host) print("words tried: " .. #tried.word) os.exit(0) end end else if arg[3] == "-f" then checkf(arg[4],"hashes ") elseif arg[4] == "-f" then checkf(arg[5],"hashes ") end function try(w) for l in io.lines(arg[3]) do if md5.sumhexa(w) == l then print("match found: " .. w) print("hostnames tried so far: " .. #tried.host) print("words tried so far: " .. #tried.word .. "\n") if arg[4] == "-o" then o:write(l .. ":" .. w .. "\n") end end end end end require("socket") tried.host = {} tried.word = {} while true do tried.tmp = gen() while tried.host[tried.tmp] do tried.tmp = gen() end local host = tried.tmp if not host then print("no matches found.") print("hostnames tried: " .. #tried.host) print("words tried: " .. #tried.word) os.exit(0) end local s = socket.connect(host,80) if s then s:settimeout(0) s:send("GET / HTTP/1.0\r\n\r\n") while true do local data, stat, part = s:receive(1024) for w in (data or part):gmatch("%S+") do if not tried.word[w] then try(w) tried.word[w] = true tried.word[#tried.word + 1] = true end end if stat == "closed" then break end end s:close() tried.host[host] = true tried.host[#tried.host + 1] = true end end end -------------------------------------------------------------------------------- -- main structure -------------------------------------------------------------------------------- if not arg[1] or arg[1] == "--help" then usage() else if arg[1] == "--about" then about() elseif arg[1] == "-c" then if not arg[4] or not arg[2] then err.few_args() else cracker() end elseif arg[1] == "-b" then brute() elseif arg[1] == "-h" then print(md5.sumhexa(arg[2])) elseif arg[1] == "-f" then checksum() elseif arg[1] == "-l" then listf() elseif arg[1] == "-w" then crawler() else err.unknown_arg(arg[1],"1") end end



RE: [Lua] LMC - MD5 cracker - noize - 08-10-2013

update: version 2.0 out now.


RE: [Lua] LMC - MD5 cracker - noize - 08-10-2013

update: version 2.0 out now.


RE: [Lua] LMC - MD5 cracker - Deque - 08-10-2013

Nice tool and lots of useful features. But it needs polishing.
A huge if-else-if pile of code is always a sign of bad smelling code. I recommend to use some functions for structuring your code and encapsulating reusable parts.


RE: [Lua] LMC - MD5 cracker - Deque - 08-10-2013

Nice tool and lots of useful features. But it needs polishing.
A huge if-else-if pile of code is always a sign of bad smelling code. I recommend to use some functions for structuring your code and encapsulating reusable parts.


RE: [Lua] LMC - MD5 cracker - noize - 08-10-2013

(08-10-2013, 09:36 AM)Deque Wrote: Nice tool and lots of useful features. But it needs polishing.
A huge if-else-if pile of code is always a sign of bad smelling code. I recommend to use some functions for structuring your code and encapsulating reusable parts.

Will be done, just as I'll add the bruteforcing function, in 2.1.

update: version 2.1 out now.


RE: [Lua] LMC - MD5 cracker - noize - 08-10-2013

(08-10-2013, 09:36 AM)Deque Wrote: Nice tool and lots of useful features. But it needs polishing.
A huge if-else-if pile of code is always a sign of bad smelling code. I recommend to use some functions for structuring your code and encapsulating reusable parts.

Will be done, just as I'll add the bruteforcing function, in 2.1.

update: version 2.1 out now.


RE: [Lua] LMC - MD5 cracker - noize - 10-19-2013

update: 2.3 out now.


RE: [Lua] LMC - MD5 cracker - noize - 10-19-2013

update: 2.3 out now.