PenetrationTestingScripts/Weak_Password/Bruteforce/plugins/rsynclib.py

195 lines
5.8 KiB
Python

import base64
import re
try:
import hashlib
hash_md4 = hashlib.new("md4")
hash_md5 = hashlib.md5()
except ImportError:
# for Python << 2.5
import md4
import md5
hash_md4 = md4.new()
hash_md5 = md5.new()
# Import SOCKS module if it exists, else standard socket module socket
try:
import SOCKS; socket = SOCKS; del SOCKS # import SOCKS as socket
from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn
except ImportError:
import socket
from socket import _GLOBAL_DEFAULT_TIMEOUT
__all__ = ["rsync"]
# The standard rsync server control port
RSYNC_PORT = 873
# The sizehint parameter passed to readline() calls
MAXLINE = 8192
protocol_version = 0
# Exception raised when an error or invalid response is received
class Error(Exception): pass
# All exceptions (hopefully) that may be raised here and that aren't
# (always) programming errors on our side
all_errors = (Error, IOError, EOFError)
# Line terminators for rsync
CRLF = '\r\n'
LF = '\n'
# The class itself
class rsync:
'''An rsync client class.
To create a connection, call the class using these arguments:
host, module, user, passwd
All arguments are strings, and have default value ''.
Then use self.connect() with optional host and port argument.
'''
debugging = 0
host = ''
port = RSYNC_PORT
maxline = MAXLINE
sock = None
file = None
server_protocol_version = None
# Initialization method (called by class instantiation).
# Initialize host to localhost, port to standard rsync port
# Optional arguments are host (for connect()),
# and module, user, passwd (for login())
def __init__(self, host='', module='', user='', passwd='',port=873,
timeout=_GLOBAL_DEFAULT_TIMEOUT):
self.timeout = timeout
if host:
self.connect(host)
if module and user and passwd:
self.login(module, user, passwd)
def connect(self, host='', port=0, timeout=-999):
'''Connect to host. Arguments are:
- host: hostname to connect to (string, default previous host)
- port: port to connect to (integer, default previous port)
'''
if host != '':
self.host = host
if port > 0:
self.port = port
if timeout != -999:
self.timeout = timeout
self.sock = socket.create_connection((self.host, self.port), self.timeout)
self.af = self.sock.family
self.file = self.sock.makefile('rb')
self.server_protocol_version = self.getresp()
self.protocol_version = self.server_protocol_version[-2:]
return self.server_protocol_version
def set_debuglevel(self, level):
'''Set the debugging level.
The required argument level means:
0: no debugging output (default)
1: print commands and responses but not body text etc.
'''
self.debugging = level
debug = set_debuglevel
# Internal: send one line to the server, appending LF
def putline(self, line):
line = line + LF
if self.debugging > 1: print '*put*', line
self.sock.sendall(line)
# Internal: return one line from the server, stripping LF.
# Raise EOFError if the connection is closed
def getline(self):
line = self.file.readline(self.maxline + 1)
if len(line) > self.maxline:
raise Error("got more than %d bytes" % self.maxline)
if self.debugging > 1:
print '*get*', line
if not line: raise EOFError
if line[-2:] == CRLF: line = line[:-2]
elif line[-1:] in CRLF: line = line[:-1]
return line
# Internal: get a response from the server, which may possibly
# consist of multiple lines. Return a single string with no
# trailing CRLF. If the response consists of multiple lines,
# these are separated by '\n' characters in the string
def getmultiline(self):
line = self.getline()
return line
# Internal: get a response from the server.
# Raise various errors if the response indicates an error
def getresp(self):
resp = self.getmultiline()
if self.debugging: print '*resp*', resp
if resp.find('ERROR') != -1:
raise Error, resp
else:
return resp
def sendcmd(self, cmd):
'''Send a command and return the response.'''
self.putline(cmd)
return self.getresp()
def login(self, module='', user = '', passwd = ''):
if not user: user = 'www'
if not passwd: passwd = 'www'
if not module: module = 'www'
self.putline(self.server_protocol_version)
# self.putline('@RSYNCD: 28.0')
# self.protocol_version = 28
resp = self.sendcmd(module)
challenge = resp[resp.find('AUTHREQD ')+9:]
if self.protocol_version >= 30:
md5=hashlib.md5()
md5.update(passwd)
md5.update(challenge)
hash = base64.b64encode(md5.digest())
else:
md4=hashlib.new('md4')
tmp = '\0\0\0\0' + passwd + challenge
md4.update(tmp)
hash = base64.b64encode(md4.digest())
response, number = re.subn(r'=+$','',hash)
print response
resp = self.sendcmd(user + ' ' + response)
if resp.find('OK') == -1:
raise Error, resp
return resp
def getModules(self):
'''Get modules on the server'''
print self.server_protocol_version
self.putline(self.server_protocol_version)
resp = self.sendcmd('')
print resp
return resp
def close(self):
'''Close the connection without assuming anything about it.'''
self.putline('')
if self.file is not None:
self.file.close()
if self.sock is not None:
self.sock.close()
self.file = self.sock = None