Violent python - UNIX Password Cracker&Zipfile Password Cracker

/etc/passwd及/etc/shadow

在写 UNIX Password Cracker之前我们首先要了解UNIX系统是如何保存用户密码的。
/etc/passwd内容如下:
/etc/passwd
/etc/shadow内容如下(密码域结构:$指示加密方式$干扰串$密码hash值):
/etc/shadow
etc/passwd、/etc/shadow文件权限如下:
ls
各域解释如下:
ls -l
(仅上图转载自https://blog.csdn.net/zhuoya_/article/details/77418413)
为此可以看出**/etc/passwd文件所有用户都可以读,而/etc/shadow仅有rootshadow**组用户可以读。

UNIX Password Cracker

UNIX Password Cracker实现思路:

  • 拿到**/etc/shadow**文件然后提取其中的密码域
  • 分析密码域的结构确定salt(即hash算法干扰串
  • 逐条计算字典中的条目的hash值并与密码域的hash值进行比对
比如:
>>> import crypt
>>> dir(crypt)
['__doc__', '__file__', '__name__', '__package__', 'crypt']
>>> crypt.crypt('root','$6$.XjiYlU6$')
'$6$.XjiYlU6$X7ux./bZdhR9.iVRy8UE10Wlk4oD3TxQsw6QymbsNTfreg/2n1Fhj3Ug1qqc.Wkp7/Gb7YcIyotOKYunJhbMV/'
  • 如果相同则对应的密码字典中的词既是密码

完整代码如下:

import crypt
import re 
r = re.compile('(\$\d\$.*\$)')
def testPass(cryptPass):
    if cryptPass:
        print "[+] No Password" 
        return 
    salt = r.findall(cryptPass)
    if not salt:
        print '[-] Password Has Expired or Been Locked'
        return 
    dictFile = open('dictionary.txt','r')
    for word in dictFile.readlines():
        word = word.strip('\n')
        cryptWord = crypt.crypt(word,salt[0])
        if (cryptWord == cryptPass):
            print "[+] Found Password: "+word+"\n"
            return
        print "[-] Password Not Found.\n"
        return
def main():
    passFile = open('passwords.txt')
    for line in passFile.readlines():
        if ":" in line:
            user = line.split(':')[0]
            cryptPass = line.split(':')[1].strip(' ')
            print "[*] Cracking Password For: "+user
            testPass(cryptPass)
if __name__ == "__main__":
    main()

Zipfile Password Cracker

关键点zipfile.ZipFile类实例化后的extactall方法在提取文件内容时通过pwd参数可以指定密码。
Zipfile Password Cracker实现思路:

  • 使用文件名初始化zipfile.ZipFile得到zFile
  • 调用zFile的extracall方法并指定pwd参数
  • 出现异常则可判断密码不正确
  • 否则密码正确

完整代码如下:

import zipfile
import optparse
from threading import Thread
def extractFile(zFile, password):
   try:
       zFile.extractall(pwd=password)
       print '[+] Found password ' + password + '\n'
   except:
       pass
def main():
   parser = optparse.OptionParser("usage%prog "+\
                                  "-f <zipfile> -d <dictionary>")
   parser.add_option('-f', dest='zname', type='string',\
                     help='specify zip file')
   parser.add_option('-d', dest='dname', type='string',\
                     help='specify dictionary file')
   (options, args) = parser.parse_args()
   if (options.zname == None) | (options.dname == None):
       print parser.usage
       exit(0)
   else:
       zname = options.zname
       dname = options.dname
   zFile = zipfile.ZipFile(zname)
   passFile = open(dname)
for line in passFile.readlines():
   password = line.strip('\n')
   t = Thread(target=extractFile, args=(zFile, password))
   t.start()
if __name__ == '__main__':
   main()    

在上述代码中optparse模块已经过期,推荐使用argparse模块,其次是没必要对每一条密码记录开启一个线程,使一个线程处理多条字典密码。改进后代码如下。

import zipfile
import argparse
import sys
import  threading
import Queue
word_list = Queue.Queue()
flag = threading.Event()
def extractFile(zFile):
   while not (word_list.empty() or flag.is_set()):
       try:
           zFile.extractall(pwd=word_list.get())
           print '[+] Found password ' + password + '\n'
           flag.set()
       except:
           pass
def main():
   parser = argparse.ArgumentParser(prog=sys.argv[0], usage="-f <zipfile> -d <dictionary>")
   parser.add_argument('-f', dest='zname', action='store',help='specify zip file')
   parser.add_argument('-d', dest='dname', action='store',help='specify dictionary file')
   options = parser.parse_args()
   if (options.zname == None) | (options.dname == None):
       print parser.usage
       exit(0)
   zname = options.zname
   dname = options.dname
   zFile = zipfile.ZipFile(zname)
   passFile = open(dname)
   for line in passFile.readlines():
       word_list.put(line.strip('\n'))
   for i in range(20):
       t = threading.Thread(target=extractFile, args=(zFile,))
       t.start()
if __name__ == '__main__':
   main()    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值