Run remote commands via IRC messages.
Author: TxGVNN
— Version: 1.1
— License: GPL-3.0-or-later
For WeeChat ≥ 0.3.0.
Tags: irc, exec, py2, py3
Added: 2018-09-29
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | # -*- coding: utf-8 -*- # execbot.py # ExecBot - Executing bot # ============================== # # Copyright (C) 2018 Giap Tran <txgvnn@gmail.com> # https://github.com/txgvnn/weechat-execbot # # == About ===================== # Execbot is a bot can execute the command from IRC message # (You maybe want to call it is a kind of backdoor) # # With server is installed execbot script, the client can execute the # command remote by send privmsg to server's nick in IRC network # # == Usage ===================== # /excebot list List server.nicknames are allowed # /execbot add -server <server> nicknames.. Add server.nicknames are allowed to execute # /execbot del -server <server> nicknames.. Remove server.nicknames are allowed # # == NOTICE ==================== # This is a POC that I want to execute a remote command via IRC # network. It's really not security, although you can set who can # talk with the bot. # # PLEASE CONSIDER CAREFULLY WHEN USING THE PLUGIN import weechat SCRIPT_NAME = 'execbot' SCRIPT_AUTHOR = 'Giap Tran <txgvnn@gmail.com>' SCRIPT_VERSION = '1.1' SCRIPT_LICENSE = 'GPL3' SCRIPT_DESC = 'Executing bot' SCRIPT_HELP_TEXT = ''' %(bold)sExecbot command options: %(normal)s list List nicknames add -server <server> <nicknames...> Add server.nicknames are allowed to execute del -server <server> <nicknames...> Del server.nicknames are allowed %(bold)sExamples: %(normal)s Allow john and jack in oftc server to talk with bot /execbot add -server oftc john jack ''' % {'bold':weechat.color('bold'), 'normal':weechat.color('-bold')} execbot_config_file = None execbot_config_section = {} execbot_allows = {} def execbot_config_init(): '''Init configuration file''' global execbot_config_file execbot_config_file = weechat.config_new('execbot', 'execbot_config_reload_cb', '') if not execbot_config_file: return execbot_config_section['allows'] = weechat.config_new_section( execbot_config_file, 'allows', 0, 0, 'execbot_config_allows_read_cb', '', 'execbot_config_allows_write_cb', '', '', '', '', '', '', '') if not execbot_config_section['allows']: weechat.config_free(execbot_config_file) def execbot_config_reload_cb(data, config_file): '''Handle a reload of the configuration file.''' global execbot_allows execbot_allows = {} return weechat.config_reload(config_file) def execbot_config_allows_read_cb(data, config_file, section_name, option_name, value): '''Read elements of the allows section from the configuration file.''' execbot_allows[option_name.lower()] = value return weechat.WEECHAT_CONFIG_OPTION_SET_OK_CHANGED def execbot_config_allows_write_cb(data, config_file, section_name): '''Write infomation to the allows section of the configuration file.''' weechat.config_write_line(config_file, section_name, '') for username, right in sorted(list(execbot_allows.items())): weechat.config_write_line(config_file, username.lower(), right) return weechat.WEECHAT_RC_OK def execbot_config_read(): ''' Read Execbot configuration file (execbot.conf).''' return weechat.config_read(execbot_config_file) def execbot_config_write(): ''' Write Execbot configuration file (execbot.conf) to disk.''' return weechat.config_write(execbot_config_file) def execbot_command_list(): '''List server.nicknames are allowed.''' nicknames = '\n'.join([' %s' % x for x in execbot_allows.keys()]) # for nickname,_ in sorted(list(execbot_allows.items())): weechat.prnt(weechat.current_buffer(), 'Nicknames are allowed:\n' +nicknames) return weechat.WEECHAT_RC_OK def execbot_command_add(server,nicknames): '''Add nicknames.''' for x in nicknames: execbot_allows['%s.%s'%(server,x.lower())] = 'allow' weechat.prnt(weechat.current_buffer(),'Add permission for %s' % '%s.%s'%(server,x.lower())) return weechat.WEECHAT_RC_OK def execbot_command_del(server,nicknames): '''Remove nicknames.''' for x in nicknames: try: del execbot_allows['%s.%s'%(server,x.lower())] weechat.prnt(weechat.current_buffer(),'Deleted permission of %s' % '%s.%s'%(server,x.lower())) except KeyError: weechat.prnt(weechat.current_buffer(),'No existing %s.%s'%(server,x.lower())) return weechat.WEECHAT_RC_OK def execbot_command(data, buffer, args): '''Hook to handle the /execbot weechat command.''' argv = args.split() # list if not argv or argv == ['list']: return execbot_command_list() # check if a server was set if (len(argv) > 2 and argv[1] == '-server'): server = argv[2] del argv[1:3] args = (args.split(' ', 2)+[''])[2] else: server = weechat.buffer_get_string(buffer, 'localvar_server') if not server: weechat.prnt(weechat.current_buffer(), 'Required -server option') return weechat.WEECHAT_RC_ERROR # add if argv[:1] == ['add']: if len(argv) < 2: return weechat.WEECHAT_RC_ERROR return execbot_command_add(server,argv[1:]) # del if argv[:1] == ['del']: if len(argv) < 2: return weechat.WEECHAT_RC_ERROR return execbot_command_del(server,argv[1:]) execbot_error('Unknown command. Try /help execbot', buffer) return weechat.WEECHAT_RC_OK def execbot_process(buffer, command, return_code, out, err): '''Execute the command and return to buffer.''' message = "%s ... | $? = %d\n" % (command.split()[0], return_code) if out != "": message += out if err != "": message += err weechat.command(buffer, message) return weechat.WEECHAT_RC_OK def execbot_hook_signal(data, signal, signal_data): server = signal.split(",")[0] info = weechat.info_get_hashtable("irc_message_parse", { "message": signal_data }) username = '.'.join([server,info['nick']]) # Check the permission allowed = execbot_allows.get(username.lower()) if not allowed: return weechat.WEECHAT_RC_OK # Prevent public channel if info['channel'].startswith('#'): return weechat.WEECHAT_RC_OK # buffer output buffer = weechat.buffer_search("irc", username) # command _, command = info['arguments'].split(':', 1) # timeout = 5 mins weechat.hook_process(command, 300000, "execbot_process", buffer) return weechat.WEECHAT_RC_OK def execbot_unload_script(): execbot_config_write() return weechat.WEECHAT_RC_OK if __name__ == '__main__' and weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, 'execbot_unload_script','UTF-8'): execbot_config_init() execbot_config_read() weechat.hook_command('execbot', 'Commands to manage Execbot options and execute Execbot commands', '', SCRIPT_HELP_TEXT, 'list %- || add -server %(irc_servers) %(nicks) %-' '|| del -server %(irc_servers) %(nicks) %-', 'execbot_command', '') weechat.hook_signal("*,irc_in2_privmsg", "execbot_hook_signal", "") |