Meszias

Automatic Reverse SSH Tunnel

Apr 10th, 2013
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.40 KB | None | 0 0
  1. import pty, re, os, sys, stat, signal
  2. global pty, re, os, sys, stat, signal
  3. global REMOTE_SSH_PORT, LOCAL_SSH_PORT, IP_PW_USR_PORT, ENABLE, SSHError, SSH
  4.  
  5. REMOTE_SSH_PORT = 1300
  6. LOCAL_SSH_PORT = 22
  7. IP_PW_USR_PORT = ('mycoolhost.com', 'mysecretpassword', 'rasp', 22)
  8. #ENABLE = False
  9. ENABLE = True
  10.  
  11.  
  12. class SSHError(Exception):
  13.     def __init__(self, value):
  14.         self.value = value
  15.     def __str__(self):
  16.         return repr(self.value)
  17.  
  18. class SSH:
  19.     def __init__(self, ip, passwd, user, port):
  20.         self.ip = ip
  21.         self.passwd = passwd
  22.         self.user = user
  23.         self.port = port
  24.        
  25.     def rev_ssh(self, local_port, remote_port):
  26.         # ssh -f -N -T -R 1100:localhost:22 [email protected]
  27.         (pid, f) = pty.fork()
  28.         if pid == 0:
  29.             os.execlp("ssh", "ssh", '-p %d' % self.port,
  30.                       self.user + '@' + self.ip, '-f', '-N', '-T', '-R' , '%d:localhost:%d' % (remote_port, local_port))
  31.         else:
  32.             return (pid, f)
  33.            
  34.     def run_cmd(self, c):
  35.         (pid, f) = pty.fork()
  36.         if pid == 0:
  37.             os.execlp("ssh", "ssh", '-p %d' % self.port,
  38.                       self.user + '@' + self.ip, '-R',
  39.                       '%d:localhost:%d' % (REMOTE_SSH_PORT, LOCAL_SSH_PORT) ,c)
  40.         else:
  41.             return (pid, f)
  42.            
  43.     def push_file(self, src, dst):
  44.         (pid, f) = pty.fork()
  45.         if pid == 0:
  46.             os.execlp("scp", "scp", '-P %d' % self.port,
  47.                       src, self.user + '@' + self.ip + ':' + dst)
  48.         else:
  49.             return (pid, f)
  50.  
  51.     def push_dir(self, src, dst):
  52.         (pid, f) = pty.fork()
  53.         if pid == 0:
  54.             os.execlp("scp", "scp", '-P %d' % self.port, "-r", src,
  55.                       self.user + '@' + self.ip + ':' + dst)
  56.         else:
  57.             return (pid, f)
  58.    
  59.     def _read(self, f):
  60.         x = ''
  61.         try:
  62.             x = os.read(f, 1024)
  63.         except Exception, e:
  64.             # this always fails with io error
  65.             pass
  66.         return x
  67.  
  68.     def ssh_results(self, pid, f, read_after_password=True):
  69.         output = ""
  70.         got = self._read(f)         # check for authenticity of host request        
  71.         m = re.search("authenticity of host", got)
  72.         if m:
  73.             os.write(f, 'yes\n')
  74.             # Read until we get ack
  75.             while True:
  76.                 got = self._read(f)
  77.                 m = re.search("Permanently added", got)
  78.                 if m:
  79.                     break
  80.             got = self._read(f)         # check for passwd request
  81.         m = re.search("assword:", got)
  82.         if m:
  83.             # send passwd
  84.             os.write(f, self.passwd + '\n')
  85.             # read two lines            
  86.             if read_after_password:
  87.                 tmp = self._read(f)
  88.                 tmp += self._read(f)
  89.                 m = re.search("Permission denied", tmp)
  90.                 if m:
  91.                     raise Exception("Invalid passwd")
  92.                 # passwd was accepted
  93.                 got = tmp
  94.             else:
  95.                 got = ''
  96.  
  97.         while got and len(got) > 0:
  98.             output += got
  99.             got = self._read(f)
  100.         os.waitpid(pid, 0)
  101.         os.close(f)
  102.         return output
  103.    
  104.     def revssh(self, local, remote):
  105.         (pid, f) = self.rev_ssh(local, remote)
  106.         return self.ssh_results(pid, f, False)
  107.  
  108.     def cmd(self, c):
  109.         (pid, f) = self.run_cmd(c)
  110.         return self.ssh_results(pid, f)
  111.  
  112.     def push(self, src, dst):
  113.         s = os.stat(src)
  114.         if stat.S_ISDIR(s[stat.ST_MODE]):
  115.             (pid, f) = self.push_dir(src, dst)
  116.         else:
  117.             (pid, f) = self.push_file(src, dst)
  118.         return self.ssh_results(pid, f)
  119.  
  120. def ssh_cmd(ip, passwd, user, port, cmd):
  121.     s = SSH(ip, passwd, user, port)
  122.     return s.cmd(cmd)
  123.    
  124. def rev_ssh(ip, passwd, user, port, local_port=22, rem_port=1100):
  125.     s = SSH(ip, passwd, user, port)
  126.     return s.revssh(local_port, rem_port)
  127.  
  128. def ssh_push(ip, passwd, src, dst, user, port=22):
  129.     s = SSH(ip, passwd, user, port)
  130.     return s.push(src, dst)
  131.  
  132.  
  133. def getSshPids():    
  134.     pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
  135.     sshpids = []
  136.     for pid in pids:
  137.         try:
  138.             cmdl =  open(os.path.join('/proc', pid, 'cmdline'), 'rb').read()
  139.             if '\x00-R\x00' in cmdl:
  140.                 sshpids.append(pid)
  141.         except:
  142.             pass
  143.     return sshpids
  144.  
  145. def killPids(sshpids):
  146.     for pid in sshpids:
  147.         try:
  148.             os.kill(int(pid), signal.SIGTERM)
  149.         except:
  150.             pass
  151.  
  152. #############################################################################
  153. #                        Programa Principal                                 #
  154. #############################################################################
  155.  
  156. ssh_pids = getSshPids()
  157.  
  158. # Desabilitando ssh reverso
  159. if ssh_pids and not ENABLE:
  160.     killPids(ssh_pids)
  161.     log.info('Disabled')
  162.  
  163. # Criando ssh reverso
  164. elif not ssh_pids and ENABLE:
  165.     # estabelece primeira conexao
  166.     log.info('enabled')
  167.     reg(69)
  168.     ret = ssh_cmd(*IP_PW_USR_PORT, cmd='ls; time sleep 300;')
  169.     log.info(ret)
  170.     # estabelece conexao abrindo porta reversa
  171.     #cfgs = IP_PW_USR_PORT + (LOCAL_SSH_PORT, REMOTE_SSH_PORT)
  172.     #ret = rev_ssh(*cfgs)        
  173.     log.info('closed')
  174.    
  175. else:
  176.     log.info('No action')
Advertisement
Add Comment
Please, Sign In to add comment