0404 | Extending Python
The Python package managers
- a package contains a bundle of files which are required for a module to work
- modules are libraries of existing code which we can use and call in our program
pip
| package manager for python- install
pwntools
- newest release
pip install pwntools
- specific version
pip install pwntools==4.13.0
- newest release
- test
pwntools
install- launch interactive python
from pwn import *
exit()
- launch interactive python
- uninstall package
pip uninstall pwntools
- list installed libraries
pip list
pip freeze
- use "requirements.txt" for multiple packages
- example | "requirements.txt"
pwntools==4.13.0
py-cpuinfo==9.0.0
py-sneakers==1.0.1 - install it with
pip
pip install -r requirements.txt
- example | "requirements.txt"
Python virtual environments
- great for solving dependency conflicts
- a virtual environment enables you to create an isolated python environment which is not dependent on other virtual environments or packages installed on the host system
- by default | the new virtual environment does not include ANY packages | clean slate
- installing
pip install virtualenv
- or in my experience on kali
sudo apt install python3.11-venv
- using it
- create working dir
mkdir virtual-demo; cd virtual-demo
- create virtual environment
python3 -m venv env
- activate the environment
source env/bin/activate
- install
pwntools
pip install pwntools
- deactivate the environment
deactivate
- create working dir
Introduction to sys
- provides functions and variables related to the python runtime environment
- example | gives access to data sent as part of the command line arguments when executing a python script
- standard library --> comes packaged with python
- gives access to some low level functions | like
flush
- example | "sys-demo.py" | (play around with commenting/uncommenting as you see fit)
import sys
# version information of the python interpreter
print(sys.version)
# current executable binary
print(sys.executable)
# current platform
print(sys.platform)
# read from standard input -- stdin -- (filehandle)
#for line in sys.stdin:
# if line.strip() == "exit":
# break
# sys.stdout.write(">> {}".format(line))
# flush the buffer
for i in range(1,5):
sys.stdout.write(str(i))
sys.stdout.flush()
# flush the buffer
for i in range(1,5):
print(i)
# cool status bar denoting the progress of cracking
import time
for i in range(0, 51):
# time.sleep(0.1)
time.sleep(0) # to speed up execution for testing
# use carrige return \r to jump to the start of the line each time
sys.stdout.write("{} [{}{}]\r".format(i, '#'*i, "."*(50-i)))
sys.stdout.flush()
sys.stdout.write("\n")
# ACCESSING COMMAND LINE ARGUMENTS
# list of the command line arguments
print(sys.argv)
# check number of args
if len(sys.argv) != 3:
print("[X] To run {} enter a username and password".format(sys.argv[0]))
sys.exit(5)
# assigning the cmd arguments
username = sys.argv[1]
password = sys.argv[2]
print("{} {}".format(username, password))
# access the path where python will search for modules
print(sys.path)
print("-"*50)
# access the modules we have access to
print(sys.modules)
# exit code
# return value after script is executed
# indicating running success or failure
# if everything went fine --> 0
# verify it with `echo $?`
sys.exit(0)
Introduction to requests
- to make and process http requests in python
- test-site | http-bin.org | just an http request/response service
- it will reflect our data back to us
- install
pip install requests
- comes preinstalled on kali
- by default | request will perform redirects for all verbs, except for head
- example | "requests-demo.py" | (play around with commenting/uncommenting as you see fit)
import requests
# x = requests.get('http://httpbin.org/get')
# # test the service -- `curl -I http://httpbin.org/get`
# # -- (-I:fetch the headers only)
# # check the headers
# print(x.headers)
# # check a specific header
# print(x.headers['Server'])
# # check status code
# print(x.status_code)
# if x.status_code == 200:
# print("Success!")
# elif x.status_code == 404:
# # like for x = requests.get('http://httpbin.org/get123123')
# print("Not found!")
# # check how much time has elapsed from sending the request
# # to receiving the response
# print(x.elapsed)
# # check the cookies -- cookiejar object containing all the cookies
# print(x.cookies)
# # check the returned contents -- in bytes -- the FULL response
# print(x.content)
# # check the response -- in UNICODE
# print(x.text)
# # create a requests with parameters
# x = requests.get('http://httpbin.org/get', params={'id':'1'})
# print(x.url)
# # specify the parameters in the requesting url
# x = requests.get('http://httpbin.org/get?id=2')
# print(x.url)
# # specify additional information -- headers -- it is reflected in the response
# x = requests.get('http://httpbin.org/get', params={'id':'3'}, headers={'Accept':'application/json'})
# print(x.text)
# # specify additional information -- headers -- it is reflected in the response
# x = requests.get('http://httpbin.org/get', params={'id':'3'}, headers={'Accept':'application/json', 'test_header':'test'})
# print(x.text)
# ##### DELETE request
# x = requests.delete('http://httpbin.org/delete')
# print(x.text)
# ##### POST request -- data included as form
# x = requests.post('http://httpbin.org/post', data={'a':'b'})
# print(x.text)
# x = requests.post('http://httpbin.org/post', data={'a':'b', 'c':'d', 'e':'f'})
# print(x.text)
# # upload multipart encoded files
# # picture downloaded from google.com -- the logo
# # file is sent as in base64 encoded format
# files = {'file': open('google.png', 'rb')}
# x = requests.post('http://httpbin.org/post', files=files)
# print(x.text)
# ###### HANDLING BASIC AUTHENTICATION
# x = requests.get('http://httpbin.org/get', auth=('username','password'))
# print(x.text)
# # this is sent: "Authorization": "Basic dXNlcm5hbWU6cGFzc3dvcmQ=",
# # checking it -- `echo -ne dXNlcm5hbWU6cGFzc3dvcmQ= | base64 -d`
# translates to username:password
###### WORKING WITH SSL CERTS
# verify bad ssl cert --> certificate has expired error
# x = requests.get('https://expired.badssl.com')
# force it -- no error but a warning
# x = requests.get('https://expired.badssl.com', verify=False)
###### REDIRECTS
# # not really readable
# x = requests.get('http://github.com')
# print(x.headers)
# # check it with curl -- `curl -I http://github.com`
# # -- 301 redirect to https://github.com
# # specify disallowing redirects
# x = requests.get('http://github.com', allow_redirects=False)
# print(x.headers)
# ##### TIMEOUTS -- waiting for the response
# # will throw an error -- will time out
# x = requests.get('http://httpbin.org/get', timeout=0.01)
# print(x.content)
###### STATEFUL request -- persising data across sessions -- SESSIONS
# x = requests.get('http://httpbin.org/cookies', cookies={'a':'b'})
# print(x.content)
# # better with sessions
# x = requests.Session()
# x.cookies.update({'a':'b'})
# print(x.get('http://httpbin.org/cookies').text)
# # will do with every subfrequent request -- no need to specify again
# print(x.get('http://httpbin.org/cookies').text)
# ##### PARSING THE JSON RESPONSE AS JSON
# x = requests.get('https://api.github.com/events')
# print(x.json())
##### Working with other data -- not just text
# download and save a picture
x = requests.get('https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png')
with open('google2.png', 'wb') as f:
f.write(x.content)
Introduction to pwntools
- a capture the flag framework and exploit development library
- includes features to interact with processes locally and remotely
- encode/pack/unpack data
- works with different architectures/contexts
- install
pwntools
pip install pwntools
- example | "pwntools-demo.py" | (play around with commenting/uncommenting as you see fit)
from pwn import *
# imports the functionality into the global namespace
# we can call the functions directly
# # create a cyclic pattern for buffer overflows
# # for identifying the offset
# print(cyclic(50))
# # identify a position -- offset
# print(cyclic_find("laaa"))
# ##### shellcode and assembly
# print(shellcraft.sh())
# # assembly for execve -- /bin///sh
# # print it in assembly
# print(hexdump(asm(shellcraft.sh())))
# ##### processes -- LOCAL
# # start a local process -- sh
# p = process("/bin/sh")
# # send a command
# p.sendline("echo hello;")
# # start an interactive terminal
# p.interactive()
# ##### processes -- REMOTE -- start netcat listener before running
# # netcat listener -- `nc -lp 1234`
# # start a remote process -- sh
# # establish connection and start process
# r = remote("127.0.0.1", 1234)
# # send a hello
# r.sendline("hello!")
# # start interactive session
# r.interactive()
# # close connection
# r.close()
# ##### PACKING/UNPACKING NUMBERS
# # packing
# print(p32(0x13371337))
# # unpacking
# print(hex(u32(p32(0x13371337))))
# ##### LOADING FILES
# # load the file
# l = ELF('/bin/bash')
# # check base address -- information about how it was compiled
# print(hex(l.address))
# # check entrypoint
# print(hex(l.entry))
# # check the address of a specific symbol from the global offset table
# print(hex(l.got['write']))
# # grab info about a specific symbol from the procedure linkage table
# print(hex(l.plt['write']))
# ###### searching in an ELF file
# # search for the /bin/sh string the the file and grab the addresses
# # null terminator at the end
# for address in l.search(b'/bin/sh\x00'):
# print(hex(address))
# # search for a specific address in the elf file
# # look for the jump esp gadget
# # next() -- the first instance found
# print(hex(next(l.search(asm('jmp esp')))))
# ###### ROP -- automatised -- no need to load and search
# r = ROP(l)
# print(r.rbx)
##################### ENCRYPTION/ENCODING/HASHING FUNCTIONS
# print(xor("A","B"))
# # verify
# print(xor(xor("A","B"), "A"))
# # base64 encoding
# print(b64e(b"test"))
# # base64 decoding
# print(b64d(b"dGVzdA=="))
# # md5sum-s
# print(md5sumhex(b"hello"))
# # sha1
# print(sha1sumhex(b"hello"))
###### LOWER LEVEL FUNCTIONS
print(bits(b'a'))
# verify
print(unbits([0, 1, 1, 0, 0, 0, 0, 1]))