Link Menu Search Expand Document

Python

Most of the stuff here is Python3 related.

Table of contents

  1. Heredoc strings
  2. Dealing with SQL
  3. Services
    1. HTTP Server
    2. HTTPS Server
    3. FTP server
  4. HTTP Requests
    1. POST request
  5. Base64 encoding/decoding
  6. Issues with decoding
  7. Command Line Argument Parsing (argparse)
  8. Disable requests/urllib InsecureRequestWarning
  9. Date manipulation
  10. Flask
    1. Reload application when you save file
  11. Prettify JSON
  12. Exception
    1. Capture any exception and print its details
    2. Get the full backtrace

Heredoc strings

To properly format a heredoc string, use textwrap.dedent

import textwrap

mystr = """
   Hey!
   How are you?
   """

print(mystr)
print(textwrap.dedent(mystr))

Dealing with SQL

SQAlchemy seems to be the common way of dealing with SQL stuff in Python. There is also DBApi which seems to be the basic Python layer for databases, but then you have to take care yourself on handling multiple different backends.

Table creation on SQLAlchemy:

Here is the documentation for Column: https://docs.sqlalchemy.org/en/13/core/metadata.html#sqlalchemy.schema.Column

In order to specify the database to connect to, provide a database URL as explained here: https://docs.sqlalchemy.org/en/13/core/engines.html#database-urls

Services

HTTP Server

Using Python 3:

$ python3 -m http.server 8000 --bind 127.0.0.1

Using Python 2:

$ python2 -m SimpleHTTPServer
$ python2 -c 'import BaseHTTPServer as bhs, SimpleHTTPServer as shs; bhs.HTTPServer(("127.0.0.1", 8888), shs.SimpleHTTPRequestHandler).serve_forever()'

If you need a simple HTTP server in your code:

import http.server
import socketserver

ADDR = "127.0.0.1" # or blank to listen on 0.0.0.0
PORT = 8000

Handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer((ADDR, PORT), Handler) as httpd:
    print("Server started at %s:%d" %(ADDR, PORT))
    httpd.serve_forever()

HTTPS Server

# taken from http://www.piware.de/2011/01/creating-an-https-server-in-python/
# generate server.xml with the following command:
#    openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
# run as follows:
#    python simple-https-server.py
# then in your browser, visit:
#    https://localhost:4443

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer(('localhost', 4443),
SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket, certfile='./server.pem',
server_side=True)
httpd.serve_forever()

FTP server

sudo apt-get install python-pyftpdlib
python -m pyftpdlib -p 21

HTTP Requests

These examples use the requests library.

pip3 install requests

POST request

import requests

cookies = {"cookie-name" : "cookie-value", 
           "other-cookie" : "other-value"
}

URL = 'https://www.gilgalab.com/python3/post-example'

data = {'param1': 'value', 'param2': 'value'}

proxies = {
           'https' : 'https://localhost:8080',
           'http'  : 'http://localhost:8080'
}

r = requests.post(url=URL, data=data, cookies=cookies, proxies=proxies, 
                  verify=False, allow_redirects=False)

print(r.text)

Base64 encoding/decoding

import base64

# Encode a string
mystr = 'abc'
encoded = base64.b64encode(mystr.encode('utf-8')))

decoded = base64.b64decode(encoded)

Issues with decoding

If you are having issues deconding strings, try to use .decode('cp437')

Command Line Argument Parsing (argparse)

If you want to use argument options when running a python script from the command line such as:

python3 somescript.py -name Gilgamesh -host gilgalab.com

Use the following:

import argparse

if __name__ == '__main__':

    segment_types = ['s1', 's2']
    fuzzer_types = ['ft1', 'ft2']
    
    # Create the argument parser
    parser = argparse.ArgumentParser()
    
    # Options that can be passed to the script 
    # This is a required one
    parser.add_argument('-f', '--fuzzer', help='Type of fuzzer to use',
                        default='myfuzz', choices=fuzzer_types, required=True)
    
    # This one is not required
    parser.add_argument('-d', '--directory', 
                        help='Where to save results',
                        default='fuzz-messages')

    # Just short option. Result goes into args.output due to `dest` param
    parser.add_argument(
        '-o', dest='output', help='Directory where to save stuff', 
        required=True)


    # Options that are mutually exclusive (either one is accepted or the
    # other)
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-a', '--all', help='Generate fuzzers for all types', action='store_true')
    group.add_argument('-s', '--segment', help='Segment name to generate a fuzzer for', choices=segment_types)
  
    args = parser.parse_args()

    # Properties in the `args` var will have the same name as the long 
    # name of the parameter
    
    if args.all:
        segment_types = get_segment_types()

    elif args.segment:
        segment_types = [args.segment]

    # This check forces one of these parameter to be provided
    # Couldn't figure out how to do it with the ArgumentParser class
    if not args.all and not args.segment:
        print("Can't find segments to generate fuzzer for. Aborting...")
        print("Did you give the program the `-a` or `-s` option?")
        exit(-1)

    output_directory = args.directory
    fuzzer_type = args.fuzzer

Disable requests/urllib InsecureRequestWarning

Sometimes you are just writing some test scripts or something that you don’t really care if you can trust the remote system or not. The following disables the annoying urllib InsecureRequestWarning message:

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

Date manipulation

Get the date in the YYYY-mm-dd HH24:MM:SS format:

import datetime
import time

now = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')

Flask

Reload application when you save file

Just run the application in debug mode:

$ export FLASK_ENV=development
$ flask run

Or in code

from flask import Flask

app = Flask(__name__)
app.run(debug=True)

Prettify JSON

$ cat file.json | python -m json.tool

Exception

Capture any exception and print its details

import sys

try:
  somethingInvalid()
except:
  e = sys.exc_info()
  print("Exception: [%s][%s]" % (e[0], e[1]))

Get the full backtrace

import traceback

def my_func():
    raise ValueError('Yey!')

try:
    my_func()
except Exception:
    print('%s' % traceback.format_exc())

Gilgalab Knowledge Base