从0开始玩安全--Python篇--Python入门指导 & 案例Unixshadow密码破解
2016-06-18 22:03
483 查看
Python 真是一门友好的语言,如果你有c或者其他常见编程语言基础,入门只需一天
入门请撸violent Python 第一章,刷廖雪峰老师的入门课 http://www.imooc.com/learn/177,手边一本《Python核心编程第二版》备查
进入今天的正题
先说说Unix的shadow文件,此文件用来存储系统用户名和密码的密文,root用户有读写权限,其它用户看不到密文,举个例子
/etc/shadow中的密码格式:
id表示hash算法。起初密码用DES算法加密,但因随DES加密破解难度的降低,已用其他加密算法替代DES。在shadow文件中,密码字段如果以"$"打头,则表示非DES加密,如:
即表示非DES加密密码。而
这段叫作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()
那么,问题来了,这个程序有什么缺点?你能不能把这个示例程序再完善完善呢?
入门请撸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()
那么,问题来了,这个程序有什么缺点?你能不能把这个示例程序再完善完善呢?
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- 10 篇对初学者和专家都有用的 Linux 命令教程
- 谷歌 Project Zero 团队宣布新政策,漏洞披露前将有完整的 90 天缓冲期
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升