#!/usr/bin/env ruby fail 'flag?' unless File.file?('flag') $stdout.sync = true limit = ARGV[0].to_i puts "Hi, I can say #{limit} bytes :P" s = $stdin.gets.strip! if s.size > limit || s[/[[:alnum:]]/] puts 'oh... I cannot say this, maybe it is too long or too weird :(' exit end puts "I think size = #{s.size} is ok to me." r = eval(s).to_s r[64..-1] = '...' if r.size > 64 puts r

Without being able to use alphanumerics, I assumed that command injection would have to be achieved using built-in variables that consisted solely of symbols. After a little googling, I found a reference describing the global variables in ruby. I also stumbled across an article by a guy who decided to program various ruby programs without using alphanumerics.

After some more research, I discovered you can run a shell command from ruby by surrounding it in backticks. Perusing the built-in variables, I found $: provides an array of paths. The first of these paths was /home/shik/.rbenv/versions/2.2.3/lib/ruby/site_ruby/2.2.0

I realized I could create a substring of this path to create the string ‘sh’ and execute it using backtricks.

Using, the articles I had found, I came up with my initial input of input = ‘_=$.+$.;`#{$:[_][_*_+_.._*_*_-$.]}`’

With a length of 35 characters I was able to get the first three keys. To get the last one, I would have to do better. Since half of the required 10 characters will be required to execute a command and interpolate a ruby variable, I assumed there had to be some trick inside the C shell itself to execute a shell. Reading the documentation for built-in C shell variables and some trial and error, I discovered that the $ symbol followed by a number would print the command line argument at the given index. It also just so happened that the first argument, $0, is always sh. Armed with this knowledge, all I had to do was find a way to get 0 from one of the built-in ruby variables. From my previous input, I knew $. always equals 1.