RESEARCH | November 21, 2017

Hidden Exploitable Behaviors in Programming Languages

In February 28th 2015 Egor Homakov wrote an article[1] exposing the dangers in the open() function from Ruby. The function is commonly used when requesting URLs programmatically with the open-uri library. However, instead of requesting URLs you may end up executing operating system commands.


Consider the following Ruby script named open-uri.rb:

require ‘open-uri’
print open(ARGV[0]).read

The following command requests a web page:
# ruby open-uri.rb “https://ioactive.com”

 

And the following output is shown:

<!DOCTYPE HTML>
<!–[if lt IE 9]><html class=”ie”><![endif]–>
<!–[if !IE]><!–><html><!–<![endif]–><head>
                <meta charset=”UTF-8″>
                <title>IOActive is the global leader in cybersecurity, penetration testing, and computer services</title>
[…SNIP…]

 

Works as expected, right? Still, this command may be used to open a process that allows any command to be executed. If a similar Ruby script is used in a web application with weak input validation then you could just add a pipe and your favorite OS command in a remote request:

|head /etc/passwd

 

And the following output could be shown:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[…SNIP…]

 

The difference between the two executions is just the pipe character at the beginning. The pipe character causes Ruby to stop using the function from open-uri, and use the native open() functionality that allows command execution[2].

 
Applications may be susceptible to unpredictable security issues when using certain features from programming languages. There are a number of possibilities to be abused in different implementations that could affect secure applications. There are unexpected scenarios for the interpreted programming languages parsing the code in Javascript, Perl, PHP, Python and Ruby.
 
Come and join me at Black Hat Europe[3] to learn more about these risky features and how to detect them. An open source extended differential fuzzing framework will be released to aid in the disclosure of these types of behaviors.
[1] Using open-uri? Check your code – you’re playing with fire! (https://sakurity.com/blog/2015/02/28/openuri.html)
 
[2] A dozen (or so) ways to start sub-processes in Ruby: Method #4: Opening a pipe (https://devver.wordpress.com/2009/07/13/a-dozen-or-so-ways-to-start-sub-processes-in-ruby-part-2/)
[3] Exposing Hidden Exploitable Behaviors in Programming Languages Using Differential Fuzzing (https://www.blackhat.com/eu-17/briefings.html#exposing-hidden-exploitable-behaviors-in-programming-languages-using-differential-fuzzing)