The challenge clearly implies this is some sort of code jail. These are typically pyjails — let’s test it out.
Sending print returns <built-in function print>, which pretty much confirms this is a pyjail. I immediately decided to try a naive method to get the flag.
1
print(open('flag.txt', 'r').read())
Output:
1
read key
2
3
None
Hey… that worked? No keywords or anything were blacklisted? Well, let’s check out key anyways.
1
print(open('key', 'r').read())
1
guera
2
3
Yep, not the flag..., use 'guera' as the password for the real challenge at port 8889
4
5
None
Ah. So there’s a part 2 to this challenge. Let’s check it out!
Here’s what we’re presented with after sending the key, guera:
1
Oh Oh you escaped from a pasta jail..., can you escape from a bank and steal a precious ruby?...
2
3
4
Welcome to:
5
HACKAPPATOI's Jewelry (We got funds from zio Berlusca)
6
Here you will find a magnific 1337 Jewel
7
8
_______
9
.'_/_|_\_'.
10
\`\ | /`/
11
`\\ | //'
12
`\|/`
13
`
14
15
But you need to obtain it and it won't be so easy...
16
You have a command to get it....
17
Good Luck!
18
Enter command:
Another pyjail? Let’s try sending print:
Oopsie.. your input is bad... We blocked it.
Not sure if it’s Python yet, but definitely some blacklisting going on. Let’s try some random letters. Eventually, with the input a, I got this:
1
(eval):1:in `<main>': undefined local variable or method `a' for main:Object (NameError)
2
from jewelry.rb:40:in `eval'
3
from jewelry.rb:40:in `<main>'
.rb…? Isn’t that a Ruby file? So this must be a Ruby jail!
With further testing, I quickly realized a lot of characters were blacklisted. Hence, I wrote a quick script to test which ones were blacklisted:
…were the only allowed characters. That’s odd… only aelv are allowed of the lowercase letters, and, importantly, these spell out eval. Maybe that’ll be important to the challenge?
At this point, since I had never even used Ruby before, much less broken a Ruby jail, I started doing a lot of research and playing around with the service. I tried octal numbers, global variables, predefined constants, etc etc. Overall, I ended up being stuck for over an hour on this section of the problem. Eventually, my search query of ruby jail without letters ctf returned results. The reason I wanted to find some sort of hint to breaking a ruby jail without letters was because a lot of lowercase letters were restricted, so if I could find a way to break it without letters, I could easily break the jail. (in hindsight, I should have searched this up much earlier!)
Scrolling down a bit, I found this writeup on CTFtime. Take a look at this section:
This article describes how you can write ruby code without letters, and since we are able to use the quote sign ’, we can create strings with the shovel operator trick they describe.
I immediately took a look through the article and found this section:
Logically enough, it can “shovel” strings into each other. This doesn’t quite help us, of course, as we’re not allowed to create explicit character strings. We can, however, shovel Unicode codepoints into strings to achieve the same effect:
1
''<<97<<98<<99
2
# "abc"
So we don’t need letters at all to construct our inputs! Perfect!
Now all that’s left to do is construct our payload. With the help of this decimal to ASCII converter and this online replace string helper, I was able to construct our payload pretty easily. At first, trying to open flag.txt didn’t work, but then, trying flag did!
Thoughts: As a complete newbie to both pyjails and ruby, I was pretty proud of this solve! Although it did take me quite a long time to solve, I thought I managed to figure out everything by the end quite nicely :)