Summer Camp 2020: Enumeration and Exploitation


For the weekly challenge, a small piece of code was given in a Ruby file:

def main
        key = 0x80
        enc = [211, 203, 217, 173, 195, 193, 212, 173, 180, 181, 182, 185]

        puts "Can I haz auth?"
        auth = gets.chomp.bytes.to_a
        if enc ==  auth.map! {|a| key ^ a} then
                puts "Congrats"
        else
                puts "fail"
        end
end

main

This is a fairly simple script that relies on some of Ruby’s functional programming features (namely higher order functions and anonymous functions, or lambdas).

I am going to explain higher order functions and lambdas in Python instead of Ruby because the concepts are the same across programming languages and the only resulting difference is syntax.

Higher order functions

Put simply, higher order functions are functions that take functions as arguments and/or return a function as the return value. This is a fairly powerful that can be used to distill a complex idea in a fairly small amount of code.

The higher order function used in the above example is map. To understand, map lets look at an example of map being implemented in Python.

def myMap(func, iter):
    #map is already a function defined in the python runtime
    for i in iter:
        yield func(i)

Map takes a function as an input as well as an iterable data type (think lists and dictionaries)

Lambdas

It’s a lamb. Duh.

Lambdas, or anonymous functions, are a way of creating functions that will be used once. (Note: Depending on the programming language, lambdas don’t have to be single use, but most of time they are). These are useful when you need to pass a function to a higher order function, but don’t want to define a completely new function. Lambda syntax also tends to be simpler and shorter than a traditional function definition. Here is an example of passing a lambda to a higher order function in Python.

a = [1,2,3,4]
map(lambda x: x + 1, a)

Bit Math 101

There are a quite a few operations when doing math on the bit level (the 0’s and 1’s!). For the sake of simplicity we are going to look at three operations: AND, OR, and XOR.

Each of these three operations are logical operators. Logical operators can be thought of on a true or false basis. For OR, only one of the two operands has to be true (AKA 1) to satisfy the condition as true. In the AND operation, both operands have to be true to satisfy the condition as true, or else it’s considered false (AKA 0). XOR is slightly different in that it works like OR, but if both operands are the same it comes back as false. (Hint: XOR also works as a simple form of encryption!)

To play around with these operations, you can run the following Python operators against some test numbers:

>>> 1 ^ 0 #Xor
1
>>> 1 & 0 #And
0
>>> 1 or 0 #Or
1

Wrap up

Using what you have learned from this blog post, you should be able to figure out the input that makes the Ruby script write “Congrats” out to the console!

With love and root shells,

Wolfshirtz

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.