您的位置:首页 > 编程语言 > Python开发

从0开始玩安全--Python篇--Python入门指导 & 案例Unixshadow密码破解

2016-06-18 22:03 483 查看
Python 真是一门友好的语言,如果你有c或者其他常见编程语言基础,入门只需一天



入门请撸violent Python 第一章,刷廖雪峰老师的入门课 http://www.imooc.com/learn/177,手边一本《Python核心编程第二版》备查



进入今天的正题



先说说Unix的shadow文件,此文件用来存储系统用户名和密码的密文,root用户有读写权限,其它用户看不到密文,举个例子





root:$1$TCVDVaiT$JC7TbKjvIZpIprdehWFH/1:15157:0:




用户名(login name)。
加密后的密码(形如:$1$2eWq10AC$NaQqalCk3InEPBrIxjaJQ1)。如果密码是"*"或"!",则表示这个不会用这个帐号来登录(通常是一些后台进程)。
密码最后修改时间,从1970年1月1日起计算的天数。
不可修改密码的天数。如果是0,表示随时可修改密码。如果是N,表示N天后才能修改密码。
密码可以维系的天数。如果设置为N,则表示N天后必须更新密码。设置为99999通常表示无需更新密码。
在密码必须修改前的N天,就开始提示用户需要修改密码。
密码过期的宽限时间。
帐号失效时间。也是UNIX时间戳格式。
最后一个字段是保留字段。


/etc/shadow中的密码格式:
$id$salt$encrypted


id表示hash算法。起初密码用DES算法加密,但因随DES加密破解难度的降低,已用其他加密算法替代DES。在shadow文件中,密码字段如果以"$"打头,则表示非DES加密,如:
$1$2eWq10AC$NaQqalCk3InEPBrIxjaJQ1


即表示非DES加密密码。而
$1$
表示使用了基于MD5的加密算法。
$2a$04$NZJWn7W2skvQRC5lW3H7q.ZTE8bz4xbCAtU1ttzUOy63si3phphUu


$2a$
表示Blowfish算法。常见的标识与算法:
ID算法
$1$MD5
$2a$Blowfish
$5$SHA-256
$6$SHA-512
$1$2eWq10AC$


这段叫作salt ,unix密码采用了常见密码算法结合salt的方式来加密,一定程度防止了彩虹表等方法破解

BUT!

Python提供了一个crypt库,直接给了这种算法的接口,只要你了解salt的生成方式就可以暴力破解密码

经过分析我们发现unix的salt是由 {$id$固定位数的随机字符$} 组成的,于是就有了以下的程序思路



思路———1.分别读入shadow文件和字典文件,通过shadow每一行的第二段字符串判断是不是可登陆的用户。

  2.截取一行的salt字段,调用crypt方法,根据字典里的密码明文生成密文与shadow的密文字段对比就

  3.循环第2点,直到找到密码或者找不到密码,跳向下一个用户行

以下贴上一个示例源码

#Function :crack password in UNIX shadow
#Usage: python ShadowCracker.py [shadow file] [dictionary file]
import hashlib
import crypt
import sys
import os

def testpass(cryptedpass):<span style="white-space:pre"> </span>#用来测试字典里的密码的函数
salt = cryptedpass[0:13] <span style="white-space:pre"> </span>#截取salt
try:<span style="white-space:pre"> </span>
dictfile = open(sys.argv[2],'r')
except Exception, e:<span style="white-space:pre"> </span>#异常判断
print "Error ! "+str(e)
exit(0)

for word in dictfile.readlines():
word = word.strip('\n')
hash = crypt.crypt(word,salt) #生成加密后的密文
if (hash == cryptedpass):<span style="white-space:pre"> </span>#进行比较
print "[+] Found Password: "+word+" \n"
return
print "[-] Not Found Password"
return

def main():
if len(sys.argv) == 3:
try:
shadowfile = open(sys.argv[1])
except Exception, e:<span style="white-space:pre"> </span>#异常判断
print "Error ! "+str(e)
exit(0)
else:
print "Usage: python ShadowCracker.py [shadow file] [dictionary file]"
exit(0)

for line in shadowfile.readlines():<span style="white-space:pre"> </span>#循环
if (":" in line) and (len(line.split(':')[1]) > 2):<span style="white-space:pre"> </span>#判断是不是有效用户
user = line.split(':')[0]<span style="white-space:pre"> </span>#截取用户名
CryptedPass = line.split(':')[1]
print "[*] Cracking Password For: "+user
testpass(CryptedPass)

if __name__=='__main__':
main()

那么,问题来了,这个程序有什么缺点?你能不能把这个示例程序再完善完善呢?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息