def print_lines(file):
with open(file) as f:
for line in f:
print(line)
def return_list(file):
with open(file) as f:
list = f.readlines()
return list
def remove_line_containing_string(file):
f = open(file, 'r')
contents = f.readlines()
f.close()
f = open(file, 'w')
for line in contents:
if not 'some string' in line:
f.write(line)
f.close()
def file_exists(file):
if os.path.isfile(file):
return True
else:
return False
def find_and_replace_in_file(inp_file, old, new):
new_output = ''
with open(inp_file, 'U') as f:
new_output = f.read()
while old in new_output:
new_output = new_output.replace(old, new)
with open(inp_file, 'w') as f:
f.write(new_output)
Resource: https://bhagat.blog/2017/01/06/replacing-string-in-a-file-using-python/
This can be found as part of mypyutils
def run_cmd(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
p_status = p.wait()
return output
python3 -m http.server <port>
web_server.py:
from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket
class HTTPServerV6(HTTPServer):
address_family = socket.AF_INET6
server = HTTPServerV6(('::', 8080), SimpleHTTPRequestHandler)
server.serve_forever()
Resource: https://stackoverflow.com/questions/25817848/python-3-does-http-server-support-ipv6
python -m SimpleHTTPServer <port>
import getpass
try:
password = getpass.getpass()
except Exception as error:
print('ERROR', error)
Resource: https://www.geeksforgeeks.org/getpass-and-getuser-in-python-password-without-echo/
>>> import re
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)
'Isaac Newton'
>>> m.group(1)
'Isaac'
>>> m.group(2)
'Newton'
>>> m.group(1,2)
('Isaac', 'Newton')
Resource: https://docs.python.org/2/library/re.html
# input could be something like:
# dog 2
pattern = re.compile("\w+(\d+)")
with open(file) as f:
for line in f:
m = pattern.match(line)
if m:
print(f"Found this item: {m.group(1)}")
>>> l = [1,2,3,4]
>>> rl = l[::-1]
>>> rl
[4, 3, 2, 1]
Resource: https://stackoverflow.com/questions/47025356/reverse-index-in-a-list
len(list)
Resource: https://stackoverflow.com/questions/4130027/python-count-elements-in-list
string.split()
Resource: https://stackoverflow.com/questions/8266529/python-convert-string-to-list
a_list = ["a", "b", "c"]
joined_string = ",".join(a_list)
Resource: https://www.kite.com/python/answers/how-to-make-a-list-into-a-comma-separated-string-in-python
if not a:
print("List is empty")
Resource: https://stackoverflow.com/questions/53513/how-do-i-check-if-a-list-is-empty
Resource: https://stackoverflow.com/questions/1270990/how-to-remove-two-chars-from-the-beginning-of-a-line
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
os.remove('path/to/file')
if os.path.isdir(self.repo_name):
shutil.rmtree(self.repo_name)
import glob, os
for f in glob.glob("*.jpg"):
os.remove(f)
from pathlib import Path
for p in Path(".").glob("*.jpg"):
p.unlink()
from mypyutils import sysutils
output = sysutils.run_cmd('aws ec2 describe-images --filters \
"Name=name,Values=Kali-X2Go" --output json')
This for loop:
for x in range(int(sp),int(ep)+1):
port_scan(site,int(x))
can also be represented as this list comprehension:
[port_scan(site, int(x)) for x in range(int(sp), int(ep)+1)]
Similar concept to a list comprehension.
This will create a dictionary that maps an idea to the number of times someone has had it if the idea is greater than 4 characters:
all_my_ideas = {idea:ideas.count(idea) for idea in ideas if len(idea) > 4}
Resource: https://stackoverflow.com/questions/3496518/using-a-dictionary-to-count-the-items-in-a-list
import os
site = 'https://google.com'
os.system(f"open -a /Applications/Google\ Chrome.app {site}")
In the event you need to have a ‘{’ in your string, use ‘{{’ to escape it
>>> foo = 'test'
>>> f'{foo} {{bar}}'
'test {bar}'
Resource: https://stackoverflow.com/questions/42521230/how-to-escape-f-strings-in-python-3-6
import os
site = 'https://google.com'
os.system("open -a /Applications/Google\ Chrome.app %s" % site)
with open(file) as f:
for line in f:
print(run_cmd("nmap --open -Pn -top-ports 1000 -T4 -sS -g80 -sC -sV {target}".format(target=line)))
Resource: https://realpython.com/python-string-formatting/
list = [
'item1',
'item2',
]
pip freeze > requirements.txt
import pdb; pdb.set_trace()
If you want to be able to test an if statement (for example) in pdb, you’ll need
to run this first:
!import code; code.interact(local=vars())
The ability to examine classes, functions and keywords to get a better sense for what they do.
Resource: https://jobtensor.com/Tutorial/Python/en/Code-Introspection
obj.rstrip().replace('"', '')
def check_root():
if not os.geteuid() == 0:
sys.exit('This script must be run as root!')
import paramiko
k = paramiko.RSAKey.from_private_key_file("/path/to/pem/file")
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect( hostname = "<ec2 hostname>", username = "<username>", pkey = k )
stdin , stdout, stderr = c.exec_command("<command to run>")
print("stdout: " + stdout.read().decode('utf-8'))
print("stderr" + stderr.read().decode('utf-8'))
c.close()
Resource: http://diego-pacheco.blogspot.com/2016/05/having-fun-with-boto-3.html
Use https://github.com/kennethreitz/autoenv, which can be installed via brew, pip, etc.
Once it’s installed, add this line to your bash_rc or zshrc or whatever (the path
will vary based on which installation method you used):
source /usr/local/opt/autoenv/activate.sh
Once this is done, you simply drop a .env file into the directory which has a virtualenv,
that should look like this:
source .venv/bin/activate
Now whenever you cd into this directory, virtualenv will automatically be activated.
You will have to deactivate manually when you leave though.
This is a great guide for writing python code in general.
The Google guide is also quite helpful.
A nice example can be found here for google style.
Resource: https://github.com/pypa/pipenv/issues/1781
You want to do this before a release:
pipenv run python -V
pipenv run python -c 'print("A" * 32)'
CTRL-d or type exit
pipenv install -r requirements.txt
Resources:
brew install pyenv
echo 'PATH=$(pyenv root)/shims:$PATH' >> ~/.zshrc
PY_VER=3.8.12
pyenv install "${PY_VER}"
PY_VER=3.8.12
pyenv local "${PY_VER}"
PY_VER=3.8.12
pyenv global "${PY_VER}"
Resource: https://opensource.com/article/20/4/pyenv
The index() function gets the index of the first occurrence of a char starting
from the beginning of a string and returns it.
The rindex() function gets the index of the first occurrence of a char starting
from the end of a string and returns it.
>>> s = "dedjdedl"
>>> s.index('d')
0
>>> s.rindex('d')
6
>>> l1 = ['a','b','c']
>>> l2 = [1,2,3]
>>> print(list(zip(l1,l2)))
[('a', 1), ('b', 2), ('c', 3)]
combined = zip(list1, list2)
for list1, list2 in combined:
print(list1)
>>> a = [[1,2],[3,4],[5,6]]
>>> print(list(zip(*a)))
[(1, 3, 5), (2, 4, 6)]
Store unordered collections of unique elements
>>> items = [1,5,2,2,3,5,1]
>>> set(items)
{1, 2, 3, 5}
for idx, val in enumerate(list_of_stuff):
print(idx)
print(val)
for i in range(start, end, 100):
Resource: https://stackoverflow.com/questions/4930404/how-do-get-more-control-over-loop-increments-in-python
import random
print(random.randint(1,101))
with fileinput.FileInput("file.txt", inplace=True) as file:
for line in file:
print(line.replace('stringtoreplace', 'replacementstring'), end='')
https://stackoverflow.com/questions/17140886/how-to-search-and-replace-text-in-a-file-using-python
def id_generator(size=20, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
run_cmd(f"gnome-terminal --tab --active -- bash -c 'ls ; exec bash'")
print('This is a really long string' \
'and it should be broken up')
web_lport = 8000
def start_webserver():
url = f"localhost:{web_lport}"
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", web_lport), handler)
print(f"Web server starting on port {web_lport}")
server_process = multiprocessing.Process(target=httpd.serve_forever)
server_process.daemon = True
server_process.start()
return server_process
server_process = start_webserver()
# Do stuff
print(f"Closing web server running on port {web_lport}")
server_process.terminate()
if [[ "$(pgrep tmux)" ]]; then
kill -9 `top -n 1 | pgrep tmux`
fi
tmux new -s web_server -d 'python -m SimpleHTTPServer'
sleep 1
python do_things.py
Resources: https://superuser.com/questions/927544/run-command-in-detached-tmux-session-and-log-console-output-to-file https://gist.github.com/pwittchen/531c0bed8a20c1f06231
with open("test.txt", "a") as myfile:
myfile.write("appended text")
Resource: https://stackoverflow.com/questions/4706499/how-do-you-append-to-a-file-in-python
s = """ this is a very
long string if I had the
energy to type more and more ..."""
Resource: https://stackoverflow.com/questions/10660435/pythonic-way-to-create-a-long-multi-line-string
A hex character can be included by doing the following (observe the \x09):
headers = {
'Host': host+':'+port,
'Content-Length': '85',
'Transfer\x09-Encoding': 'chunked',
}
Another example:
data = '0\x0d\x0a\x0d\x0a' \
'GET /' \
'/ HTTP/1.1\x0d\x0aHost: ' + host + ':' + port'
This is done by using a prepared request. In this example, the content-length will be set to 85, no matter what:
s = requests.Session()
req = requests.Request("POST", protocol+'://'+host+':'+port,
headers=headers, data=data)
prepped = req.prepare()
prepped.headers['Content-Length'] = 85
s.send(prepped)
This is useful for intercepting requests coming from a piece of malware that’s python-based.
proxies = {"http": "http://127.0.0.1:8090", "https": "http://127.0.0.1:8090"}
response = requests.post(target_url, headers=headers, json=data, verify=False, timeout=15,
proxies=proxies)
Resource: https://www.th3r3p0.com/random/python-requests-and-burp-suite.html
python -c 'print "A" * 32'
Copy output using pbcopy in OSX:
python -c "print('b'*64)" | pbcopy
Add value to list in dictionary if it doesn’t exist; otherwise append the value to the existing list.
if not dict.has_key(key):
dict[key] = [value]
else:
dict[key].append(value)
In this instance, we’ll say that c is a random character, and we’re currently counting
the number of instances of this character in a string.
Just use https://pypi.python.org/pypi/PrettyTable and save yourself a headache.
from prettytable import PrettyTable
def output_dict_to_table(in_dict):
"""
Print an input dictionary as a table
Usage:
output_dict_to_table({'Key': ['Value'], 'Key2': ['Value2', 'Value3']})
"""
t = PrettyTable(['Key', 'Value'])
for k, v in in_dict.items():
t.add_row([k, v])
print t
This example uses the run_cmd function above.
# Output is bytes; convert to string with the .decode('utf-8')
output = run_cmd('terraform output -json').decode('utf-8')
tf_json = json.loads(output)
The tf_json object will be properly set up as a python dictionary.
Resources:
This dictionary will have counters for each letter. If there are duplicate letters, the counter will increment, i.e.
will return the following:
{'l': 2, 'h': 1, 'e': 1, 'o': 1}
The code to do this is as follows:
from collections import Counter
print(Counter(['h','e','l','l','o']))
Note that you can also use this with a string, i.e.
from collections import Counter
print(Counter('hello'))
This particular example will output a dictionary that has a word as its key and a dictionary as the value that maps each letter of the word to the number of times it appears.
from collections import Counter
words = ['hi', 'bye', 'toodles']
word_to_chars = {}
for word in words:
word_to_chars[word] = Counter(word)
print(word_to_chars)
# {'bye': Counter({'y': 1, 'b': 1, 'e': 1}), 'hi': Counter({'i': 1, 'h': 1}), 'toodles':
Counter({'o': 2, 'e': 1, 'd': 1, 'l': 1, 's': 1, 't': 1})}
def check_if_in_list_of_dict(sample_dict, value):
"""Check if given value exists in list of dictionaries """
for elem in sample_dict:
if value in elem.values():
return True
return False
if check_if_in_list_of_dict(dict_name, 'value'):
print('yep')
Resource: https://thispointer.com/python-check-if-value-exists-in-list-of-dictionaries/
# Open new tab
driver.execute_script("window.open('');")
# Switch to new tab
driver.switch_to.window(driver.window_handles[1])
# Load stackoverflow
driver.get("http://stackoverflow.com")
# Wait for page to load
time.sleep(3)
# Close the new tab
driver.close()
driver.switch_to.window(driver.window_handles[0])
Resource: https://stackoverflow.com/questions/28431765/open-web-in-new-tab-selenium-python
Resource: https://pythonbasics.org/selenium-get-html/
driver.get_cookie('cookie_name')['value']
In the event you need to be able to get request and/or response data, you’ll probably want to look at using a proxy like browsermob.
A fully working example can be found here.
from selenium import webdriver
from browsermobproxy import Server
import time
server = Server(
path="./assets/browsermob-proxy-2.1.4/bin/browsermob-proxy", options={'port':
8095})
server.start()
proxy = server.create_proxy()
profile = webdriver.FirefoxProfile()
selenium_proxy = proxy.selenium_proxy()
profile.set_proxy(selenium_proxy)
driver = webdriver.Firefox(firefox_profile=profile)
proxy.new_har('req', options={'captureHeaders': True, 'captureContent': True})
driver.get("https://www.google.com")
print(proxy.har)
server.stop()
driver.quit()
Resources:
Using Chrome, I do the following to get the information I need to trigger an event-driven dropdown and then click one of the listed items:
driver.find_element_by_xpath('<copied xpath>').click()
Continue on in this manner until you have the desired behavior.
import pandas as pd
table = pd.read_html(driver.page_source)
# Print all values associated with a particular column
df = table
print(df.<column_name>)
# for example:
# print(df.IP)
Resources: https://beenje.github.io/blog/posts/parsing-html-tables-in-python-with-pandas/ https://stackoverflow.com/questions/6325216/parse-html-table-to-python-list
This is one option:
driver.find_element_by_xpath(
"//*[contains(text(), 'text to match')]")
This is another (specifically for a button):
driver.find_element_by_xpath(
"//button[normalize-space()='text to match']").click()
Resources: https://www.guru99.com/using-contains-sbiling-ancestor-to-find-element-in-selenium.html https://stackoverflow.com/questions/12323403/how-do-i-find-an-element-that-contains-specific-text-in-selenium-webdriver-pyth https://stackoverflow.com/questions/49906237/how-to-find-button-with-selenium-by-its-text-inside-python
from selenium.webdriver.common.keys import Keys
driver.find_element_by_name('elementName').send_keys(Keys.BACK_SPACE)
from selenium.webdriver.support import expected_conditions as EC
# wait for 10 seconds for the page to load
delay = 10
try:
WebDriverWait(driver, delay).until(
EC.presence_of_element_located((By.ID, 'name of id associated with element
you want')))
except TimeoutException:
sys.exit("Loading the page took too much time, exiting!")
Argparse is great for when you need to use CLI arguments - it’s clean and can be implemented with minimal fuss.
import argparse
def parse_arg():
parser = argparse.ArgumentParser(description='Do stuff')
parser.add_argument("-a", '--argument', required=True, help='description of what
your awesome code does')
return parser.parse_args()
# Return value of a single argument if you don't have multiple ones:
#return parser.parse_args().arg
For an example of how I’ve used this previously, check this page out: https://github.com/l50/base64_rot13_decoder
import argparse
def __parse_args__():
parser = argparse.ArgumentParser(
description='Do stuff.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-f', action=.....)
group.add_argument('-d', type=bool, help='do a boolean thing')
return parser.parse_args()
Resource: https://stackoverflow.com/questions/11154946/require-either-of-two-arguments-using-argparse
If you want to have a flag that defaults to true (so you don’t have to specify it as an argument), do the following:
parser.add_argument('-d', dest="debug", action='store_true',
help='debug mode')
Resource: https://docs.python.org/3/library/argparse.html
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
print "Port is open"
else:
print "Port is not open"
sock.close()
Resource: https://stackoverflow.com/questions/19196105/how-to-check-if-a-network-port-is-open-on-linux
status_code = subprocess.call(
['ansible-playbook', 'site.yml', '-i', 'hosts'])
# status_code = 0 is an indicator of running the command successfully
Resource: https://www.cyberciti.biz/faq/python-run-external-command-and-get-output/
import smtplib
from email.mime.text import MIMEText
smtp_user = '[email protected]'
smtp_pw = 'YEP PUT THAT HERE'
sender = ['[email protected]']
recipients = ['[email protected]', '[email protected]']
msg = MIMEText('Sweet text br0')
msg['Subject'] = "Awesome Subject
msg['From'] = ','.join(sender)
msg['To'] = ','.join(recipients)
s = smtplib.SMTP('smtp.mailgun.org', 587)
s.login(smtp_user, smtp_pw)
s.sendmail(sender, recipients, msg.as_string())
s.quit()
import smtplib
from email.mime.text import MIMEText
smtp_user = '[email protected]'
smtp_pw = 'YEP PUT THAT HERE'
sender = ['[email protected]']
recipient = ['[email protected]']
cc_emails = ['[email protected]', '[email protected]']
msg = MIMEText('Sweet text br0')
msg['Subject'] = "Awesome Subject
msg['From'] = ','.join(sender)
msg['To'] = ','.join(recipient)
msg['Cc'] = ','.join(cc_emails)
s = smtplib.SMTP('smtp.mailgun.org', 587)
s.login(smtp_user, smtp_pw)
s.sendmail(sender, recipient+cc_emails, msg.as_string())
s.quit()
Resources: https://stackoverflow.com/questions/49062924/send-e-mail-to-multiple-cc-and-multiple-to-recipients-simultaneously-using-pytho https://stackoverflow.com/questions/1546367/python-how-to-send-mail-with-to-cc-and-bcc
git.Repo.clone_from(f"https://github.com/{self.user_name}/{self.repo_name}.git",
f"./{self.repo_name}")
os.environ['GIT_USERNAME'] = config.username
os.environ['GIT_PASSWORD'] = config.passwordrepo_path = 'repo_name'
try:
repo = git.Repo(repo_path)
repo.git.add(update=True)
repo.index.commit('Commit Message')
origin = repo.remote(name='origin')
origin.push()
print("Pushed the latest commit to the repo!")
except Exception as e:
print(f"Failed to push the new commit due to {e}")
os.unsetenv('GIT_USERNAME')
os.unsetenv('GIT_PASSWORD')
Resources:
from typing import Dict
import binascii
import hashlib
import hmac
import secrets
import string
import uuid
def gen_pw(size: str) -> str:
return ''.join((secrets.choice(string.ascii_letters + string.digits + string.punctuation)
for i in range(size)))
def create_pw_hash(size: int) -> Dict[bytes, bytes]:
"""
Hash the provided password with a randomly-generated salt and return the
salt and hash to store in the database.
"""
salt = secrets.token_bytes(32).hex().upper()
password = gen_pw(size)
key = hashlib.sha256(password.encode('utf-8') + salt.encode('utf-8'))
return { 'salt': salt, 'key': key.hexdigest(), 'pw': password }
def is_correct_password(salt: str, pw_hash: str, password: str) -> bool:
"""
Given a previously-stored salt and hash, and a password provided by a user
trying to log in, check whether the password is correct.
"""
return hmac.compare_digest(
pw_hash,
hashlib.sha256(password.encode('utf-8') + salt.encode('utf-8')).hexdigest()
)
output = create_pw_hash(32)
assert(is_correct_password(output['salt'], output['key'], output['pw']))
Resources:
strings_from_html = ' '.join(BeautifulSoup(html_code, "html.parser").stripped_strings)
words = strings_from_html.split()
Resource: https://stackoverflow.com/questions/328356/extracting-text-from-html-file-using-python
from collections import Counter
stuff = {'bla':4,'hey':6,'chicken':2,'bob':10}
counter = Counter(stuff)
print(counter.most_common(3))
Resource: https://www.geeksforgeeks.org/python-program-to-find-the-highest-3-values-in-a-dictionary/
# Random string
a = '6f8FGlE(u'
str.encode(a)
# Random string
a = b'6f8FGlE(u'
a.decode('utf-8')
Resource: https://stackoverflow.com/questions/606191/convert-bytes-to-a-string
hex_string = '6465616462656566'
bytes.fromhex(hex_string)
# b'deadbeef'
byte_string = b"deadbeef"
byte_string.hex()
# '6465616462656566'
Resource: https://stackoverflow.com/questions/5649407/hexadecimal-string-to-byte-array-in-python
from bs4 import BeautifulSoup
soup = BeautifulSoup(input, 'html.parser')
for a in soup.find_all('a', href=True):
if a.text:
print(a['href'])
Python 3.5+:
from pathlib import Path
home = str(Path.home())
Alternative:
from os.path import expanduser
home = expanduser("~")
Resource: https://stackoverflow.com/questions/4028904/how-to-get-the-home-directory-in-python
import argparse
# Initialize parser
parser = argparse.ArgumentParser()
# Adding optional argument
parser.add_argument('--foo', type=str, help='foo help')
# Read arguments from command line
args = parser.parse_args()
Reference your input in your code with:
Resources:
import os
print(os.path.expanduser('~')
Resource: https://www.kite.com/python/examples/4284/os-get-the-path-of-the-home-directory
import shutil
# Source path
source = "/home/User/Documents/file.txt"
# Destination path
destination = "/home/User/Documents"
try:
shutil.copyfile(source, destination)
print("File copied successfully.")
# If source and destination are same
except shutil.SameFileError:
print("Source and destination represents the same file.")
# If destination is a directory.
except IsADirectoryError:
print("Destination is a directory.")
# If there is any permission issue
except PermissionError:
print("Permission denied.")
# For other errors
except:
print("Error occurred while copying file.")
Resource: https://www.geeksforgeeks.org/python-shutil-copyfile-method/
import os
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
This will do the same thing as mkdir -p:
import os, os.path
def safe_open_w(path):
''' Open "path" for writing, creating any parent directories as needed.
'''
os.makedirs(os.path.dirname(path), exist_ok=True)
return open(path, 'w')
with safe_open_w('/Users/bill/output/output-text.txt') as f:
f.write(...)
Resource: https://stackoverflow.com/questions/23793987/write-file-to-a-directory-that-doesnt-exist
Run the following to generate the hash on your linux machine:
python3 -c 'import crypt; print(crypt.crypt("sickpasswordbro!", crypt.mksalt(crypt.METHOD_SHA512)))'
Resource: https://serverfault.com/questions/330069/how-to-create-an-sha-512-hashed-password-for-shadow