# License WTFPL, License Details: http://sam.zoy.org/wtfpl/ # Adam Pridgen # SkypeShell Proof of Concept Python Code import Skype4Py, pexpect, time, sys, sets, re, threading from subprocess import * ESCAPE_CODES = ["\x1B[c", "\x1B[5n", "\x1B[0n", "\x1B[3n", "\x1B[6n", "\x1Bc", "\x1B[7h", "\x1B[71", "\x1B(", "\x1B)", "\x1B[s", "\x1B[u", "\x1B7", "\x1B8", "\x1B[r", "\x1B[D", "\x1B[M", "\x1BH", "\x1B[g", "\x1B[3g", "\x1B[K", "\x1B[1K", "\x1B[2K", "\x1B[J", "\x1B[1J", "\x1B[2J", "\x1B[i", "\x1B[4i", "\x1B[5i"] ESCAPE_ATTR = re.compile("\\x1B\[.*m") DEVICE_CODE = re.compile("\\x1B\[.*0c") FT = None COMMANDS = { 'start skype shell':"Start the skype shell interface", 'stop skype shell':"Start the skype shell interface", 'start bash':"starts the bash shell", 'stop bash':"stop the bash shell", 'cmd ':'execute a single command on the remote host', 'help':"print the command help"} SHELLS = {} class SkypeShell: def __init__(self): self.shells = {} self.Me = '' self.PollingMode = False self.Chats = set() self.Poll = None def read(self, shell): data = '' while 1: try: data += shell.read_nonblocking(2048, timeout=1) except: data = "%s"%'\n'.join(data.split("\r\n")) break return data def poll_shells(self): print "Entering poll more" while self.PollingMode: time.sleep(3) self.CheckShells() print "Checked shells" def execute_cmd(self, command, shell): print "Executing command: %s"%command #p = Popen(cmd, shell=False, bufsize=1024, stdin=PIPE, stdout=PIPE) #(child_stdout, child_stdin) = (p.stdout, p.stdin) shell.sendline(command) #return self.read(shell) def CheckShells(self): for shell in self.shells.itervalues(): data = '' data = self.read(shell[0]) if data != '': data = self.remove_escape_codes(data) shell[1].SendMessage(data) def check_codes(self, data): for j in ESCAPE_CODES: if data.startswith(j): return data.strip(j) return '' def remove_escape_codes(self, data): input = data.split("\x1B") filter = [] for i in input: #print i if i == '': continue r = self.check_codes('\x1B'+i) if r != '': filter.append(r) continue r = '\x1B'+i if len(ESCAPE_ATTR.split(r)) == 2: filter.append(ESCAPE_ATTR.split(r)[1]) continue if len(DEVICE_CODE.split(r)) == 2: filter.append(DEVICE_CODE.split(r)[1]) continue filter.append(i) return " ".join(filter) def HandleMsg(self, Message): body = Message.Body m = '' #body = body.split(':') print "Recieved Msg: %s\n"%body #self.CheckShells() body = body.strip().lstrip() if body.lower() == "start bash": p = pexpect.spawn("bash") p.read_nonblocking(4096, timeout=2) p.setecho(False) self.shells[Message.ChatName] = (p, Message.Chat) m = "Started Bash Shell" self.Poll = threading.Thread(None, self.poll_shells, None, ()) if not self.PollingMode: self.PollingMode = True self.Poll.start() Message.Chat.SendMessage(m) elif body.lower() == "stop bash" and\ Message.ChatName in self.shells: self.shells[Message.ChatName][0].close() del self.shells[Message.ChatName] m = "Stopped bash shell" Message.Chat.SendMessage(m) if len(self.shells) == 0: self.PollingMode = False elif body.split()[0].lower() == 'cmd' and\ Message.ChatName in self.shells: cmd = " ".join(body.split()[1:]) shell = self.shells[Message.ChatName] self.execute_cmd(cmd, shell[0]) #m = self.remove_escape_codes(m) return def print_help(self): m = '' for cmd in COMMANDS: m = m + "%s %s\n"%(cmd, COMMANDS[cmd]) return m def MessageStatus(self, Message, Status): body = Message.Body body = body.strip().lstrip() body = body.lower() print self.Me, Message.FromHandle if Message.Status == 'SENT' or \ Message.Status == 'SENDING': return elif body == 'stop skype shell': self.Chats.remove(Message.ChatName) for shell in self.shells.itervalues(): shell[0].close() self.shells.clear() Message.Chat.SendMessage("Skype Shell Stopped, all bash shells terminated") elif body == 'help': Message.Chat.SendMessage(self.print_help()) elif body == 'start skype shell': self.Chats.add(Message.ChatName) Message.Chat.SendMessage("Skype Shell Started") elif Message.ChatName in self.Chats and \ Message.FromHandle != self.Me: print "handling command" self.HandleMsg(Message) # Create Skype instance print "Skype Shell 0.1a Proof of Concept" print "Provides basic bash access: type help" s = SkypeShell() skype = Skype4Py.Skype() s.Me = skype.CurrentUser.Handle skype.RegisterEventHandler('MessageStatus', s.MessageStatus) print "Created Skype Object" # Connect Skype object to Skype client skype.Attach() print "Attached to Skype CLient" # create our shell